你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CubeMX教程-GPIO输入之外部中断

[复制链接]
STMCU 发布时间:2020-10-14 15:06
STM32CubeMX教程-GPIO输入之外部中断


本篇主要讲述GPIO外部中断输入检测,实际物理输入方式是按键,但是实际上更适合外部设备信号的输入检测,物理按键输入因为有抖动,还需要硬件或者软件去抖才比较可靠。这个例子不考虑防抖的情况。
软件版本:
STM32CubeMX V4.25.0  
System Workbench V2.4

硬件:OneNet 麒麟座V2.3
    在STM32CubeMX中新建项目,选择正确的MCU型号
11.png     设置RCC和SYS,然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M) 12.png 13.png     根据板子的具体连接设置4个GPIO_OUTPUT (连接到LED)和4个GPIO_EXIT*(外部中断模式,连接到物理按键)。
14.png
    GPIO OUTPUT引脚设置
15.png
    麒麟座按键有外部上拉,所以GPIO_EXIT*不需要配置内部上拉,检测下降沿(Falling Edge),GPIO_EXIT*设置如下
16.png
    LED名称标号我用了1/2/3/4,SW名称标号我用了2/3/4/5,实例中标号也未必相同,但是要做好一一对应关系。
    在NVIC(嵌套向量中断控制器)中,勾选EXIT Line2 interrupt 和 EXIT Line[15:12] interrupt 使能中断。右边两个选项设置抢占优先级和响应优先级。此处我们选择默认的,不修改。
17.png
    同样修改Project - setting ,ToolChain/IDE选择 SW4STM32
18.png
    勾选这里。
19.png
    生成代码后点击Open Project在Eclipse中打开项目,然后在 在stm32f7xx_it.c中断服务函数文件中,我们可以找到EXTI2 和EXTI15_10中断的服务函数。



  1. /******************************************************************************/
  2. /* STM32F1xx Peripheral Interrupt Handlers                                    */
  3. /* Add here the Interrupt Handlers for the used peripherals.                  */
  4. /* For the available peripheral interrupt handler names,                      */
  5. /* please refer to the startup file (startup_stm32f1xx.s).                    */
  6. /******************************************************************************/
  7. /**
  8. * @brief This function handles EXTI line2 interrupt.
  9. */
  10. void EXTI2_IRQHandler(void)
  11. {
  12. /* USER CODE BEGIN EXTI2_IRQn 0 */
  13. /* USER CODE END EXTI2_IRQn 0 */
  14. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
  15. /* USER CODE BEGIN EXTI2_IRQn 1 */
  16. /* USER CODE END EXTI2_IRQn 1 */
  17. }
  18. /**
  19. * @brief This function handles EXTI line[15:10] interrupts.
  20. */
  21. void EXTI15_10_IRQHandler(void)
  22. {
  23. /* USER CODE BEGIN EXTI15_10_IRQn 0 */
  24. /* USER CODE END EXTI15_10_IRQn 0 */
  25. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
  26. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
  27. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  28. /* USER CODE BEGIN EXTI15_10_IRQn 1 */
  29. /* USER CODE END EXTI15_10_IRQn 1 */
  30. }
复制代码


右键点击HAL_GPIO_EXTI_IRQHandler 选择"Open Declaration"会跳转到如下代码:



  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. }
  15. /**
  16.   * @brief  EXTI line detection callbacks.
  17.   * @param  GPIO_Pin: Specifies the pins connected EXTI line
  18.   * @retval None
  19.   */
  20. __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  21. {
  22. /* Prevent unused argument(s) compilation warning */
  23. UNUSED(GPIO_Pin);
  24. /* NOTE: This function Should not be modified, when the callback is needed,
  25.            the HAL_GPIO_EXTI_Callback could be implemented in the user file
  26.    */
  27. }
复制代码


上述代码中可以看到GPIO外部中断处理函数首先清除中断标识位,然后调用中断回调函数HAL_GPIO_EXTI_Callback()。往下看这个回调函数定义的时候使用了__weak修饰符(关于__weak修饰符, 可以参看此博文),里面没有任何有作用的代码,我们需要重新定义这个函数。编辑gpio.c(或者main.c也可以),进行如下修改:



  1. /* USER CODE BEGIN 2 */
  2. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  3. {
  4.   if(GPIO_Pin == SW2_Pin)
  5.   {
  6.   HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
  7.   }
  8.   if(GPIO_Pin == SW3_Pin)
  9.   {
  10.   HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
  11.   }
  12.   if(GPIO_Pin == SW4_Pin)
  13.   {
  14.   HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);
  15.   }
  16.   if(GPIO_Pin == SW5_Pin)
  17.   {
  18.   HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin);
  19.   }
  20. }
  21. /* USER CODE END 2 */
复制代码


然后右键点击项目,选择Properties, Run-Debug Settings, 点击右侧的New,在弹出对话框中选择Ac6 STM32 Debugging。
20.png
然后任务栏上点击Run图,当然会报错的,原因请查看另一篇我的博客,所以需要右键点击  项目名Run.cfg ,给它改个名字,
21.png

    然后右键点击项目树里面的项目名称,选择“Propeties”,然后在Run/Debug Settings-选择项目名-Edit-Main-C/C++Application那里点击“Search Project”,然后选择出现的默认的elf文件:
22.png
    然后在Debugger-User Defined-Browse 那里选择你自己改名的配置文件:
23.png
    然后右键点击那个新的cfg文件,选择"Open With - Text Editor", 进行如下更改:

  1. source [find interface/stlink.cfg]
  2. //更改为 source [find interface/stlink-v2.cfg]

  3. reset_config srst_only srst_nogate connect_assert_srst
  4. //这一行改为 reset_config none
复制代码


Run一下,就可以了。然后再Run一下,就实现四个按键分别控制LED的开关切换了。但是这里没有防抖处理,你会发现有时候LED会闪一下,或者没反应,其实是很快地点亮然后熄灭一次或者若干次,只是由于速度太快电流很小导致你看不到。下一篇我们会通过使用SysTick中断来实现按键去抖扫描。在实际项目中,最好加上硬件防抖,因为抖动产生的反向电压可能会冲击GPIO导致损坏。











收藏 1 评论0 发布时间:2020-10-14 15:06

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版