按键消抖是否必须空等待

f4016 2012-06-18 11:58:51
小弟初学单片机,看教材的按键消抖均采用delay()函数。
请问各位大侠,在实际工程应用中是否这样,让CPU什么也不做等待10ms?
...全文
531 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
sterrys 2012-08-13
  • 打赏
  • 举报
回复
定时中断中加状态判断计数
linliangqiu 2012-08-13
  • 打赏
  • 举报
回复
定时中断加状态机
akeeenet 2012-07-24
  • 打赏
  • 举报
回复
不一定,简单的程序可以吧,如果想要程序高效一点,举个例子吧,液晶固定显示,延时,清屏。等待的时间完全可以让单片机去干别的事,从而使程序高效一些,简洁一些,而且,更稳定一些。
skertone 2012-07-12
  • 打赏
  • 举报
回复
十个硬件/嵌入 式工程师 九个会直接 delay 而且在中断例程中 delay的我都见到过。

总的来说,够用就行了。

完美的方式,是中断触发并作全局标记,然后定时来扫描 既可以实现防抖,还可以实现 键按下/弹起 两个状态均能被应用层处理。


另外就是 按下不松的话,可以很方便地实现 “自动连续按键”

当然这个会需一个定时器资源。
nobita88513 2012-07-11
  • 打赏
  • 举报
回复
空等待差不多5ms就够了
蒙古战狼 2012-07-11
  • 打赏
  • 举报
回复
有篇文章叫做“从单片机初学者迈向单片机工程师”那里面介绍的按键应该大多数情况都可以用。
dceacho 2012-06-25
  • 打赏
  • 举报
回复
给一次程序你参考下,可以根据key1cnt的值来判断按键是否长按
[/CODE=C/C++]
//按键上升沿有效
//不只是读取按键
//如果需要调整按键位置,这里修改,global.h中keyupcnt,keydowncnt也需要修改
typedef struct{
uint32_t set:1;
uint32_t down:1;
uint32_t up:1;
uint32_t ok:1;
uint32_t reserve:28;
}KEY_T;
KEY_T keyv;
void keyread(void)
{
if(DrvGPIO_GetBit(KEY1)==0)
{
key1cnt++;
}
else
{
if(key1cnt>=LENTH_KEYS)keyv.set=true;
key1cnt=0;
}

if(DrvGPIO_GetBit(KEY2)==0)
{
key2cnt++;
}
else
{
if(key2cnt>=LENTH_KEYS)keyv.ok=true;
key2cnt=0;
}

if(DrvGPIO_GetBit(KEY3)==0)
{
key3cnt++;
}
else
{
if(key3cnt>=LENTH_KEYS)keyv.down=true;
key3cnt=0;
}
if(DrvGPIO_GetBit(KEY4)==0)
{
key4cnt++;
}
else
{
if(key4cnt>=LENTH_KEYS)keyv.up=true;
key4cnt=0;
}

DrvGPIO_SetBit(KEY1);
DrvGPIO_SetBit(KEY2);
DrvGPIO_SetBit(KEY3);
DrvGPIO_SetBit(KEY4);

}

[/CODE]
of123 2012-06-25
  • 打赏
  • 举报
回复

1 可以直接延时,然后再检查键位。

2 更常用的是,利用 Timer 中断(例如 10ms),当在中断服务中检查到 n 次同一键位,就认为是按下了该键。n 的值相关于你去抖动的时值。这样做的目的,是可以同时处理其他事务。



aydf1 2012-06-22
  • 打赏
  • 举报
回复
看具体情况了,实时性要求不高这样最简单。
zhuoxizx 2012-06-22
  • 打赏
  • 举报
回复
定时中断也可以吖
御猫 2012-06-21
  • 打赏
  • 举报
回复
看具体情况了,实时性要求不高这样最简单。
cramkl 2012-06-21
  • 打赏
  • 举报
回复
看你实际系统的情况,对实时性要求不高的,建议就直接延时吧,简单可靠,实际工业应用中,简单可靠是最重要的。如果说实时性要求很高,那另当别论。
图灵狗 2012-06-21
  • 打赏
  • 举报
回复
如果没有操作系统的话,那么你可以在主体上用状态机,保证各个任务并行执行,当你的按键扫描在等待的时候,其它的任务照常在执行就行。
f4016 2012-06-18
  • 打赏
  • 举报
回复
那是否按键扫描程序写在定时中断函数内?
有没有实际工程实例的程序段贴上一段
不胜感谢
net_friends 2012-06-18
  • 打赏
  • 举报
回复
用定时器中断嘛
ymm198606 2012-06-18
  • 打赏
  • 举报
回复
可取多次平均值,但保证每次取值都在按键有效范围内;
dsoyy 2012-06-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
那是否按键扫描程序写在定时中断函数内?
有没有实际工程实例的程序段贴上一段
不胜感谢
[/Quote]

中断要尽量简洁。

终端中置位一个标志,主循环去查询,比较合理。
dsoyy 2012-06-18
  • 打赏
  • 举报
回复
坦白的讲,实际代码中99%用的都不是延时。

常用方法:
如楼上说的中断,端口产生中断,置位一个标志,主循环去查询标志;
计数消抖也是很常用的方式。

推荐楼主一片不错的文章《匠人手记》之《按键漫谈》,时序图,代码,单击、连击等等讲解详细,难得好书.
网络版很容易搜到。

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧