
简介 本次主要讲解STM32的外部中断以及使用STM32CubeMX编写中断程序,实现按键按下点亮LED灯。 ) U: l3 Q' d& e; q) @( q( \# L STM32的中断介绍 中断是什么) q/ e7 L. w# v" N- [6 A 我们可以暂时认为单片机的执行流程是单向的,这件事做完做下一件事。而中断顾名思义,就是当单片机接收到一个信号后,停下手上的程序,转而去执行中断函数里面的程序,执行完再返回原来程序的位置,继续执行未完成的原程序。(就比如你在打单机,结果舍友说等下要上课,你接收到了这个信息,然后只能把游戏存档,先去上课,上完课再继续读档)+ C! a) [ @) ~% K' [2 m STM32的中断系统 几个概念:中断源,中断通道,中断优先级,NVIC(嵌套向量中断控制器),中断服务程序。, P! f. g; h& \5 t8 ] 中断源: 所谓中断源,就是触发中断的方式。即引起中断的事件或原因,或发出中断申请的来源。分内部和外部中断源。2 ?: g1 R: I# R) y V, U/ q 中断通道 STM32的中断系统比51单片机强大的多。8051只有两个外部中断的IO口,而STM32的每一个GPIO都能作为外部中断输入。 STM32的中断控制器支持19个外部中断/事件请求: ( \' ] x1 T8 n 线0~15:对应外部IO口的输入中断。! {2 ~, W8 U7 {. K! ]/ G ~) y 线16:连接到PVD输出。 线17:连接到RTC闹钟事件。 线18:连接到USB唤醒事件。 每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。 & n& g; p3 v7 j1 `, A 从上面可以看出,STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112), STM32F103RCT6(51),那么中断线怎么跟io口对应?7 a7 E7 d* z) O1 O# z( ` ![]() 0 c1 v( V- |- Z* H5 G q) [( K 从图上可以看到每组IO的0引脚都对应EXTI0,1引脚对应EXTI1。。。。。以此类推 / ^5 _( j3 @0 b" x L& m 中断优先级 当出现多个中断的时候,单片机要先执行哪个中断呢?% h6 W+ c8 _' ^: Z 为了解决这个问题,单片机设计了中断优先级来安排每个中断的执行先后顺序,也因此产生了中断嵌套。+ W' ?4 ]3 `, w! }/ j; I 32有两个优先级,占先优先级和副优先级。规则如下:: L& w5 R0 _. I0 e. T 1.高占先优先级的中断可以打断低占先优先级的中断服务,从而构成中断嵌套。相同占先优先级的中断之间不能构成中断嵌套,只能按先来后到执行。( e E' V. j6 D; k ? 2.副优先级不能中断嵌套,但在占先优先级相同的情况下,优先响应副优先级高的中断。4 h8 Y$ [' a3 s. M) B / u" P0 S8 o1 J8 T' T0 |* ` NVIC(嵌套向量中断控制器). E9 M) [$ {5 J# p NVIC的作用就是优先级分组(说人话就是,分配有几个占先优先级有几个副优先级)6 v% G) g" p" @6 V+ t+ I- ?4 K ![]() STM32以4个比特位表示中断的抢占优先级和响应优先级。中断优先级分组是为了给抢占式优先级和响应优先级在中断优先级寄丛器的四个比特位分配各个优先级数字所占的位数。例如3位用于抢占优先级(优先级有2的三次方等于8种级),1位用于响应优先级(优先级有2的一次方等于2种优先级)。& q5 ?& ~- p# }+ u9 ^ 中断服务程序 就是一个函数,里面写你要执行的程序。 使用STM32CubeMx编写中断程序的步骤 我们打开上一篇教程的工程,在此基础上增加PA9这个外部中断口。2 x) _- D# k" w. u- U' L+ { 如图选择IO模式 ' F6 D6 ]! G: u: Y) k ![]() 打开NVIC,勾选EXTI line优先级使能+ h2 t; i+ s& i2 ~6 [8 y ) T) S# h, q- k ![]() 打开GPIO中的NVIC,发现已经配置好了 3 }, h3 }/ T$ p, ] h3 C* j2 {' g ![]() % X( o1 _4 w* m f 接下来配置GPIO的模式,选择下降沿触发,依然是推挽输出% i j" j7 c2 ^' k* A* H7 e/ _ 9 D* ]: G# |0 E4 ] ![]() $ x, X% [$ a: `$ D; z! L 然后生成工程(时钟树之前配置过了) 我们打开工程可以看到在gpio.c文件里面看到,软件已经自动帮我们把IO口配置好了' H' I7 K" \" S. b% J 0 D7 p6 [* M2 D ![]() # O8 E' ^: C& C) y1 g$ Z+ t# ] stm32f1xx_it.c文件里面的EXTI9_5_IRQHandler函数是PA9的中断服务函数。) c! {6 A9 Y" y) J ![]() / W& v0 }- p0 T* @ c% A5 ]# m 我们查看HAL_GPIO_EXTI_IRQHandler的定义6 O3 J) R: X' Y! R. N , H& a( u, @1 P ![]() ![]() : E. x$ e' p% e! J1 d/ Q 从他的程序中我们不难看出HAL_GPIO_EXTI_IRQHandler这个函数是用来清除中断标志位的5 U$ T# w4 I3 f4 g7 N J- ^ 在清除之后,还调用了 HAL_GPIO_EXTI_Callback这个函数。 ![]() 我们右键跳转到它的定义我们发现,这是一个中断回调函数,而且这个函数里面什么都没有。通过注释的提示我们知道,我们不要在这里就进行修改,而是要在用户文件中重构这个函数。5 [. ~$ Y$ H; I' q' a+ y 而且有个问题,为什么这个函数前面有一个__weak? (关于__weak修饰符可以看这里链接博文讲的很详细) 于是我们重新回到main函数,编写了 HAL_GPIO_EXTI_Callback,简单给按键写一下消抖。: g+ l b2 Y) m8 c' { ![]() 6 Y) M/ V7 Z) W# {! U, q 记得把HAL_GPIO_EXTI_IRQHandler函数里面的中断清除语句注释掉,因为我们写在callback函数里面了。6 ?. D& X9 h; }$ y+ _+ P2 ?) A0 A( L 实现按键控制数码管。 . S a2 {( A, z# q& a/ p2 D * s# E. t& L" }& v' Q" p 4 n8 }4 x8 p; N' u- l |
STM32 ISP IQTune:真正零门槛的免费ISP调整软件
【经验分享】STM32 新建基于STM32F40x 固件库的MDK5 工程
意法半导体MCU双供应链策略,打消中国客户后顾之忧
【经验分享】基于STM32使用HAL库实现USB组合设备CDC+MSC
2024意法半导体工业峰会:赋能智能电源和智能工业,构筑可持续未来
ST推出灵活、面向未来的智能电表通信解决方案,助力能源转型
意法半导体 x Qu-Bit Electronix:推动新一轮的数字声音合成革命
从STM32 MPU产品看嵌入式系统中微处理器的新变化
【Hot!】STM32全系列开发板都支持Arduino开发,你知道吗?
【经验分享】STM32 HAL库移植FreeModbus详细步骤