
扫描码键值转换程序流程第一类按键的扫描码键值转换程序代码:
if (F0_FLAG) {//接收扫描码为断码
switch (mcu_revchar){//处理控制键
case 0x11: agcs_status&=0xF7break//左alt释放
case 0x12: agcs_status&=0xFEbreak//左shift释放敬并困
case 0x14: agcs_status&=0xFDbreak//左ctrl释放
case 0x58: if(led_status&0x04)
led_status&=0x03//caps lock键
else led_status =0x04
ps2_ledchange()
break
case 0x59: agcs_status&=0xEFbreak//右shift释放
case 0x77: if(led_status&0x02)
led_status&=0x05//num lock键
else led_status =0x02
ps2_ledchange()
break
case 0x7E: if(led_status&0x01)
led_status&=0x06//scroll lock键
else led_status =0x01
ps2_ledchange()
break
default:break
}
F0_FLAG = 0
}
else {//接收扫描码为通码
if (led_status &0x04) caps_flag = 1else caps_flag = 0
if (led_status &0x02) num_flag = 1else num_flag = 0
if (scga_status &0x11) shift_flag = 1else shift_flag = 0
file://扫描码键值转换
if ((caps_flag == shift_flag) (!num_flag))
KeyVal=kb_plain_map\[mcu_revchar\]
else KeyVal=kb_shift_map\[mcu_revchar\]
switch(mcu_revchar){//处理控制键或状态键
case 0x11: agcs_status = 0x08//左alt按下
case 0x12: agcs_status = 0x01//左shift按下
case 0x14: agcs_status = 0x02//左ctrl按下
case 0x59: agcs_status = 0x10//右shift按下
default: break
}
}第二类按键的扫描码键值转换程序与上相似。要注意的是在退出该程序段时对
E0_FLAG和F0_FLAG标志的清0。
PAUSE键的处理程序:如果接收到0xE1,置E1_FLAG=1,然后顺次将后续接收到的7
个字节数据和亮念PAUSE的通码后7个字节比较,一致则返回KeyVal=KB_PAUSE。在比较
完所有7个字节后清除E1_FLAG标志。
键盘初始化程序kb_init()流程:
① 上电后,接收键盘上电自检通过信号0xAA,或者自检出错信号0xFC。单片机接
收为0xAA,进入下一步,否则,进行出错处理。
② 关LED指示,单片机发送0xED,然后接收键盘回应0xFA,接着发送送0x00接收
0xFA。
③ 设蔽樱置机打延时和速率。 单片机发送0xF3,接收0xFA,发送0x00
(250ms,2.0cps),接收0xFA。
④ 检查LED,发送0xED,接收0xFA,发送0x07(开所有LED),接收0xFA。发送0xED,
接收0xFA,发送0x00(关LED),接收0xFA。
⑤ 允许键盘发送0xF4,接收0xFA。
键盘LED改变ps2_ledchange()函数流程:发送0xED→接收0xFA→发送led_status→接收0xFA。
结语
该驱动程序经Keil uVision2编译,在AT89C51单片机上运行通过,实现了对PS/2 104键盘的支持,以及对字符按键大小写切换,num lock切换,控制键及组合按键的支持。该程序对其他嵌入式或单片机系统中PS/2键盘的应用也有借鉴意义。
键盘扫描子程序: KEY1 : ACALL KS1 调用判断有无键按下子程序 JNZ LK1 有键按下,转LK1 AJMP KEY1 无键按下,返回 LK1:ACALL T12MS 调延时12ms子游握拿程序 ACALL KS1 查有无键按下 JNZ LK2 若有,则为键确实按下,转逐列扫描 AJMPKEY1 无键按下,返回 LK2: MOVR4,#00H 首列号R4 MOVR2,#FEH 首列扫描字R2 LK4: MOVA,R2 列扫描字P1口 MOVP1,A 使第一列线为0 MOV A,P1 读入行状态 JB ACC.0,LONE 第0行无键按下,转查第一行 MOVA,#00H 第0行有键按下,该行首键号#00H AJMPLKP 转求键号 LONE: JB ACC.1,NEXT 第一行无键按下,转查下一列 MOVA,#02 第一行有键按下,该行首键号#02 LKP: ADD A,R4 键号=首行号+列号 PUSHACC 键号进栈保护 LK3: ACALL KS1 等待键释放 JNZ LK3 未释放,等待 POP AC 键释放,键号 RET 键扫描结束 NEXT:INC R4 列号加1,指向下一列 MOV A,R2 列扫描字 JNB ACC.1,KND 判断2列全扫描完?扫描完,转KND RL A 没扫描完,扫描字左移一位,形成下一列扫描字 MOV R2,A 扫描字 AJMP LK4 扫描下一列 AJMP KEY1 全扫描完,返回 MOV A,#FCH 全扫描字11111100B MOV P1,A 全扫描字所有行 MOV A,P1 读取列值 CPL A 取正皮银逻辑,高电平表示有键按下 ANL A,#0C0H 屏蔽低6位,取高神搭2位 RET 出口状态(A)!=0,有键按下欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)