前面已经学习了单个按键的检测,今天我们来学学单个按键长按和短按的检测。利用一个按键实现数字增减操作。短按一次数码管数值加一,长按一次数码管数据减一。
一、长短按键的检测原理:
当检测到有按键按下时,启动定时器T0开始定时,置位按键按下标志位为1,设置定时器每10ms中断一次,在中断服务程序中让计数器R5的值加1。等待按键弹起,关掉定时器,清除按键按下标志位。然后根据R5的值乘以10ms得到按键按下去持续的时间,再用该时间和设定的阀值时间进行比较,如果小于阀值时间则判定为短按,否则为长按键。阀值可以更改,一般大于300ms认为是长按键,所以本实验设置阀值为300ms,当R5的值大于等于30时,就认为是长按键。
二、实验原理图
三、程序代码
/*********************************/
/*程序功能:主要用在按键较少的情况
该程序可以实现一个按键两种功能,短按一次
数码管数值加一,长按一次数码管数据减一
实现一个按键控制数据的增减
/*********************************/
keyold bit 20h.0 ;保存按键值
key bit p3.2 ;按键输入
LED bit p1.4 ;P1.4接LED
FMQ bit p2.4 ;蜂鸣器
DUAN equ P0 ;P0段码(共阳极)
WEI bit P2.0 ;位选端
org 0000h
ajmp main
org 000bh
;定时10ms
MOV TL0,#000H ;设置定时初值
MOV TH0,#0DCH ;设置定时初值
inc r5
reti
main:
ORL TMOD,#01H ;设置定时器模式
MOV TL0,#000H ;设置定时初值
MOV TH0,#0DCH ;设置定时初值
setb et0
setb ea
clr WEI ;位选打开,显示数码
loop:
acall keysan
acall disp
sjmp loop
keysan:
setb key ; 设置为输入
jnb f0,nodown ; 按键按下标志位f0,未按下转nodown
sjmp anxia ;按键按下转anxia
nodown:
mov c,key ;读取按键状态送C
mov keyold,c ;暂存按键值
jb keyold,keyend ;判断是否按下,没有按键按下转keyend
setb f0 ;只要按下f0置一,
setb tr0 ;启动定时器,每1ms中断一次,
mov r5,#0 ;R5计数器初始化,开始计时间
anxia:
jnb key,keyend ;没有松手转keyend
clr f0 ;按键抬起,清标志位
clr tr0 ;松手后才处理 ;主要配合按键发声,按下蜂鸣器发声
cjne r5,#30,panduan ;通过r5的值可以判断按键按下的时间的长短
;更改R5的比较值,可更改判断长、短按键的时间
panduan:
jc duanan ;r5的值小于30,按键时长小于300ms表示短按
mov r3,#01 ;按键时间>=300ms认为是长按键
sjmp keydata
duanan:
mov r3,#02 ;短按
keydata: ;按键数据处理
cjne r3,#01,jia ;r3为一,表示长按,数据减一
dec r0 ;数据减一
cjne r0,#0ffh,keyend
mov r0,#9
sjmp keyend
jia: inc r0 ;r3为2,表示短按,计数值加一
cjne r0,#10,keyend
mov r0,#00
keyend: ;在等待松手的时间里可以安排其他程序
ret
/*显示按键值*/
disp: ;显示按键值
mov a,r0 ;送待显示的数据
mov dptr,#tab ;段码首地址
movc a,@a+dptr
mov p0,a
ret
tab: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
end