一、中断函数里不能使用延时Delay()函数的解决办法
前言,在使用按键中断时,为了消除按键抖动,想在中断函数里使用延迟函数以消除按键抖动,但是直接在中断函数中使用延时函数,会导致直接就进不了按键中断。
如图,默认的系统滴答计时器的抢占优先级是比中断线的优先级低的
要想在按键中断中使用延时函数,就需要将系统滴答计时器的优先级设置的比按键中断高,所以做如下设置,重新生成代码即可解决。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
static int work_status = 0;
if(GPIO_Pin == GPIO_EXTI15_Pin)//判断是否是对应的中断号
{
HAL_Delay(200);
if(HAL_GPIO_ReadPin(GPIOI, GPIO_EXTI15_Pin) == GPIO_PIN_RESET)
{
work_status += 1;
if(work_status > 2)work_status = 0;
}
switch(work_status)
{
case 0:
LED_R_ON;
LED_G_OFF;
LED_B_OFF;
break;
case 1:
LED_R_OFF;
LED_G_ON;
LED_B_OFF;
break;
case 2:
LED_R_OFF;
LED_G_OFF;
LED_B_ON;
break;
default:
break;
}
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_EXTI15_Pin);
}
}
二、关于回调函数HAL_GPIO_EXTI_Callback()(中断函数具体要响应的动作)
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
/**
* @brief EXTI line detection callbacks.
* @param GPIO_Pin Specifies the pins connected EXTI line
* @retval None
*/
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_GPIO_EXTI_Callback could be implemented in the user file
这个函数不应该被改变,如果需要使用回调函数,请重新在用户文件中实现该函数。
*/
}
HAL_GPIO_EXTI_Callback() 按照官方提示我们应该再次定义该函数,__weak 是一个弱化标识,带有这个的函数就是一个弱化函数,就是你可以在其他地方写一个名称和参数都一模一样的函数,编译器就会忽略这一个函数,而去执行你写的那个函数;而 UNUSED(GPIO_Pin) ,这就是一个防报错的定义,当传进来的GPIO端口号没有做任何处理的时候,编译器也不会报出警告。其实我们在开发的时候已经不需要去理会中断服务函数了,只需要找到这个中断回调函数并将其重写即可而这个回调函数还有一点非常便利的地方这里没有体现出来,就是当同时有多个中断使能的时候,STM32CubeMX会自动地将几个中断的服务函数规整到一起并调用一个回调函数,也就是无论几个中断,我们只需要重写一个回调函数并判断传进来的端口号即可。具体实践???
/**
* @brief This function handles EXTI line[15:10] interrupts.
*/
void EXTI15_10_IRQHandler(void)
{
/* USER CODE BEGIN EXTI15_10_IRQn 0 */
/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_EXTI13_Pin);
HAL_GPIO_EXTI_IRQHandler(GPIO_EXTI14_Pin);
HAL_GPIO_EXTI_IRQHandler(GPIO_EXTI15_Pin);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */
/* USER CODE END EXTI15_10_IRQn 1 */
}
具体代码入问题一里所示。