第一次写博客,有错误与问题欢迎指正。
1、轮询的消抖方式
这部分直接上代码,假设PB5为输入端且上拉,PB11为输出。
while(1)
{
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_RESET)//判断按键按下
{
HAL_Delay(20);//延时消抖
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_RESET)//按键仍然按下
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_11);//执行程序
while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_RESET);//松手检测
}
}
}
2、改为外部中断时遇到的问题
在CubeMx中配置完引脚(下降沿触发)并在NVIC中开启外部中断后,我们注意到,上一个程序有5个要素(我写了注释的5个):
(1)首次判断按键按下
中断回调函数HAL_GPIO_EXTI_Callback是一个虚函数,我们可以重写它,并将其作为中断触发的判断。
(2)延时
由于按键抖动大约10ms,延时一段时间之后就可以有效规避这段不稳定时期。
但此时我们不可以使用HAL_Delay()函数延时,因为该函数使用的时钟为SysTick,我们要保证SysTick的优先级比外部中断高,才能使单片机停止外部中断去执行HAL_Delay(),即中断嵌套。
在CubeMx - System Core - NVIC - Preemption(抢占优先级)可以如下配置:
这样我们就可以在中断中使用HAL_Delay了,也可以自己写一个从1加到1000延时函数。
(3)判断按键仍然按下
这部分和后面的执行程序以及松手检测,基本上和轮询的代码没什么变化。
注意这里用HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_RESET作为判断依据而不是GPIO_Pin == GPIO_PIN_5。文章来源:https://www.toymoban.com/news/detail-846907.html
3、修改后的程序
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_5)
{
HAL_Delay(20);
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_RESET)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_11);
while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_RESET);
}
}
}
/* USER CODE END 0 */
事实上,外部中断并不是按键开发最好的方式,因为中断讲究快,不然如果中断程序运行时一直占用大量时间,主程序就无法正常运行,但按键又要求延时与松手检测,因此,我们可以通过轮询或定时器中断检测等方式来制作按键。文章来源地址https://www.toymoban.com/news/detail-846907.html
到了这里,关于STM32:基于HAL 库的外部中断按键以及消抖的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!