请指点行列式键盘扫描程序

[复制链接]
5989|14
 楼主| sfofyyy 发表于 2009-7-13 17:42 | 显示全部楼层 |阅读模式

 
下面是我写的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
 楼主| sfofyyy 发表于 2009-7-13 17:48 | 显示全部楼层

流程图

928315 发表于 2009-7-13 18:53 | 显示全部楼层

帮顶

汇编确实不怎么会玩
ayb_ice 发表于 2009-7-13 21:01 | 显示全部楼层

用反转扫描法效率最高

我是土匪 发表于 2009-7-13 21:08 | 显示全部楼层

汇编没有去看

有本书叫做<嵌入式架构> 里面有源码,其中有一章专门讲解行列式键盘,功能强大,稳定性好,可以移植性好,楼主有兴趣可以找一下,能下载到得
qianlong30 发表于 2009-7-13 23:57 | 显示全部楼层

太复杂了.

zjw5000 发表于 2009-7-14 11:30 | 显示全部楼层

5楼 ,《嵌入式架构》怎么搜不到

 楼主| sfofyyy 发表于 2009-7-16 10:08 | 显示全部楼层

谢谢大家

我也感觉有点复杂,不过有更好的算法吗?怎么改进呢?
用C的话可以循环嵌套,但这是汇编
huangqi412 发表于 2009-7-16 10:26 | 显示全部楼层

晕,反转扫描,然后查表.

lichunlian 发表于 2009-7-16 16:16 | 显示全部楼层

反转法

用反转法吧!!!那样效果或许更佳!!
古道热肠 发表于 2009-7-16 16:44 | 显示全部楼层

楼主这流程图画得漂亮

书名大概是叫<<嵌入式构件>>吧,老外写的,很有深度和借鉴性.
不知何为 发表于 2009-7-16 16:44 | 显示全部楼层

首次回复

行列式扫描键盘用一般都用反转法吧···
4*5会比4*4难办点  原理一样
我是土匪 发表于 2009-7-16 16:58 | 显示全部楼层

向7楼致歉

那本书的名字记错了,经核实为:《嵌入式系统构件》
943096020 发表于 2013-6-20 18:35 | 显示全部楼层
你是个高手啊,汇编头晕
流水随春去远 发表于 2013-6-23 01:18 | 显示全部楼层
帮顶


汇编确实不怎么会玩
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

174

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部