Sebuah keyboard seperti miniatur komputer. Keyboard mempunyai prosesor sendiri dan rangkaian sirkuit yang membawa informasi menuju dan dari prosesor tersebut. Bagian terbesar dari rangkaian keyboard berupa “key matrix”.
“Key matrix” adalah sebuah kisi rangkaian dibawah tombol-tombol keyboard. Di dalam keyboard, tiap rangkaiannya terputus (seperti saklar)
Gambar 1. Prosesor dalam keyboard
Untuk interfacing dari PS/2 PC keyboard ke mikrokontroler AVR ATMega8535 seperti gambar berikut:
Gambar 2. Pin out PS/2
Cara kerja keyboard:
-Keyboard melakukan scanning lokasi tombol yg ditekan.
-Setiap penekanan tombol, keyboard mengirim data F0 diikuti kode scan masing-masing tombol(gambar 3).
-Transmisi data, dari keyboard ke sistem, dilakukan dengan frame 11 bit. Bit pertama adalah bit start ( logika 0 ), diikuti dengan 8 bit data ( LSB first ), satau bit paristas ( paritas ganjil ) dan bit stop ( logika 1 ). Setiap bit harus dibaca pada sisi turun dari clock.

Gambar 3. Scan Code
Ilustrasi pengiriman data adalah sebagai berikut:

Gambar 4. Sinyal clock dan data
Data yang dikirim dari keyboard ke mikro ditampilkan ke LCD yang dihubungkan ke portB:
Gambar 5. Koneksi LCD ke mikro
Algoritma:
Clock masuk pada PortD.2 (INT0) yang akan mengeksekusi clock dan data disimpan saat falling edge (dari ’1′ menjadi ’0′). Setelah semua bit diterima maka data diterjemahkan ke karakter ASCII dengan metode lookup table.
Source code (CodeVision AVR):
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.8 Professional
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 5/14/2010
Author : F4CG
Company : F4CG
Comments:
Chip type : ATmega8535
Program type : Application
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8535.h>
#include <delay.h>
#include <stdio.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
/*----------------------------------------------------------------
define mouse pin
----------------------------------------------------------------*/
#define indata PIND.3
#define otdata PORTD.3
#define inclk PIND.2
#define otclk PORTD.2
/*---------------------------------------------------------------*/
// Standard Input/Output functions
#include <stdio.h>
/****************************************
* Baca data dari PS2 *
*****************************************/
char Read_ps2data(void)
{
char data = 0x00;
int i=0;
char dt = 0x01;
//start the clock
//gohi(MCLK);
DDRD.2=0;
otclk=1;
//gohi(MDATA);
DDRD.3=0;
otdata=1;
delay_us(50);
//while (digitalRead(MCLK) == HIGH);
//DDRD.2=0;
while (inclk==1);
delay_us(5);
//while (digitalRead(MCLK) == LOW); // eat start bit
while (inclk==0); // eat start bit
for (i=0; i < 8; i++)
{
//while (digitalRead(MCLK) == HIGH);
while (inclk==1);
//if (digitalRead(MDATA) == HIGH)
//DDRD.3=0;
//putchar(indata);
if (indata==1)
{
data = data | dt;
}
//while (digitalRead(MCLK) == LOW);
while (inclk==0);
dt = dt << 1;
}
//eat parity bit, which we ignore
//while (digitalRead(MCLK) == HIGH);
//while (digitalRead(MCLK) == LOW);
while (inclk==1);
while (inclk==0);
//eat stop bit
while (inclk==1);
while (inclk==0);
//put a hold on the incoming data.
//golo(MCLK);
DDRD.2=1;
PORTD.2=0;
return data;
}
void main(void)
{
// Declare your local variables here
unsigned int even;
char buff[33];
unsigned char kbd;
bit flag;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
lcd_init(16);
while (1)
{
even=Read_ps2data();
//huruf kecil
if (even==0x1c){kbd='a';} if (even==0x32){kbd='b';} if (even==0x21){kbd='c';}
if (even==0x23){kbd='d';} //huruf kecil
if (even==0x24){kbd='e';} if (even==0x2b){kbd='f';} if (even==0x34){kbd='g';}
if (even==0x33){kbd='h';}
if (even==0x43){kbd='i';} if (even==0x3b){kbd='j';} if (even==0x42){kbd='k';}
if (even==0x4b){kbd='l';}
if (even==0x3a){kbd='m';} if (even==0x31){kbd='n';} if (even==0x44){kbd='o';}
if (even==0x4d){kbd='p';}
if (even==0x15){kbd='q';} if (even==0x2d){kbd='r';} if (even==0x1b){kbd='s';}
if (even==0x2c){kbd='t';}
if (even==0x3c){kbd='u';} if (even==0x2a){kbd='v';} if (even==0x1d){kbd='w';}
if (even==0x22){kbd='x';}
if (even==0x35){kbd='y';} if (even==0x1a){kbd='z';}
//angka
if (even==0x16){kbd='1';} if (even==0x1e){kbd='2';} if (even==0x26){kbd='3';}
if (even==0x25){kbd='4';}
if (even==0x2e){kbd='5';} if (even==0x36){kbd='6';} if (even==0x3d){kbd='7';}
if (even==0x3e){kbd='8';}
if (even==0x46){kbd='9';} if (even==0x45){kbd='0';}
if (even==0x4e){kbd='-';} if (even==0x55){kbd='=';} //simbol tanpa shift
if (even==0x54){kbd='[';} if (even==0x5b){kbd=']';} if (even==0x4c){kbd=';';}
if (even==0x52){kbd=',';}
if (even==0x29){kbd=' ';} if (even==0x41){kbd=',';} if (even==0x49){kbd='.';}
if (even==0x4a){kbd='/';}
if (even==0x0e){kbd='~';} if (even==0x7b){kbd='-';} if (even==0x79){kbd='+';}
if (even==0xe0){kbd='?';} if (even==0x7c){kbd='<';} if (even==0x71){kbd='>';}
if (even==0x05){lcd_putsf("F1");} if (even==0x06){lcd_putsf("F2");}
if (even==0x04){lcd_putsf("F3");} if (even==0x0c){lcd_putsf("F4");}
if (even==0x03){lcd_putsf("F5");} if (even==0x0b){lcd_putsf("F6");}
if (even==0x83){lcd_putsf("F7");} if (even==0x0a){lcd_putsf("F8");}
if (even==0x01){lcd_putsf("F9");} if (even==0x09){lcd_putsf("F10");}
if (even==0x78){lcd_putsf("F11");} if (even==0x07){lcd_putsf("F12");}
if (even==0x76){kbd='';lcd_gotoxy(0,0);} //esc
if (even==0x0d){kbd='`';lcd_gotoxy(15,1);}//tab
if (even==0x5a){kbd='';lcd_gotoxy(0,1);} //enter
if (even==0x66){kbd='';lcd_clear();} //backspace
if (even==0x12){kbd='';flag=1;} //shift
if ((flag==1)&(even==0x1c)) {kbd='A';flag=0;} //Huruf besar
if ((flag==1)&(even==0x32)) {kbd='B';flag=0;}
if ((flag==1)&(even==0x21)) {kbd='C';flag=0;}
if ((flag==1)&(even==0x23)) {kbd='D';flag=0;}
if ((flag==1)&(even==0x24)) {kbd='E';flag=0;}
if ((flag==1)&(even==0x2b)) {kbd='F';flag=0;}
if ((flag==1)&(even==0x34)) {kbd='G';flag=0;}
if ((flag==1)&(even==0x33)) {kbd='H';flag=0;}
if ((flag==1)&(even==0x43)) {kbd='I';flag=0;}
if ((flag==1)&(even==0x3b)) {kbd='J';flag=0;}
if ((flag==1)&(even==0x42)) {kbd='K';flag=0;}
if ((flag==1)&(even==0x4b)) {kbd='L';flag=0;}
if ((flag==1)&(even==0x3a)) {kbd='M';flag=0;}
if ((flag==1)&(even==0x31)) {kbd='N';flag=0;}
if ((flag==1)&(even==0x44)) {kbd='O';flag=0;}
if ((flag==1)&(even==0x4d)) {kbd='P';flag=0;}
if ((flag==1)&(even==0x15)) {kbd='Q';flag=0;}
if ((flag==1)&(even==0x2d)) {kbd='R';flag=0;}
if ((flag==1)&(even==0x1b)) {kbd='S';flag=0;}
if ((flag==1)&(even==0x2c)) {kbd='T';flag=0;}
if ((flag==1)&(even==0x3c)) {kbd='U';flag=0;}
if ((flag==1)&(even==0x2a)) {kbd='V';flag=0;}
if ((flag==1)&(even==0x1d)) {kbd='W';flag=0;}
if ((flag==1)&(even==0x22)) {kbd='X';flag=0;}
if ((flag==1)&(even==0x35)) {kbd='Y';flag=0;}
if ((flag==1)&(even==0x1a)) {kbd='Z';flag=0;}
if ((flag==1)&(even==0x16)) {kbd='!';flag=0;} //Simbol diatas angka
if ((flag==1)&(even==0x1e)) {kbd='@';flag=0;}
if ((flag==1)&(even==0x26)) {kbd='#';flag=0;}
if ((flag==1)&(even==0x25)) {kbd='$';flag=0;}
if ((flag==1)&(even==0x2e)) {kbd='%';flag=0;}
if ((flag==1)&(even==0x36)) {kbd='^';flag=0;}
if ((flag==1)&(even==0x3d)) {kbd='&';flag=0;}
if ((flag==1)&(even==0x3e)) {kbd='*';flag=0;}
if ((flag==1)&(even==0x46)) {kbd='9';flag=0;}
if ((flag==1)&(even==0x45)) {kbd='0';flag=0;}
if ((flag==1)&(even==0x41)) {kbd='<';flag=0;} //Simbol lain
if ((flag==1)&(even==0x49)) {kbd='>';flag=0;}
if ((flag==1)&(even==0x4a)) {kbd='?';flag=0;}
if ((flag==1)&(even==0x55)) {kbd='+';flag=0;}
if ((flag==1)&(even==0x5d)) {kbd='|';flag=0;}
if ((flag==1)&(even==0x4e)) {kbd='_';flag=0;}
if ((flag==1)&(even==0x52)) {kbd='"';flag=0;}
if ((flag==1)&(even==0x4c)) {kbd=':';flag=0;}
if ((flag==1)&(even==0x54)) {kbd='{';flag=0;}
if ((flag==1)&(even==0x5b)) {kbd='}';flag=0;}
sprintf(buff,"%c",kbd); //tampilkan lcd
lcd_puts(buff);
delay_ms(10);
};
}


