洋桃电子STM32F407单片机入门教程笔记五:外部中断功能

 此文档作为对洋桃电子STM32F407单片机视频的整理,B站链接:第19集)外部中断功能_哔哩哔哩_bilibili

1. 外部中断功能介绍

        GPIO端口可用于逻辑电平的输入和输出,作为输入功能时可通过程序来读取GPIO端口状态,经典应用是按键读取程序,GPIO端口读取按键状态看似是一个理想的解决方案,但在实际项目开发中会遇见很多问题,比如在主循环程序里有很多工作任务,每个任务都会占用一段处理时间导致循环读取按键的时间变长 按键反应慢。

        在实时性要求很高的场合要把按键变成外部中断处理,按下按键马上中止当前工作跳转到按键处理程序,外部中断功能不再需要程序代码循环读取电平状态,开启外部中断功能后,当端口电平按照预先设置的方式变化就会产生外部中断。使单片机进入中断处理程序。

        中断触发电平变化有上升沿 下降沿和高低电平三种,触发方式有中断触发和事件触发两种。首先要将GPIO端口设置为逻辑电平输入,可输入高电平和低电平。

        第一种是下降沿触发,是指由高电平变成低电平的变化过程。形成一条向下变化的边沿线,只要外部中断功能检测到这一条下降的边沿线就会触发中断。

        第二种上升沿触发,是由低电平向高电平变化时的边沿线。

        第三种高低电平触发是无方向的边沿触发,电平由高变低或由低变高都会触发中断。

        从按键中断的角度来看,在按键未按下时端口应处于高电平,当按键按下时端口由高电平变成低电平产生下降沿,所以可用下降沿中断方式。

1.1 GPIO端口与中断通道的关系

        外部电平从右下角的GPIO端口的“输入线”输入到单片机内部中断处理电路,输入电路首先通过“边沿检测电路”判断是否有上升沿和下降沿出现,具体判断是上升、下降还是高低电平触发由“上升沿触发选择寄存器”和“下降沿触发选择寄存器”来决定。当设置开启“上升沿触发选择奇存器”则“边沿检测电路”只有检测到上升沿才触发,当设置开启“下降沿触发选择奇存器”则“边沿检测电路”只有检测到下降沿才触发,当设置同时开启“上升沿触发选择奇存器”和“下降沿触发选择寄存器”则“边沿检测电路”是无方向的高低电平变化触发。触发信号再经过一系列处理,最后送入NVIC中断控制器实现中断的触发。

        从下图中可以看出,外部中断功能共有23个中断通道,当产生外部中断后我们可以通过中断标志位判断出触发来自哪里,图中可以看出PAO~PIO端口共用一个中断标志位EXTIO,也就是说如果中断来自PAO PBO PCO PDO PEO PFO PGO端口,中断标志位将触发为EXTIO,PA1~PG1端口触发中断标志位将变成EXTI1,以此类推,各组端口标号对应着不同的中断标志位,除了EXT10~15的外部中断输入还有7个特殊中断事件标志位。

        当出现PVD电源检测事件 (电源电压突然降低)会产生EXTI16中断。EXTI17中断是RTC闹钟事件,EXTI18中断是USB唤醒事件。

1.2 各端口产生中断后进入对应的中断处理函数

        EXTIO~EXTI4对应着各自独立的中断处理函数,但需要注意其中的EXTI5~EXTI9标志位共用一个中断处理函数EXTI9_5_IRQHandler,EXTI10~EXTI15共用一个中断处理函数EXTI15 10 IRQHandler。

        假如产生了EXTIO中断,怎么知道触发来源是PAO还是PBO呢?如果只设置PA0为外部中断引脚,PBO设置为普通GPIO端口,那一定是PAO产生中断。如果二者都设置为外部中断输入端口可以在中断处理程序中重新读取电平状态 便可区分。

2. CuebMX设置

        在单片机端口视图中设置PF12端口。

         在CubeMX中设置PA0的参数。

        端口触发模式的六个选项。

        端口上下拉模式的三个选项。

        设置EXTI0中断允许。

        进入NVIC设置窗口,在NVIC选项卡里有所有中断列表,在其中可以找到PVD中断、RTC闹钟中断和USB中断的内部中断源选项,需要时勾选相应的中断允许即可。

         还可以单击“生成代码”选项卡,在列表中设置EXTI line[15:10] interrupts的代码生成,初始化函数排序等内容。

3. 编写应用程序

        全部设置完成后重新生成代码,发现在主函数中并没有出现外部中断的初始化函数。这是因为外部中断隶属于GPIO功能,所以外部中断的初始化是在GPIO初始化函数内完成的。

        在代码编辑区先找到外部中断处理函数和回调函数,然后编写一段用外部中断实现的按键处理程序。

        首先在工程文件树中打开stm32f4xx_it.c文件,这里保存了与中断有关的自动生成的函数。当产生中断事件程序会跳转到中断处理函数(233行),但中断处理函数里只简单标注了中断来源,然后退出中断回到主函数。回到主函数后并不是继续执行之前中止的程序,而是自动调用中断回调函数,中断事件的处理都放在调函数里。由于程序已经退出中断状态,回归主函数所以其他中断不会受阻,这就是回调函数的作用和意义。

        文件第233行有EXTI15_10的中断处理函数,在函数内部只调用了第238行的HAL库函数,进行真正的中断处理工作。可以在stm32f4xx_hal_gpio.c文件的第492行找到这个函数。函数内容是清除中断标志位并调用中断回调函数,第507行(下图)是中断回调的弱函数,中断回调函数的弱函数带有“__weak”前缀,也叫修饰符。

        __weak前缀的作用是定义弱函数,弱函数相当于后补球员,如果正式球员在场侯补球员不能上场,如果正式球员缺席,侯补球员补位保证比赛正常进行。

        当main.c文件的第60行定义了同名的中断回调正式函数(不带 weak前缀), 弱函数不会被编译,假如删除了main.c文件里的中断回调正式函数。将会编译中断回调的弱函数。如果程序中没有弱函数当侯补,删除正式函数会导致编译器找不到中断回调函数而报错。在HAL库中有很多这样的弱函数,我们只要在自己的程序代码中创建一个同名的中断回调函数,就可以在其中添加对按键的操作程序。

      为了设计简单,将中断回调函数创建在main.c文件里,在main.c文件第60 ~ 68行插入中断回调函数,此函数有一个参数,参数内容是在中断时自动存入触发中断的端口号,进入函数后的第61行判断触发端口号是不是KEY1按键(PF12端口),如果是则执行第63行的调用按键处理函数。为了防止在执行按键处理程序的过程中再次触发中断,需要在第62行添加禁止中断触发的HAL库函数。当按键处理完成后再在第66行添加允许中断的HAL库函数。如果不添加这两行程序,会出现按下按键时反复缺发中断使LED反复跳变的问题。所有按键处理程序都在中断回调函数中完成了,在while()主循环中没有添加任何代码。这说明按键处理工作完全是在中断函数中完成的,可以在主循环部分写入其他程序代码,即使ARM内核一直被占用也能保证按键的实时响应。另外还有一处需要说明,HAL_Delay()函数只能被主函数和子函数调用,不能在任何中断函数中调用。

  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32F407外部中断是指通过将外部信号连接到STM32F407的IO口来触发中断事件。STM32F407的每个IO口都可以作为外部中断输入。中断控制器支持22个外部中断/事件请求。其中, EXTI线0到15对应外部IO口的输入中断, EXTI线16连接到PVD输出, EXTI线17连接到RTC闹钟事件, EXTI线18连接到USB OTG FS唤醒事件, EXTI线19连接到以太网唤醒事件, EXTI线20连接到USB OTG HS唤醒事件,在FS中配置, EXTI线21连接到RTC入侵和时间戳事件, EXTI线22连接到RTC唤醒事件。 需要注意的是,每个中断线可以映射多个IO口,但是同组IO口中一次只能有一个IO口占用中断线。例如,(PA0-PG0)是一组可以映射到中断线EXTI0的IO口,但是一次只能有其中的一个IO口映射上去。 总结来说,STM32F407外部中断是通过将外部信号连接到IO口来触发中断事件的机制,中断控制器支持22个外部中断/事件请求,每个中断事件都有独立的触发和屏蔽设置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [stm32f407外部中断](https://blog.csdn.net/MLW20010726/article/details/123269643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [STM32 IO中断(F407)(个人学习)](https://blog.csdn.net/qq_45494003/article/details/104446251)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值