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

【经验分享】STM32CubeMX教程-GPIO输入之外部中断

[复制链接]
STMCU小助手 发布时间:2022-6-26 14:04
    本篇主要讲述GPIO外部中断输入检测,实际物理输入方式是按键,但是实际上更适合外部设备信号的输入检测,物理按键输入因为有抖动,还需要硬件或者软件去抖才比较可靠。这个例子不考虑防抖的情况。
软件版本:
STM32CubeMX V4.25.0  
System Workbench V2.4
硬件:OneNet 麒麟座V2.3
    在STM32CubeMX中新建项目,选择正确的MCU型号

P3(JN_GJJ{EAO_QWJ71@6QD.png

    设置RCC和SYS,然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M)

RNKZ)M(_OU8}{69@22(N}6L.png

    根据板子的具体连接设置4个GPIO_OUTPUT (连接到LED)和4个GPIO_EXIT*(外部中断模式,连接到物理按键)。
SHZX%))XIBBR8WZL0}[)G]A.png

    GPIO OUTPUT引脚设置

867WS$DX8`YK)@IR`YNS.png

    麒麟座按键有外部上拉,所以GPIO_EXIT*不需要配置内部上拉,检测下降沿(Falling Edge),GPIO_EXIT*设置如下

9M5YZ$CD02I44WJYP9VO404.png

    LED名称标号我用了1/2/3/4,SW名称标号我用了2/3/4/5,实例中标号也未必相同,但是要做好一一对应关系。
    在NVIC(嵌套向量中断控制器)中,勾选EXIT Line2 interrupt 和 EXIT Line[15:12] interrupt 使能中断。右边两个选项设置抢占优先级和响应优先级。此处我们选择默认的,不修改。
{OV8`3U_BK65%E~V~5KL0)G.png

    同样修改Project - setting ,ToolChain/IDE选择 SW4STM32
微信图片_20220626140135.png

    勾选这里。
NF~XL]W(CZA)S%$OYWXYI0S.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。

B%P@V9W8U3M94COZI6E01ZJ.png

    然后任务栏上点击Run图,当然会报错的,原因请查看另一篇我的博客,所以需要右键点击  项目名Run.cfg ,给它改个名字,

I3CK6X3D]CWV~87E7LXL{[1.png

    然后右键点击项目树里面的项目名称,选择“Propeties”,然后在Run/Debug Settings-选择项目名-Edit-Main-C/C++Application那里点击“Search Project”,然后选择出现的默认的elf文件:

微信图片_20220626140034.png

    然后在Debugger-User Defined-Browse 那里选择你自己改名的配置文件:

微信图片_20220626140031.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导致损坏。

收藏 评论0 发布时间:2022-6-26 14:04

举报

0个回答

所属标签

相似分享

官网相关资源

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