?? kb.c
字號:
/*---------------------------------------------------------
*Filename:kb.c
*Function:PS2鍵盤程序,忽略起始位、奇偶校驗位、停止位
*Author:ken
*Date:2007-8-18
----------------------------------------------------------*/
#include "kb.h"
#include "scancodes.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#define BUFF_SIZE 64
#define PSDAT PD6
#define PSCLK PD2
unsigned char edge, bitcount; //edge表示是下降沿讀取,還是上升沿讀取;bitcount是一幀的位數
unsigned char kb_buffer[BUFF_SIZE];
unsigned char *inpt, *outpt;
unsigned char buffcnt; //用于記錄當前的緩沖區讀或寫的位置
/*-----------------------------------------------------------
InitKeyBoard :鍵盤程序初始化函數
輸入參數 :無
輸出參數 :無
作者 :ken
日期 :2007-8-18
------------------------------------------------------------*/
void InitKeyBoard(void)
{
inpt = kb_buffer; // 初始化鍵盤緩沖區
outpt = kb_buffer;
buffcnt = 0;
MCUCR = (1<<ISC01); // INT0下降沿有效
edge = 0; // 0 = 下降沿 1 = 上升沿
bitcount = 11; // PS2傳輸一幀數據是11位,一個起始位,一個奇偶校驗位,一個停止位。
sei(); // 開全局中斷
}
/*-----------------------------------------------------------
INT0_interrupt:處理鍵盤中斷服務程序
輸入參數 :無
輸出參數 :無
作者 :ken
日期 :2007-8-18
------------------------------------------------------------*/
SIGNAL(SIG_INTERRUPT0) //PSCLK與PD2即INT0連接,下降沿讀取PSDAT的數據
{
static unsigned char data; // data用來保存接收到的數據。
if(bitcount < 11 && bitcount > 2) // 3-10位是數據位. 忽略起始位,校驗位,停止位
{
data = (data >> 1); //因為PS2協議是低位在前的,所以要右移
if(PIND & (1<<PSDAT))
data = data | 0x80;
}
if(--bitcount == 0) // 11位數據都接收完,進入解碼程序
{
decode(data);
bitcount = 11;
}
}
/*-----------------------------------------------------------
decode :解碼鍵碼程序
輸入參數 sc :8bit原始代碼數據
輸出參數 :無
作者 :ken
日期 :2007-8-18
------------------------------------------------------------*/
void decode(unsigned char sc)
{
static unsigned char is_up=0, shift = 0, mode = 0;
unsigned char i;
if (!is_up) // Last data received was the up-key identifier
{
switch (sc)
{
case 0xF0 : // The up-key identifier
is_up = 1;
break;
case 0x12 : // Left SHIFT
shift = 1;
break;
case 0x59 : // Right SHIFT
shift = 1;
break;
case 0x05 : // F1
if(mode == 0)
mode = 1; // Enter scan code mode
if(mode == 2)
mode = 3; // Leave scan code mode
break;
default:
if(mode == 0 || mode == 3) // If ASCII mode
{
if(!shift) // 識別有沒有按下shift鍵
{ // for語句又于尋找鍵盤碼
for(i = 0; unshifted[i][0]!=sc && unshifted[i][0]; i++);//輸出沒按shift鍵的碼
if (unshifted[i][0] == sc) {
put_kbbuff(unshifted[i][1]);
}
} else { // If shift pressed
for(i = 0; shifted[i][0]!=sc && shifted[i][0]; i++);//輸出按下shift鍵的碼
if (shifted[i][0] == sc) {
put_kbbuff(shifted[i][1]);
}
}
}
else{ // Scan code mode
print_hexbyte(sc); // Print scan code
put_kbbuff(' ');
}
break;
}
} else {
is_up = 0; // Two 0xF0 in a row not allowed
switch (sc)
{
case 0x12 : // Left SHIFT
shift = 0;
break;
case 0x59 : // Right SHIFT
shift = 0;
break;
case 0x05 : // F1
if(mode == 1)
mode = 2;
if(mode == 3)
mode = 0;
break;
case 0x06 : // F2
break;
}
}
}
/*-----------------------------------------------------------
put_kbbuff :鍵碼保存到緩沖區
輸入參數 c :經解碼所得鍵碼數據
輸出參數 :無
作者 :ken
日期 :2007-8-18
------------------------------------------------------------*/
void put_kbbuff(unsigned char c)
{
if (buffcnt<BUFF_SIZE) // If buffer not full
{
*inpt = c; // Put character into buffer
inpt++; // Increment pointer
buffcnt++;
if (inpt >= kb_buffer + BUFF_SIZE) // Pointer wrapping
inpt = kb_buffer;
}
}
/*-----------------------------------------------------------
getchar_kb :鍵碼接收程序
輸入參數 :無
輸出參數 :鍵碼
作者 :ken
日期 :2007-8-18
------------------------------------------------------------*/
unsigned char getchar_kb(void)
{
unsigned char byte;
while(buffcnt == 0); // Wait for data
byte = *outpt; // Get byte
outpt++; // Increment pointer
if (outpt >= kb_buffer + BUFF_SIZE) // Pointer wrapping
outpt = kb_buffer;
buffcnt--; // Decrement buffer count
return byte;
}
/*-----------------------------------------------------------
print_hexbyte :直接保存原始8bit代碼到緩沖區,不經解碼
輸入參數 i :原始8bit代碼
輸出參數 :無
作者 :ken
日期 :2007-8-18
------------------------------------------------------------*/
void print_hexbyte(unsigned char i)
{
unsigned char h, l;
h = i & 0xF0; // 高4位
h = h>>4;
h = h + '0';
if (h > '9')
h = h + 7;
l = (i & 0x0F)+'0'; // 低4位
if (l > '9')
l = l + 7;
put_kbbuff(h);
put_kbbuff(l);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -