下面是我写的EM78P510N的4×5行列键盘扫描程序,20ms循环一次, 其中:k1,k2,k3,k4为输出,复用4个LED;ka,kb,kc,kd,ke为输入,外部上拉。 拿出来希望大家多扔点砖头过来,以便提高改进。 readkey: ;20ms扫描一次,说明:扫描到的键值没有来得及 ;发送时又扫描到其他键值时,会被覆盖掉 bank 0 bc port7,led_con ;扫描前关闭指示灯使能端 mov a,port9 mov port9_buff,a ;保存指示灯状态 nop bc port9,k1 ;扫描第一行 bs port9,k2 bs port9,k3 bs port9,k4 mov a,@1 mov key_databuff,a ;先假定为1 nop nop nop nop nop nop jbs porta,ka jmp first_read_k_over inc key_databuff jbs porta,kb jmp first_read_k_over inc key_databuff jbs porta,kc jmp first_read_k_over inc key_databuff jbs porta,kd jmp first_read_k_over inc key_databuff jbs porta,ke jmp first_read_k_over inc key_databuff ;;;;;;;;;;;;;;;;;;;;; bs port9,k1 ;扫描第二行 bc port9,k2 bs port9,k3 bs port9,k4 nop nop nop nop nop nop nop nop jbs porta,ka jmp first_read_k_over inc key_databuff jbs porta,kb jmp first_read_k_over inc key_databuff jbs porta,kc jmp first_read_k_over inc key_databuff jbs porta,kd jmp first_read_k_over inc key_databuff jbs porta,ke jmp first_read_k_over inc key_databuff ;;;;;;;;;;;;;;;;;;;;; bs port9,k1 ;扫描第三行 bs port9,k2 bc port9,k3 bs port9,k4 nop nop nop nop nop nop nop nop jbs porta,ka jmp first_read_k_over inc key_databuff jbs porta,kb jmp first_read_k_over inc key_databuff jbs porta,kc jmp first_read_k_over inc key_databuff jbs porta,kd jmp first_read_k_over inc key_databuff jbs porta,ke jmp first_read_k_over inc key_databuff ;;;;;;;;;;;;;;;;;;;;; bs port9,k1 ;扫描第四行 bs port9,k2 bs port9,k3 bc port9,k4 nop nop nop nop nop nop nop nop jbs porta,ka jmp first_read_k_over inc key_databuff jbs porta,kb jmp first_read_k_over inc key_databuff jbs porta,kc jmp first_read_k_over inc key_databuff jbs porta,kd jmp first_read_k_over inc key_databuff jbs porta,ke jmp first_read_k_over nokey: clr key_databuff ;无键 bc keyflag,keydown ;按键按下标志 bank 2 clr key_datalast clr keydown_cnt jmp readkey_out
first_read_k_over: bank 0 ;复合键判断 bs port9,k1 ;扫描第三行 bs port9,k2 bc port9,k3 bs port9,k4 nop nop nop nop nop nop nop nop jbc porta,ke jmp first_read_k_over_0 bs port9,k1 ;扫描第四行 bs port9,k2 bs port9,k3 bc port9,k4 nop nop nop nop nop nop nop nop jbc porta,ke jmp first_read_k_over_0 mov a,@21 mov key_databuff,a jmp first_read_k_over_1 ;是紧急按钮则直接跳到1,不经过有键按下检查 first_read_k_over_0: jbc keyflag,keydown jmp readkey_out ;确定有普通键按下时(已发送)不响应其他按键 ;------------------------ mov a,key_databuff jbc status,z jmp nokey sub a,@21 jbs status,c jmp nokey ;------------------------检查键值是否在1-21范围内,防止出错 first_read_k_over_1: mov a,key_databuff bank 2 xor a,key_datalast jbs status,z jmp key_different ;键值与前一次不同 inc keydown_cnt ;键值与上一次相同,则计相同次数 mov a,@4 ;是否连续有相同按键4次 sub a,keydown_cnt jbs status,c jmp readkey_out clr keydown_cnt bank 0 ;--------------------------- bs keyflag,keydown ;有键按下状态标志(确定有键)
bs uart_sendflag2,key_send ;uart使用请求标志,申请使用uart mov a,key_databuff lcall key_table ;键值转换 mov key_data_uartsend_buff,a ;--------------------------------------------------------- jmp readkey_out key_different: bank 0 mov a,key_databuff bank 2 mov key_datalast,a ;与上次不同,保存当前键值 clr keydown_cnt jmp readkey_out readkey_out: bank 0 bc port9,k1 bc port9,k2 bc port9,k3 bc port9,k4 ;停止行输出 bs port7,led_con ;扫描后打开指示灯使能端 mov a,port9_buff mov port9,a ;恢复指示灯状态 ret |