完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
按键抖动
成功扫描到按键按下后,由于按键本身有着不可避免的抖动问题,一般我们会设置一段延时,延时过后再次判断按键是否按下。 这是使用逻辑分析仪捕捉的一个按键从按下到松开的过程(高电平为按下)。可以发现,在按下的一瞬间,按键的电平发生了一段无规律跳动,这个就是抖动。 很多在学校的小伙伴可能对这种现象不以为然。当然,设置一小段时间的delay的确可以解决这个问题。但在一些公司的项目开发中,是不允许使用任何的延时函数的,这会造成主程序的阻塞(即使是几毫秒的延时阻塞也不允许),用按键触发的外部中断或者用while来判断按键松开也会对主函数造成一瞬间的阻塞(不松开按键主程序就无法继续执行那种),这也是不允许的。 那么,不允许使用延时函数来过滤抖动信号,还有什么方法来解决这个问题呢? 很多小伙伴应该会立马给出一个答案:定时器。 定时器的确可以完美解决这个问题。将定时器配置为每1ms触发一次定时器中断,或者每5ms、10ms触发一次,通过这个设置计时标志,只需要检测这个计时标志是否到达所需要的时间,到了之后再检测按键是否按下。期间不会对主程序造成阻塞,程序会一直循环执行。 比如我们配置一个定时器TIM2 static void MX_TIM2_Init(void) { //Tout = ((10 Period)*(7200 Prescaler))/72000000 Hz(外部高速时钟) = 0.001s TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 7200-1; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 10-1; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } } 每1ms触发一次计数溢出中断,函数外部设置一个全局变量,在中断回调函数中每触发一次对这个值进行自增。 uint16_t ShakeTime = 0; //全局变量 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if (htim->Instance == htim2.Instance){ ShakeTime++; //这个的作用是防止计数溢出。对这个全局变量清零的比较频繁的话可以不用这段代码 if (ShakeTime >= 32768){ ShakeTime = 0; } } } 每1ms触发一次计数溢出中断,也就是说这个全局变量每1ms自增一次。 在检测到按键按下后,把这个值清零,之后在每一轮的程序循环中,只需要检测这个全局变量是否自增到了某个数字,到了之后再对按键电平进行检测即可。 特殊情况 我们对这个按键抖动的问题一般只对按下时进行解决而已,但有没有想过,在松开的瞬间,按键是否也会产生抖动? 答案是有的,不过松开按键产生抖动的情况可能会比按下按键的情况少一点,但在项目开发中,如果对产品设计严格一点的话,这也是一个不允许被忽略的问题。 从图中我们可以看到,按键按下跟松开时都有一段时间的抖动。比如按键操作一个LED灯,结合上述提出的情况,这段松开按键的过程如果不做任何处理的话,很有可能会造成一瞬间的一亮一灭,然后又会点亮。在严格一点的项目开发中是不允许这种情况出现的。 什么,你说松开的一瞬间即使抖动,由于LED***作了一次,这段抖动也可以被开头的消抖操作给自动过滤掉,没问题啊? 那么我们再看一下这个 (没想到吧) 这种现象我估计在按键使用过久老化之后才会出现的多(你啪啦啪啦瞎乱按一通也可能会出现),不对这个进行处理的话,产品使用久了,按键抖动的厉害,可能就会导致操作失误。 解决办法倒也简单,检测到按键松开时再进行抖动检测就好,跟上面按下时检测抖动的步骤基本一样。 |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 08:09 , Processed in 0.864927 second(s), Total 48, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号