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

【经验分享】STM32G4之外部中断

[复制链接]
STMCU小助手 发布时间:2022-7-5 22:23
一、外部中断原理
$ M/ O& t3 w; sSTM32G4 的每个 IO 都可以作为外部中断的中断输入口,stm32芯片集成了一个外部中断/事件控制器(EXTI),由23个能产生事件/中断请求的边沿检测器组成
+ R( `/ d, x" ?4 K# u
/ p5 C# ^' b! f% |) l9 ?# @/ q每个输入线可以独立地配置输入类型(事件或中断)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求
* a3 q6 n& e4 E. ?' q5 T7 p1 P9 k& C! ~7 Z$ N' o* O% r- G* c
23个中断/事件请求包括:- v) ]4 i) m# e( R' R9 `: A6 M2 W
IO可以做为EXTI线(0…15)【常用】  C, J( ?9 H0 L0 M# u$ s
EXTI 线 16 连接到 PVD(可编程电压监测器,用于掉电检测) 输出
' v3 a1 o! K# d) {EXTI 线 17 连接到 RTC 闹钟事件+ n2 J. t" N# Q, Y0 t) e6 @' b
EXTI 线 18 连接到 USB OTG FS 唤醒事件
% n/ {6 G& U" f+ L# g7 o) K8 hEXTI 线 19 连接到以太网唤醒事件
5 k1 f, m3 H- M) z& yEXTI 线 20 连接到 USB OTG HS(在 FS 中配置)唤醒事件6 ]; D) U8 X) V, |  k2 W
EXTI 线 21 连接到 RTC 入侵和时间戳事件1 A7 y( S. |- i& \' s$ W
EXTI 线 22 连接到 RTC 唤醒事件
1 m: H4 T2 u3 T* x4 p使用外部线中断需要开启AFIO中对应的中断功能
! Q6 X3 T1 o* E- Z. ]5 }  M
. v4 N8 P; }9 b* G 7~ULLK$N9E~%OHD65}I0F51.png + u" t$ ^6 L+ @  j' {
, M0 B2 j7 k9 e) d4 F; `. Y
GPIOx.0~GPIOx.15(x=A,B,C,D,E…)分别对应中断线 0~15,中断线每次只能连接到 1 个 IO口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上! E5 b. F' c  Q3 C# S1 T0 N

3 h6 L* ^, q6 j0 U* G0 ?) _边沿检测电路是检测上升沿触发还是下降沿触发或者两者同时触发,检测都产生外部中断请求或者事件请求
4 Y# @! [) e6 D( j, D3 z6 |: y- Y" Q, W" @* v: Y
中断产生过程=:; T( G/ n0 U' f
(1)通过配置上升沿/下降沿触发选择寄存器选择边沿检测电路所要检测的边沿跳变==
$ X. I. S7 E, ?6 y& z! L( R+ d  s3 c* [9 y- ^; q( I; d
(2)边沿检测电路根据输入线是否有相应的边沿跳变,检测到则输出信号1,否则输出信号0
. J$ p% a" r" {* U  b5 m# }' S1 E! K; d" |' j: c: W
(3)通过一个或门,以边沿检测电路和软件中断事件寄存器(中断事件可以通过软件产生) 作为输入。只要有一个产生信号1,或门就输出信号1# P* L6 h+ X9 J1 C$ N. v; y
! i& j( k0 P( I5 i( y. T3 E- f
(4)或门输出的信号1, 输出的信号1发至请求挂起寄存器
5 l6 v1 {! O0 @0 j+ P9 T# Y6 T3 c
+ h4 d1 ^5 Z, s(5)请求挂起寄存器对应寄存器的位置1,然后请求挂起寄存器会产生一个信号1
* q3 R+ k' v* G
, I1 t7 m* {9 s2 A7 T" \6 I, r(6)请求挂起寄存器、中断屏蔽寄存器同时输出信号1,则发生信号1到NVIC中断控制器, 如果中断屏蔽寄存器的对应位为0,则该请求信号不能传输到与门的另一端,实现了中断的屏蔽.8 y% A/ P  b. M# [% ^' o3 Y
9 ~( m6 E0 E- L- m( k; |2 b+ h
事件产生过程:
0 x6 _) y( y7 H% M- s(1)通过配置 上升沿/下降沿触发选择寄存器 选择 边沿检测电路 所要检测的边沿跳变3 u7 h# C0 I+ O
* |) |: \, r: m6 k6 O2 c
(2)边沿检测电路 根据输入线是否有相应的边沿跳变,检测到则输出信号1,否则输出信号0。6 Q, B) _4 H/ s3 Z9 I
* P# W: t) z/ `1 P! D4 m& B* G8 p
(3)通过一个或门,以边沿检测电路和软件中断事件寄存器(中断事件可以通过软件产生) 作为输入。只要有一个产生信号1,或门就输出信号1
! x* P# X. H" Z  b" r9 y3 G: e& Z; x& ]" b. a/ @, b' V) |
(4)或门输出的信号1, 若事件屏蔽寄存器也产生信号1,则产生一个信号1发至脉冲发生器,脉冲发生器产生脉冲
/ C. I" b/ u" E/ c* B% N) a# E" j  s, Q2 S+ G# I
从外部激励信号来看,中断和事件的产生源都可以是一样的。分成2个部分,是由于中断是需要CPU参与的,需要软件的中断服务函数才能完成中断后产生的结果;但是事件是靠脉冲发生器产生一个脉冲,进而由硬件自动完成这个事件产生的结果,当然相应的联动部件需要先设置好' ?: T+ c, g- h* S! x' R6 g) D
  |6 V  ?5 a6 Y! n
注:
* j3 J1 ^  D3 A) R( c& m6 d5 \(1)中断是需要经过芯片内部程序处理,然后跳转的中断服务函数
! c- {/ X( D+ C' \% U7 e8 ~3 S& F1 Q" X
(2)事件是检测到某一动作(电平边沿)触发事件发生了,进而由提前设置好的相应的联动硬件自动完成产生的结果,
) }/ L8 J! y* }5 g" l$ e# A; Y4 k2 [, U8 T- z+ H' h7 R( D  u1 r
事件机制提供了一个完全有硬件自动完成的触发到产生结果的通道, 不要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度(硬件总快于软件),是利用硬件来提升CPU芯片处理事件能力的一个有效方法
) x9 G) |. g' f$ S/ V
: c2 N+ ^2 R. L6 D, e  ueg :
) i7 ~/ X- s- D% {5 B外部I/O触发AD转换,来测量外部物品的重量,如果使用中断通道,需要I/O触发产生外部中断,外部中断服务程序启动AD转换,AD转换完成中断服务程序提交最后结果;/ O/ M% W4 Y  v1 i& ~

) n. e) b; P; A若使用事件通道,I/O触发产生事件,然后联动触发AD转换,AD转换完成中断服务程序提交最后结果0 o6 Q# ~8 P# L7 ?- I9 [) o

7 z8 y5 i* e5 v4 b3 e* J相比之下,后者不要软件参与AD触发,并且响应速度也更块;要是使用事件触发DMA操作,就完全不用软件参与就可以完成某些联动任务5 I' a1 p8 e1 U" T

  n, H) u) y' F! ]8 B7 a% B二、配置外部中断3 [4 s% b# y4 H) [. b  l& F
(1)将PA0配置成外部中断0" H1 C5 U$ G0 ~! ]# D
  g) x$ V6 }) n0 Y2 J' x
Y3V1Z8[[V2T)`VY@KQT_WVV.png
. o5 j3 R8 S/ @
. ?' w6 T( _  A. a+ q- A' b; d(2)配置外部中断的触发方式,就是配置边沿检测电路,配置成下降沿触发(PA0接有上拉电阻)上下拉可以不管; |% Q' w1 o, {" H/ o. d
& t! Y' [, Z/ G
SA30N`MW@MY)61EQDZ94C$S.png 0 t% T$ Y- R& {; x4 p% y3 {. S2 i

0 a/ L' w- B% U) a+ n(3)在NVIC里面配置中断优先级分组和抢占式优先级与响应优先级0 R) v, V* h& W
  C+ ^! f( d4 c9 }0 a
1[@J_WTYGPS}6LC[_Q8[`R4.png 7 ^0 _5 a% N9 p& _5 G
- k3 y3 ~+ @% C9 i
生成CubeMX文件,进行移植需要有关PA0和外部中断的配置
8 p2 f- a8 J3 |, K/ z- z2 q2 E4 g/ b4 x. M' t
(4)优先级分组设置一般在msp.c文件的初始化中
; M+ e) b5 K5 b! a
/ m4 E5 r. W+ H  r# j Y((F~([GT8B@LP$K9LU%}$X.png
$ l2 }% R/ y4 S; _9 a4 G0 x+ _% T# J5 B3 Y
(5)外部中断的中断服务函数在it.c的文件底部
' U* N+ G9 b+ D0 R( y" M我们不需要修改这个服务函数,因为在里面他调用了HAL_GPIO_EXTI_Callback这个弱定义函数,所以我们要写的代码应该写在这个函数里面,可以在main里面重新定义一个一样的函数即可# y4 _$ s! S) S
# b8 ^8 E3 l; I/ Q- P
Z4%ERE2)[{W[UXQ1P~]2K%U.png " Z* P4 Y6 N0 z! P  ]) T* C
1 W1 W, v! X" ^3 r9 e4 @  `
小结
& \3 h9 ~! R+ j! i- u: T' b8 H: c& R0 |4 c  d
DROLT2RB9BC8NRY3WZ80PS6.png
$ q) w6 P3 D* m1 y9 f( i4 ~# [9 E6 P  J' o7 n6 C# _6 ]2 }
三、部分代码9 B; F& m. J3 o
外部中断引脚初始化% F7 _2 R3 B) P3 r6 U: t2 Q

$ S% u, o) R1 I" s7 u
  1. void Exit_Init(void)
    % h! K# E* a* Y5 r1 l# O
  2. {
    9 J! t  b  z4 `. f7 D
  3.         GPIO_InitTypeDef GPIO_InitStruct = {0};
      U! }4 N9 Y; {# e
  4.         __HAL_RCC_GPIOA_CLK_ENABLE();5 J- T7 F8 Q! K9 u8 ^+ [
  5.         
    ( ]6 W; E( v* _" U# e; ]
  6.   /*Configure GPIO pin : PA0 */
    9 c7 P- I' p3 {# P
  7.   GPIO_InitStruct.Pin = GPIO_PIN_0;4 s& |' m& D' y3 k" J
  8.   GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;0 u1 n& L& S# |2 C% R
  9.   GPIO_InitStruct.Pull = GPIO_NOPULL;
    ( |% ?( r7 X( u% M+ [- o/ J9 P8 P) Y
  10.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    ( M; v9 y7 K! x, G: z
  11.         / C# K, E* z( _" T4 Z. [% `
  12.          /* EXTI interrupt init*/
    9 W. g: v- X) g. ?
  13.   HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 1);
    - e% M' z/ h. k5 \) [1 X
  14.   HAL_NVIC_EnableIRQ(EXTI0_IRQn);
    6 D7 X9 T: d8 S( h" @: f
  15. }
复制代码
$ ^9 x% [+ |, E2 {
外部中断处理函数–>回调函数
+ s9 Z3 }: D4 A! l; K每按一次按键4,LED4和LED8反转一次
8 i$ M% ~9 Q, Q3 U6 g% J4 Y$ f" Y7 U: V: B! {4 `
  1. // 外部中断回调函数, 产生外部中断,会跳转到外部中断的中断处理函数* B" i8 b9 h: N9 z; ~' c7 ?
  2. // 中断处理函数又调用回调函数,进行中断处理! {5 d& B9 U3 _3 w7 Y
  3. // 每触发一次进入外部中断
    2 s! ]: _& o7 [1 j. K; {
  4. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)2 R7 H2 [! i9 V  K1 k2 [. U+ t7 n
  5. {
    3 Z/ b  y( w: o, L. K
  6.         /* uclde = 0000 0000 ^ 1000 1000 =1000 1000  (1)
    . v& c$ D- k: k0 G
  7.            ucled = 1000 1000 ^ 1000 1000 = 0000 0000  (2)" x0 B& B+ Z0 H3 T5 v( _
  8.                 uclde = 0000 0000 ^ 1000 1000 = 1000 1000  (3)
    3 e/ ~6 D6 ^, y# S# c
  9.          如此下去继续反转
    4 w  V6 }6 K2 p' {2 W
  10.         与0相异或值不变,与1相异或值变化
    , _9 k* w7 X( r
  11.         */
    9 K7 z. P5 N5 V* J4 ^
  12.         ucLed ^= 0x88;
    $ |1 F6 |7 V2 j1 Y
  13.         LED_Display(ucLed);! l- U' E( r4 h+ _& G9 Z- f
  14. }
复制代码
- u9 ~2 e" x. \- t) a( R

: _: [8 f1 }: J+ A/ q, G" o! O
. |, X" C# y# Q  D
! b$ w) W! P  A. k
收藏 评论0 发布时间:2022-7-5 22:23

举报

0个回答

所属标签

相似分享

官网相关资源

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