on Wednesday, 4 December 2013

Do you want to interface computer keyboard to your microcontroler, then this is a good chance to learn and can do it by yourself. I'm using PIC , but concept is the same for all other microcontrollers. Better not to waste time, just dive in..

Basic understanding:
First we need to know few basics of ps2 keyboard i.e what are the protocols and how they transmit data and so on..
Ps2 Keyboard:
Ps2 keyboard will have 6 pins for male plug and 6 for female plug, fig.1 shows the male plug of keyboard and fig2 is the female plug

Now let us see which pin do what,

>>They sends and receive data serially i.e only on one transmitting line.
>>Pin1 is the data line, which sends the data (ex: when key is pressed then data will be send through this line) and also receives data (ex: when leds of caps, scroll, num  need to be blink or ON or OFF then keyboard takes the instructions from this line)
>> Pin5 is the clock line, i.e keyboard will send clock pulses through this line. It is necessary to know about these two lines i.e data line and clock line and also how they work inter dependent.
To have a clear picture i'll explain you how the data and clock go on, check the below fig.

Important Points:
>>Observe the above fig. clock .All pulses will have the rising edge and falling edge. To say simply, raising edge is nothing but when the clock pulse will raise from bottom to top is called raising edge, whenever pulse fall from top to bottom(indicated by arrow marks above) are falling edge.
>>Data which is sending by the keyboard will have one start bit and one stop bit, always stop bit will be high(1) and start bit low(0) i.e for example the data is something like "10101000" then by adding start and stop bit it will be like this "0101010001"  i.e 8bits data and 2 bits additional.
>>The most important point we need to keep in mind while writing code is that, microcontroller need to check for input bit for every falling edge. It means if microcontroller realizes that clock pin is having falling edge then immediately  data pin should be checked for input data.
>> Micro-controller receive LSB first and then MSB that means keyboard sends first LSB and then MSB.
>> Whenever we press the key, then  a special value will be send though data pin. Every key will have a unique value. For example if we press key A then "11100" will be transmitted i.e '1c' hex value will be transmitted. All the key values are shown below

NOTE: When a key is pressed a separate code will be transmitted when key is released a different code will be transmitted, when a key is pressed for certain time or when we hold the key then a separate code will be transmitted. Dont worry about all these codes just consider standard code which will be transmitted after key is pressed and key is released.
How it works internally(Algorithm):
>> Initialize the Interrupts of the microcontroller for fallen edge of the clock.
>> For every falling edge an interrupt will be produced, then check the input pin for the input bit.
>>Store the bit in any variable and shift right(>>) , because first we get LSB and then MSB.
>>After we get all the 10bits , check the data bits and compare with all the key values and print it on to the lcd module
Project requirements:
  • MikroC compiler(download free from official website)
  • Micro controller- pic18f452
  • Lcd-16x2
  • Resistors-4.7k ohm , 10k ohm(1)
  • capacitors-30 pf(2), 0.1 uf, 100uf  crystal oscillator 4Mhz
  • 9v battery , Lm7805 voltage regulator
Circuit diagrams:
POWER SUPPLY:As we are using 9v input battery , so we need to convert it to 5v using 7805 Ic.

Overall circuit look like this:

The general connections for pic are the same
i.e crystal oscillator between 13 and 14th pin, pin31=pin12=ground,pin11=pin32=vcc.
MikroC is one of the comprehensive software which have lot of inbuilt libraries. We need not to worry about writing code for general modules interfacing like Lcd's, keypad's, and many more.. so basic idea at C language is enough to code using MikroC compiler.
Now let us analyze the code, i'll explain few impotent content in the code section so that when u see the code you can easily understand as a whole..
Configure the LCD
sbit Lcd_Rs at RC4_bit;
sbit lcd_en at Rc5_bit;
sbit lcd_d4 at rc0_bit;
sbit lcd_d5 at rc1_bit;
sbit lcd_d6 at rc2_bit;
sbit lcd_d7 at rc3_bit;
sbit Lcd_Rs_direction at TRISC4_bit;
sbit Lcd_EN_direction at TRISC5_BIT;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;
Main program
void main()
TRISC=0X00;//making portC as output
TRISD=0XFF;//making portd as input
INTCON2.INTEDG1=0; //interrupt on falling edge
INTCON3.INT1IE=1; //external interrupt enable
INTCON3.INT1IP=0; //low priority
INTCON3.INT1IF=0; //clearing interrupt flag, when interrupt occur it will be '1'
INTCON.GIEL=1; //enables all low priority interrupts
// lcd config
Lcd_cmd(_Lcd_clear); // lcd clear
Lcd_out(1,1,"welcome"); //show welcome on lcd
Lcd_cmd(_lcd_clear); //clear lcd
INTCON.IPEN=1; //start
while(1)  //do always
      if(rdy==1) //if received data is ready then
        switch(answer) //received data in the answer variable
          case 0x1c: //code for A
          case 0x32: //code for B
          case 0x21: //code for C
          ---------------------------- //so on
          case 0x1A: //code for Z
          case 0x45: // code for zero
          case 0x46:
         answer=0; //make answer zero for receiving fresh data
         rdy=0; // received flag zero
Interrupt service routine
 void interrupt()
     if(INTCON3.INT1IF==1)     //if interrupt flag is high
          if(count>1 && count<10)
           if(portd.f0==1)answer=answer|0x80;    // if input bit is high
           if(count>1 && count<9)answer=(answer>>1);  // need to shift 7times,not to loose last  bit
          INTCON2.INTEDG1=0; //making falling edge interrupt
Download  full code from below
Author: Youstron Sic
Special thx to Micro Arena group , SHerzod Bek, Ro Wyak Sun, pyro website, and Google