Nita Gici's Blog

^^trusted information found here^^

Embedded system: Interfacing ps/2 pc keyboard to AVR ATMega8535 microcontroller June 15, 2010

Filed under: electronics — nitagici @ 2:23 am

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);

 };

}
About these ads
 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.