
一、外部中断原理 STM32G4 的每个 IO 都可以作为外部中断的中断输入口,stm32芯片集成了一个外部中断/事件控制器(EXTI),由23个能产生事件/中断请求的边沿检测器组成 每个输入线可以独立地配置输入类型(事件或中断)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求/ H# _! G# c$ [( d/ ^! p6 z 23个中断/事件请求包括: IO可以做为EXTI线(0…15)【常用】 R6 A! E# O6 `; N; Q( ]; [2 I EXTI 线 16 连接到 PVD(可编程电压监测器,用于掉电检测) 输出 EXTI 线 17 连接到 RTC 闹钟事件$ _3 p8 n1 ^" Z1 l EXTI 线 18 连接到 USB OTG FS 唤醒事件7 z% j' @6 ~/ M, _/ C7 ] EXTI 线 19 连接到以太网唤醒事件" \3 I, {+ S& D1 A0 ? EXTI 线 20 连接到 USB OTG HS(在 FS 中配置)唤醒事件 EXTI 线 21 连接到 RTC 入侵和时间戳事件 EXTI 线 22 连接到 RTC 唤醒事件0 v- s5 _ S. f! J$ \' Q 使用外部线中断需要开启AFIO中对应的中断功能 ![]() ( v) p6 I7 _2 V% v4 {( J GPIOx.0~GPIOx.15(x=A,B,C,D,E…)分别对应中断线 0~15,中断线每次只能连接到 1 个 IO口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上# O9 M0 b* H9 l/ T- V2 ~ 1 d: u0 Q$ X* ? 边沿检测电路是检测上升沿触发还是下降沿触发或者两者同时触发,检测都产生外部中断请求或者事件请求 $ l3 m6 l Y2 W: i; } w% H$ x- U8 p 中断产生过程=: (1)通过配置上升沿/下降沿触发选择寄存器选择边沿检测电路所要检测的边沿跳变== ' h ~* I. s6 Q( ? (2)边沿检测电路根据输入线是否有相应的边沿跳变,检测到则输出信号1,否则输出信号0 " _+ R. T$ q! k (3)通过一个或门,以边沿检测电路和软件中断事件寄存器(中断事件可以通过软件产生) 作为输入。只要有一个产生信号1,或门就输出信号1$ i' Y0 ~! v3 Y' `- h3 C" ^ $ w6 L# M: u) X9 \; `) O (4)或门输出的信号1, 输出的信号1发至请求挂起寄存器 (5)请求挂起寄存器对应寄存器的位置1,然后请求挂起寄存器会产生一个信号1+ t$ J4 L I2 v: W% K 2 Q8 _& i" G" A o6 A (6)请求挂起寄存器、中断屏蔽寄存器同时输出信号1,则发生信号1到NVIC中断控制器, 如果中断屏蔽寄存器的对应位为0,则该请求信号不能传输到与门的另一端,实现了中断的屏蔽.9 ~, Z. d0 b0 R 3 y+ V. H9 j6 O# y+ J 事件产生过程: (1)通过配置 上升沿/下降沿触发选择寄存器 选择 边沿检测电路 所要检测的边沿跳变6 t7 b+ ?' H5 U8 K8 Z (2)边沿检测电路 根据输入线是否有相应的边沿跳变,检测到则输出信号1,否则输出信号0。 (3)通过一个或门,以边沿检测电路和软件中断事件寄存器(中断事件可以通过软件产生) 作为输入。只要有一个产生信号1,或门就输出信号12 w, ?2 {2 s' S: n i5 L 0 n$ S% \; y/ ^' w& ` (4)或门输出的信号1, 若事件屏蔽寄存器也产生信号1,则产生一个信号1发至脉冲发生器,脉冲发生器产生脉冲 从外部激励信号来看,中断和事件的产生源都可以是一样的。分成2个部分,是由于中断是需要CPU参与的,需要软件的中断服务函数才能完成中断后产生的结果;但是事件是靠脉冲发生器产生一个脉冲,进而由硬件自动完成这个事件产生的结果,当然相应的联动部件需要先设置好# x* b; w( a' A( x8 \ 注:5 F/ B* y+ s4 M (1)中断是需要经过芯片内部程序处理,然后跳转的中断服务函数0 |9 _0 R9 y: s# z1 R( Q 3 O2 l S. R5 {% s (2)事件是检测到某一动作(电平边沿)触发事件发生了,进而由提前设置好的相应的联动硬件自动完成产生的结果,: r* C4 _% Q( c, z, J& a 事件机制提供了一个完全有硬件自动完成的触发到产生结果的通道, 不要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度(硬件总快于软件),是利用硬件来提升CPU芯片处理事件能力的一个有效方法8 C5 X$ Y* s9 c2 H 2 z( h' ]+ O) A+ ?* c/ Y eg : 外部I/O触发AD转换,来测量外部物品的重量,如果使用中断通道,需要I/O触发产生外部中断,外部中断服务程序启动AD转换,AD转换完成中断服务程序提交最后结果; 若使用事件通道,I/O触发产生事件,然后联动触发AD转换,AD转换完成中断服务程序提交最后结果7 W2 R2 N! F+ x8 q: m 相比之下,后者不要软件参与AD触发,并且响应速度也更块;要是使用事件触发DMA操作,就完全不用软件参与就可以完成某些联动任务% T% ?# S$ V1 h8 S1 |9 P# R2 E( u8 r 5 F6 D$ d5 e8 C. \2 r 二、配置外部中断 (1)将PA0配置成外部中断09 @ n- u+ K: i0 R3 ?7 B ![]() (2)配置外部中断的触发方式,就是配置边沿检测电路,配置成下降沿触发(PA0接有上拉电阻)上下拉可以不管1 [8 J, {: o* O' f ![]() 9 `9 j* `* F( `% |( y8 o (3)在NVIC里面配置中断优先级分组和抢占式优先级与响应优先级, H5 W7 ~4 U" D6 c# n t& X, S( V ![]() ( C2 U O ?6 G) m" Z9 {: \0 K 生成CubeMX文件,进行移植需要有关PA0和外部中断的配置- H6 n) |, r6 P ; J8 M, o- l8 m- N* z; H (4)优先级分组设置一般在msp.c文件的初始化中 0 h' g" k' B/ \ ![]() / C- l% P9 ?8 _; e1 P- q- F (5)外部中断的中断服务函数在it.c的文件底部 我们不需要修改这个服务函数,因为在里面他调用了HAL_GPIO_EXTI_Callback这个弱定义函数,所以我们要写的代码应该写在这个函数里面,可以在main里面重新定义一个一样的函数即可# \3 w" p" k7 s' O ![]() 小结% J7 r7 ?7 @- U: T, j ![]() ( ~% ]! ~) ?9 e# S3 ?( K& Z 三、部分代码# l+ }+ a2 k: V4 A 外部中断引脚初始化 9 A' j* L* c/ Y6 ?$ u, L- U# K
外部中断处理函数–>回调函数, N/ `, v. e, U9 ~* W% C, Q( S+ y 每按一次按键4,LED4和LED8反转一次 6 x3 h4 k/ x _5 U0 X
0 V8 t' v0 u+ ^: r6 ~+ i % V6 X: x& W3 E9 s( Z |