STM32编程时,如何确定中断回调函数的函数名
换句话说,就是如何找到中断回调函数的函数名
程序进中断时,都会调用中断回调函数,很多初学者朋友在用STM32编程时,经常不知道这个回调函数的函数名。
其实这个问题有2个通用的解法。
EXTI外部中断,方法1:中断内打断点,跟踪运行,找到回调函数
本方法适用中断过程简单的中断,如果比较长的话,当然也可以,不过建议用后面的方法
以多线共用中断为例,本例是4~15共用中断,其中使用了4个中断,中断代码如下:
void EXTI4_15_IRQHandler(void)
{
/* USER CODE BEGIN EXTI4_15_IRQn 0 */
/* USER CODE END EXTI4_15_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(RAIN_IN_Pin);
HAL_GPIO_EXTI_IRQHandler(HALL_1S_Pin);
HAL_GPIO_EXTI_IRQHandler(HALL_1E_Pin);
HAL_GPIO_EXTI_IRQHandler(HALL_2S_Pin);
HAL_GPIO_EXTI_IRQHandler(HALL_2E_Pin);
/* USER CODE BEGIN EXTI4_15_IRQn 1 */
/* USER CODE END EXTI4_15_IRQn 1 */
}
到底是哪一个引脚触发引起的中断呢,打断点分别进入这几个HAL_GPIO_EXTI_IRQHandler函数就行了。
进去以后是下面这样的:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if (__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);
HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin);
}
if (__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin);
HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);
}
}
这就很简单了,第1个if是上升沿中断,第2个if下降沿中断,里面含有Callback的语句就是中断回调函数。然后自己重写这函数就可以了,如下:
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_12) //EXTI12
{
}
if(GPIO_Pin == GPIO_PIN_13) //EXTI13
{
}
}
ADC等函数简单的中断,方法2 :在定义中断函数结束以后,一般都接着定义该中断的回调函数
下面以ADC1为例,来查找它的中断回调函数。首先打开CubeMX生成的代码,找到所有中断函数入口的C文件
首先需要编译一下,接下来找到ADC1对应的中断入口,它是和ADC2共用一个入口函数,函数前一行有说明
/**
* @brief This function handles ADC1 and ADC2 global interrupts.
*/
void ADC1_2_IRQHandler(void)
{
/* USER CODE BEGIN ADC1_2_IRQn 0 */
/* USER CODE END ADC1_2_IRQn 0 */
HAL_ADC_IRQHandler(&hadc1); //查看这个函数
/* USER CODE BEGIN ADC1_2_IRQn 1 */
/* USER CODE END ADC1_2_IRQn 1 */
}
选中HAL_ADC_IRQHandler这个函数,按F12具体查看这个函数。
往下翻,直到这个函数结束,再往后,就是这个函数所包含的所有回调函数,以__weak打头,比如ADC就包含了以下这几个回调函数和它们的描述。篇幅所限,此处没有列出描述。
__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
看描述选中你需要的,
以ADC来说,一般是用这一个:HAL_ADC_ConvCpltCallback
重写需要的回调函数,在里面实现你所需要的功能。建议是新建.c和.h文件,然后这样后续代码复会比较方便。当然前面的 __weak 描述符要去掉。
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc.Instance == ADC1)
{
//在这里写代码,实现需要的功能
}
}
在自己重写的这个函数中,还需要做一下判断,以区分ADC1还是ADC2
最后将.h和.c文件加入到工程中即可。
定时器等函数特别多的中断,方法3:搜索Callback
以TIM3为例,中断入口是这样的:
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
选中 HAL_TIM_IRQHandler ,按F12键,进入函数定义,搜索Callback(,意思是寻找回调函数,一定要加上括号哦。
接下来找到的就都是回调函数了 ,注意看找到的函数名称,它代表了具体的相关功能,找到你要的那个功能,然后按上面的方法去重写这个弱函数即可。如下:
HAL_TIM_IC_CaptureCallback(htim);
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
HAL_TIM_PeriodElapsedCallback(htim);
HAL_TIMEx_BreakCallback(htim);
HAL_TIM_TriggerCallback(htim);
HAL_TIMEx_CommutCallback(htim);