|
#include <pgmspace.h> #include "kb.h" #include "serial.h" #include "gpr.h" #include "scancodes.h" #define BUFF_SIZE 64 unsigned char edge, bitcount; // 0 =符號. 1 = 正號. unsigned char kb_buffer[BUFF_SIZE]; unsigned char *inpt, *outpt; unsigned char buffcnt; void init_kb(void) { inpt = kb_buffer; // 初始化緩沖區(qū) outpt = kb_buffer; buffcnt = 0; MCUCR = 2; // INT0 中斷,下降沿觸發(fā) edge = 0; // 0 = 下降沿; 1 = 上升沿 bitcount = 11; } interrupt [INT0_vect] void INT0_interrupt(void) { static unsigned char data; // 保持接受掃描碼的狀態(tài) if (!edge) // 下降沿觸發(fā)中斷服務(wù)程序 { if(bitcount < 11 && bitcount > 2) // 3到10位是數(shù)據(jù), { // 忽略起始和停止位 data = (data >> 1); if(PIND & 8) data = data | 0x80; // 存儲一個'1' } MCUCR = 3; // 用上升沿引發(fā)中斷 edge = 1; } else { // 上升沿觸發(fā)中斷服務(wù)程序 MCUCR = 2; // 用下降沿引發(fā)中斷 edge = 0; if(--bitcount == 0) // 接受到所有的數(shù)據(jù)位 { decode(data); bitcount = 11; } } } void decode(unsigned char sc) { static unsigned char is_up=0, shift = 0, mode = 0; unsigned char i; if (!is_up) // 最后一位數(shù)據(jù)接受 { switch (sc) { case 0xF0 : // 確定完成鍵 is_up = 1; break; case 0x12 : // 左SHIFT按鍵 shift = 1; break; case 0x59 : // 右SHIFT按鍵 shift = 1; break; case 0x05 : // F1鍵 if(mode == 0) mode = 1; // 進(jìn)入按鍵掃描碼模式 if(mode == 2) mode = 3; // 離開按鍵掃描碼模式 break; default: if(mode == 0 || mode == 3) // ASCII 模式 { if(!shift) //如果沒有SHIFT鍵按下, { // 查表 for(i = 0; unshifted[i][0]!=sc && unshifted[i][0]; i++); if (unshifted[i][0] == sc) { put_kbbuff(unshifted[i][1]); } } else { // 如果SHIFT鍵按下 for(i = 0; shifted[i][0]!=sc && shifted[i][0]; i++); if (shifted[i][0] == sc) { put_kbbuff(shifted[i][1]); } } } else { // 掃描鍵盤碼模式 print_hexbyte(sc); // 顯示模式 put_kbbuff(' '); put_kbbuff(' '); } break; } } else { is_up = 0; // 2個 0xF0在一列中是不允許的 switch (sc) { case 0x12 : // 左 SHIFT shift = 0; break; case 0x59 : // 右SHIFT shift = 0; break; case 0x05 : // F1 if(mode == 1) mode = 2; if(mode == 3) mode = 0; break; case 0x06 : // F2 clr(); break; } } }
void put_kbbuff(unsigned char c) { if (buffcnt<BUFF_SIZE) // 若緩沖區(qū)為空 { *inpt = c; // 在緩沖區(qū)中輸入一個字符 inpt++; // 指針加1 buffcnt++; if (inpt >= kb_buffer + BUFF_SIZE) // 指針判斷 inpt = kb_buffer; } } int getchar(void) { int byte; while(buffcnt == 0); // 等待數(shù)據(jù) byte = *outpt; // 取數(shù)據(jù) outpt++; // 指針加1 if (outpt >= kb_buffer + BUFF_SIZE) // 指針比較 outpt = kb_buffer; buffcnt--; // 緩沖區(qū)減去1 return byte; } |