📄 keyboard.c
字号:
/******************************************/
/* 广州天河双龙电子公司 */
/* http://www.sl.com.cn */
/* PS2键盘驱动程序 */
/* 作者:lpf@sl.com.cn */
/* 2003年8月28日 */
/* 目标MCU:MEGA16 晶振:外部(EXT) 8MHZ */
/******************************************/
#include<iom16v.h>
#include<macros.h>
#define PIN_DIR DDRD
#define PIN_KB PIND
#define PORT_KB PORTD
#define CLOCK 3
#define DATAPIN 2
#define BUFF_SIZE 64
#define fosc 8000000
//晶振8MHZ
#define baud 19200
//波特率
#pragma data:code
//设置数据区为程序存储器
//没有按下shift键的PC机键盘扫描码
const unsigned char unshifted[][2] = {
0x0d,9,0x0e,'`',0x15,'q',0x16,'1',0x1a,'z',0x1b,'s',0x1c,'a',0x1d,'w',0x1e,'2',
0x21,'c',0x22,'x',0x23,'d',0x24,'e',0x25,'4',0x26,'3',0x29,' ',0x2a,'v',0x2b,'f',0x2c,'t',0x2d,'r',0x2e,'5',
0x31,'n',0x32,'b',0x33,'h',0x34,'g',0x35,'y',0x36,'6',0x39,',',0x3a,'m',0x3b,'j',0x3c,'u',0x3d,'7',0x3e,'8',
0x41,',',0x42,'k',0x43,'i',0x44,'o',0x45,'0',0x46,'9',0x49,'.',0x4a,'/',0x4b,'l',0x4c,';',0x4d,'p',0x4e,'-',
0x52,0x27,0x54,'[',0x55,'=',0x5a,13, 0x5b,']',0x5d,0x5c,0x61,'<',0x66,8,0x69,'1',0x6b,'4',0x6c,'7',
0x70,'0',0x71,',',0x72,'2',0x73,'5',0x74,'6',0x75,'8',0x79,'+',0x7a,'3',0x7b,'-',0x7c,'*',0x7d,'9',0,0
};
//按下shift键的PC机键盘扫描码
const unsigned char shifted[][2] = {
0x0d,9,0x0e,'~',0x15,'Q',0x16,'!',0x1a,'Z',0x1b,'S',0x1c,'A',0x1d,'W',0x1e,'@',
0x21,'C',0x22,'X',0x23,'D',0x24,'E',0x25,'$',0x26,'#',0x29,' ',0x2a,'V',0x2b,'F',0x2c,'T',0x2d,'R',0x2e,'%',
0x31,'N',0x32,'B',0x33,'H',0x34,'G',0x35,'Y',0x36,'^',0x39,'L',0x3a,'M',0x3b,'J',0x3c,'U',0x3d,'&',0x3e,'*',
0x41,'<',0x42,'K',0x43,'I',0x44,'O',0x45,')',0x46,'(',0x49,'>',0x4a,'?',0x4b,'L',0x4c,':',0x4d,'P',0x4e,'_',
0x52,'"',0x54,'{',0x55,'+',0x5a,13, 0x5b,'}',0x5d,'|',0x61,'>',0x66,8,0x69,'1',0x6b,'4',0x6c,'7',
0x70,'0',0x71,',',0x72,'2',0x73,'5',0x74,'6',0x75,'8',0x79,'+',0x7a,'3',0x7b,'-',0x7c,'*',0x7d,'9',0,0
};
#pragma data:data
//设置数据区回到数据存储器
unsigned char bitcount; //pc键盘数据长度计数
unsigned char kb_buffer[BUFF_SIZE]; //键盘缓冲区
unsigned char input=0; //缓冲区读指针
unsigned char output=0; //缓冲区写指针
//键盘缓冲区使用软件模拟FIFO
void put_kbbuff(unsigned char c) //送键盘按键ASCII码到键盘缓冲区
{
kb_buffer[input]=c;
if (input<(BUFF_SIZE-1))
input++;
else
input=0;
}
unsigned char get_char(void) //从键盘缓冲区读取按键的ASCII码
{
unsigned char temp;
if (output==input)
return 0;
else
{
temp=kb_buffer[output];
if (output<(BUFF_SIZE-1))
output++;
else
output=0;
return temp;
}
}
void uart_init(void)
{
UCSRB=(1<<RXEN)|(1<<TXEN); //允许发送和接收
UBRRL=(fosc/16/(baud+1))%256;
UBRRH=(fosc/16/(baud+1))/256; //波特率19200
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8位数据+1位STOP位
}
void putchar(unsigned char c)
{
while (!(UCSRA&(1<<UDRE)));
UDR=c;
}
int puts(char *s)
{
while (*s)
{
putchar(*s);
s++;
}
putchar(0x0a); //回车换行
putchar(0x0d);
return 1;
}
void init_kb(void)
{
PIN_DIR&=~((1<<CLOCK)|(1<<DATAPIN));
PORT_KB|=(1<<CLOCK)|(1<<DATAPIN);
MCUCR = 0x08;
GICR = 0x80;
SEI();
bitcount = 11;
}
void decode(unsigned char sc) //对PC键盘的扫描码进行解码
{
static unsigned char shift,up,shiftup;
unsigned char i;
if (sc==0xf0) //按键释放
{
up=1;
return;
}
if (up==1) //SHIFT键开关
{
up=0;
if ((sc==0x12)|(sc==0x59)) shift=0;
return;
}
switch (sc) //检测左SHIFT键
{
case 0x12:{
shift=1;
shiftup=1;
}
case 0x59:{ //检测右SHIFT键
shift=1;
shiftup=1;
}
default:{
if (shift==0)
{
for(i = 0;unshifted[i][0]!=sc && unshifted[i][0]; i++);
if (unshifted[i][0] == sc)
put_kbbuff(unshifted[i][1]);
}
else
{
for(i = 0;shifted[i][0]!=sc && shifted[i][0]; i++);
if (shifted[i][0] == sc)
{
put_kbbuff(shifted[i][1]);
}
}
}
}
}
#pragma interrupt_handler int1_isr:iv_INT1
//键盘数据读取中断程序
void int1_isr(void)
{
static unsigned char data;
switch (bitcount)
{
case 11:{
if ((PIN_KB&(1<<DATAPIN))!=0)
return;
else
bitcount--;
break;}
case 2:{
bitcount--;
break;}
case 1:{
bitcount--;
if ((PIN_KB&(1<<DATAPIN))==0)
{
bitcount=11;
return;
}
else
{
bitcount=11;
decode(data);
}
break;}
default:{
data = (data >> 1);
if((PIN_KB&(1<<DATAPIN))!=0)
data|=0x80;
bitcount--;
}
}
}
//PC键盘演示程序,SHIFT键和按键同时按下时为大写
void main()
{
unsigned char key;
uart_init();
init_kb();
puts("双龙电子PC键盘演示程序:");
putchar(0x0d);
putchar(0x0d);
while(1)
{
key=get_char();
if (key!=0)
{
if (key==0x0d)
{
putchar('\n');
putchar(key);
}
else
putchar(key);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -