STM32编程时,如何确定中断回调函数的入口

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文件
STM32编程时,如何确定中断回调函数的入口_第1张图片
首先需要编译一下,接下来找到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);

你可能感兴趣的:(嵌入式开发,stm32,单片机,嵌入式,arm)