[STM32F7] 关于Callback的疑问

[复制链接]
3013|9
 楼主| 734774645 发表于 2016-11-17 22:07 | 显示全部楼层 |阅读模式
下面是F7的一个例程中的一段
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  Blinks LED2 with two frequencies depending on User press button.
  3.   * @param  None
  4.   * @retval None
  5.   */
  6. static void LED2_Blink(void)
  7. {
  8.   /* Configure LED2 on Nucleo */
  9.   BSP_LED_Init(LED2);

  10.   /* Configure the User Button in EXTI Mode */
  11.   BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
  12.   
  13.   /* Initiate BlinkSpeed variable */
  14.   BlinkSpeed = 0;  
  15.   
  16.   /* Infinite loop */
  17.   while(1)
  18.   {
  19.     /* Test on blink speed */
  20.     if(BlinkSpeed == 0)
  21.     {
  22.       BSP_LED_Toggle(LED2);
  23.       /* Wait for 500ms */      
  24.       HAL_Delay(500);      
  25.     }      
  26.     else if(BlinkSpeed == 1)
  27.     {
  28.       BSP_LED_Toggle(LED2);
  29.       /* Wait for 100ms */
  30.       HAL_Delay(100);
  31.     }
  32.     else if(BlinkSpeed == 2)
  33.     {
  34.       BSP_LED_Toggle(LED2);   
  35.       /* Wait for 50ms */
  36.       HAL_Delay(50);  
  37.     }
  38.   }
  39. }

  40. /**
  41.   * @brief  EXTI line detection callbacks.
  42.   * @param  GPIO_Pin: Specifies the pins connected EXTI line
  43.   * @retval None
  44.   */
  45. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  46. {
  47.   if(BlinkSpeed == 2)
  48.   {
  49.     BlinkSpeed = 0;
  50.   }
  51.   else
  52.   {
  53.     BlinkSpeed ++;
  54.   }
  55. }


 楼主| 734774645 发表于 2016-11-17 22:14 | 显示全部楼层
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
上面这句与后面的回调是因果关系吗?
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
——————————————————————————————————————————
经过查询这个GPIO外部中断回调函数在stm32f7xx_hal_gpio.h中定义的
那么是不是这种使用方法是规定好的套路呢?通过定位发现配置跟中断有关的函数实际上是
   /* Enable and set Button EXTI Interrupt to the lowest priority */
    HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0x00);
    HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
这俩构成的,一个设置优先级,一个使能,那么是不是这个是固定好的套路呢?

 楼主| 734774645 发表于 2016-11-17 22:15 | 显示全部楼层
求高手解读这个Callback的使用套路具体是什么
 楼主| 734774645 发表于 2016-11-17 22:43 | 显示全部楼层
  1. /**
  2.   * @brief  This function handles EXTI interrupt request.
  3.   * @param  GPIO_Pin: Specifies the pins connected EXTI line
  4.   * @retval None
  5.   */
  6. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
  7. {
  8.   /* EXTI line interrupt detected */
  9.   if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  10.   {
  11.     __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
  12.     HAL_GPIO_EXTI_Callback(GPIO_Pin);
  13.   }
  14. }
在hal_gpio.h中有上面一段,跟之前学到的类似,就是在中断里面回调那个函数,就是你要在中断发生后干甚。
这就好比之前的单片机开发一样,中断发生后除了清理中断标志外就是要干你想干的事情了。。这里是不是回调就是封装了这个你想干的事情。
 楼主| 734774645 发表于 2016-11-17 22:47 | 显示全部楼层
而在开发板的配置文件里
有下面的代码
  1. /**
  2.   * @brief  Configures Button GPIO and EXTI Line.
  3.   * @param  Button: Specifies the Button to be configured.
  4.   *   This parameter should be: BUTTON_USER
  5.   * @param  ButtonMode: Specifies Button mode.
  6.   *   This parameter can be one of following parameters:   
  7.   *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO
  8.   *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
  9.   *                            generation capability  
  10.   * @retval None
  11.   */
  12. void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
  13. {
  14.   GPIO_InitTypeDef GPIO_InitStruct;
  15.   
  16.   /* Enable the BUTTON Clock */
  17.   BUTTONx_GPIO_CLK_ENABLE(Button);
  18.   
  19.   if(ButtonMode == BUTTON_MODE_GPIO)
  20.   {
  21.     /* Configure Button pin as input */
  22.     GPIO_InitStruct.Pin = BUTTON_PIN[Button];
  23.     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  24.     GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  25.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  26.     HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
  27.   }
  28.   
  29.   if(ButtonMode == BUTTON_MODE_EXTI)
  30.   {
  31.     /* Configure Button pin as input with External interrupt */
  32.     GPIO_InitStruct.Pin = BUTTON_PIN[Button];
  33.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  34.     GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  35.     HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
  36.    
  37.     /* Enable and set Button EXTI Interrupt to the lowest priority */
  38.     HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0x00);
  39.     HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
  40.   }
  41. }
我们可以根据主函数传递进来的内容知道,传递进来的是按键的位置以及按键的配置功能为中断类

Ketose 发表于 2016-11-17 22:48 | 显示全部楼层
1、在GPIO初始化的时候配置GPIO的外部中断,
2、现次设置中断优先级开启中断
中断是在中断向量表是已经确定了的,也就是说不管你开不开中断,中断函数都已经写好了的。
中断触发后在HAL里调用顺序是这样子的:
EXTI15_10_IRQHandler --> HAL_GPIO_EXTI_IRQHandler --> HAL_GPIO_EXTI_Callback

HAL_GPIO_EXTI_Callback 是用__aweak修饰的,也就是说用户重写了这个函数,就用用户写的,如果不写就是内置的。
 楼主| 734774645 发表于 2016-11-17 22:50 | 显示全部楼层
我们可以看到是执行了下面那个if,我们可以看到初始化端口的结构体变量内容是不同的。看清楚了。这些个实际上是可以照抄的东西。普通的配置完就完了,但是中断的后面有两句,设置中断的优先级我们看到三个参数中,第一个就是传递之前进来的按键的位置。另外一行是使能外部中断,同样参数就是外部的中断引脚位置。
 楼主| 734774645 发表于 2016-11-17 22:55 | 显示全部楼层
那么启动了中断功能后,是不是工程自动就包含了对应的中断处理函数进来了呢?
我没在main函数中看到这个内容,而是在hal_gpio.c里面有这个函数
内容就是之前说过的,清理中断,调用回调函数。
 楼主| 734774645 发表于 2016-11-17 22:56 | 显示全部楼层
Ketose 发表于 2016-11-17 22:48
1、在GPIO初始化的时候配置GPIO的外部中断,
2、现次设置中断优先级开启中断
中断是在中断向量表是已经确定 ...

也就是说,跟我后面理解的差不多一样了,就是中断触发后,就自动的把中断处理函数包含进来了。中断函数除了简单的处理完套路中的清理中断标志外就是调用回调函数。回调函数才是我们中断函数内要做的事情,对吧
gaoyang9992006 发表于 2016-11-18 09:33 | 显示全部楼层
楼主理解的很对,就是这样,那都是ST官方库函数结构里的套路,都写好了,你只需要完成你要实现的部分就行。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

211

主题

3588

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部