标题: 单片机定时器中断按键扫描程序如何检测长按状态? [打印本页]
作者: PDDDF 时间: 2019-12-24 16:50
标题: 单片机定时器中断按键扫描程序如何检测长按状态?
unsignedchar Trg;
unsignedchar Cont;
voidKeyRead( void )
{
unsigned char ReadData = PINB^0xff; // 1
Trg = ReadData & (ReadData ^ Cont); // 2
Cont =ReadData; // 3
}
网上流传很广的3句语句实现按键扫描,自己用却不会用,只能做到检测单击按键,长按和双击检测不会做,求大佬指点
作者: PDDDF 时间: 2019-12-24 17:24
void key_scan()
{
uchar S,b;
S = P1^0xff;
if(0<S && S == R)
{
b = T;
T = S&(S^R);
R = S;
if(b != T)
{
if(S == 0x20) {key = 1; return;}
if(S == 0x10) {key = 2; return;}
if(S == 0x08) {key = 3; return;}
if(S == 0x18) {key = 8; return;}
}
else
{
if(S == 0x20) {key = 4; return;}
if(S == 0x10) {key = 5; return;}
if(S == 0x08) {key = 6; return;}
if(S == 0x18) {key = 9; return;}
}
}
else
{
T = S&(S^R);
R = S;
}
}
1238为对应按键的单击标识,4569为对应按键的长按标识,共4个按键, key_scan()放在中断函数里面,20MS扫描一次
while(1)
{
switch (key)
{
case......
}
}循环执行返回按键标识的对应程序
问题:无法辨别是单击或是长按,按了几下后卡死
作者: wulin 时间: 2019-12-24 23:17
不是简单的3条代码就搞定的,这只是读键过程,还要有其配套服务程序解读才能生效。
应用示例:
作者: PDDDF 时间: 2019-12-25 08:58
我最搞不懂的就是这个按键扫描是怎样做到消抖的,扫描我是放在中断里面执行的,一旦有触发信号(假设0x01),read Trg Con的值都为0x01,下一个中断到来时如果是真的按下(read继续读到0x01)那经过这个按键扫描算法的处理就变为read 0x01 Trg 0x00 Con 0x01 ,那判断两次读取的值一样才算消抖啊,但是这样就判断不了长按了,因为一直长按 R T C 的值都没变的,还是read 0x01 Trg 0x00 Con 0x01 ,这样我就搞不懂了
作者: wulin 时间: 2019-12-25 10:38
这是原作者的解释,是在特定的程序构架下才有效。
一款精巧的按键处理程序.doc
(36.5 KB, 下载次数: 51)
作者: PDDDF 时间: 2019-12-25 11:50
谢谢大佬
作者: 还有谁? 时间: 2019-12-25 13:39
其实思路很简单,在定时中断中判断一个按健按下来开始计数,然后这样:if((K1<40) && (K1>5) && (ON_flag==1))//消抖时间+去抖时间+开关标记,后面处理好清0事宜就好了
作者: 1394077003 时间: 2019-12-25 18:37
太好了 又学到了新知识 好评
作者: ahshmj 时间: 2019-12-25 18:54
和处理键抖动一回事,N次检测仍未释放就是长按......,N次加或减1,2N次加减2......,快速双击道理一样,检测的时间间隔不同。
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |