There are two main portions of code that we are concerned with:
-Main Loop
-Capture Interrupt Routine
The main loop will have the job of running through the buffer of input commands and executing them to the 7-segment led. The code below is a little abridged, but you can get the general idea of what is going on.
Main Loop
------------« Begin Code »------------
#include <p18f452.h> #include <cature.h> #include <timers.h> #include <delays.h> //7-Segment Display Output #define number_0 0b01111110 .. ... .. #define letter_a 0b11101110 #define letter_b 0b11111110 .. ... .. void main(void){ TRISC = 0xFF; TRISD = 0x01; PORTB = 0x00; PORTC = 0x00; //7-Seg LED is Reverse Polarity PORTD = 0x00 ^ 0xFF; Delay10KTCYx(10); INTCON = 0b11000000; OpenCapture1( C1_EVERY_FALL_EDGE & CAPTURE_INT_ON ); OpenTimer1( TIMER_INT_ON & T1_SOURCE_INT & T1_PS_1_1 & T1_16BIT_RW ); WriteTimer1( 0x0000 ); while(1) { if(buf_ready == 1){ switch(scan_code_buf[0]){ case 0x1C : PORTD = (letter_a ^ 0xFF); break; ... .... .. break; case 0x45 : PORTD = (number_0 ^ 0xFF); break; case 0x66 : PORTD = (delete ^ 0xFF); break; default : break; } //Shift Buffer Forward scan_code_buf[0] = scan_code_buf[1]; scan_code_buf[1] = scan_code_buf[2]; scan_code_buf[2] = scan_code_buf[3]; scan_code_buf[3] = scan_code_buf[4]; scan_code_buf[4] = scan_code_buf[5]; scan_code_buf[5] = scan_code_buf[6]; scan_code_buf[6] = scan_code_buf[7]; scan_code_buf_cnt--; if(scan_code_buf_cnt == 0) buf_ready = 0; } Delay10KTCYx(1); } }
------------« End Code »------------
So the main loop's purpose is to parse the incoming data that is inside of a fifo buffer. The code below is the interrupt service routine which receives the PS/2 data and puts it into that FIFO buffer. The Keypress release 0xF0 is ignored, only keyboard scan code are given any priority.
Two Interrupt Service Routines
------------« Begin Code »------------
void InterruptHandlerHigh(void) // Declaration of InterruptHandler //Check If TMR1 Interrupt Flag Is Set if(PIR1bits.CCP1IF){ if(bit_counter < 10){ current_scan_code = current_scan_code >> 1; current_scan_code += (PORTDbits.RD0*0b10000000000); bit_counter++; } else if(bit_counter == 10){ scan_code_buf[scan_code_buf_cnt]=(current_scan_code>>2)&0xFF; scan_code_buf_cnt++; buf_ready = 1; bit_counter = 0; } WriteTimer1( 0x0000 ); //Clear CCP1 Overflow Flag Bit PIR1bits.CCP1IF = 0; } //Check If CCP1 Interrupt Flag Is Set else if(PIR1bits.TMR1IF){ //Clear Timer1 Overflow Flag Bit bit_counter = 0; PIR1bits.TMR1IF = 0; } INTCONbits.GIE = 1; }
------------« End Code »------------
As you can see above, the Capture module interrupt and timer1 are used together to make sure that we only catch the 8 data bits and not the start, stop or parity bits. I'm sure a better parsing routine could be created, but for now, the one above works just fine.