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

【经验分享】STM32CUBEMX--外部中断(EXTI)

[复制链接]
STMCU小助手 发布时间:2022-4-30 21:55
概述6 e% D1 h( o6 t0 X' }- E- W3 q
外部中断和事件控制器 (EXTI) 管理外部和内部异步事件 / 中断,并生成相应的事件请求到CPU/ 中断控制器和到电源管理的唤醒请求。本例程主要讲解如何使用外部中断触发LED。( X8 P9 Y2 B- t1 [) Y/ j4 ]

% @$ ]# |/ ]6 G$ b4 y1 J硬件准备% B9 `; a9 S$ z! s% ~7 m
首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:
5 C6 ~( H! R9 I+ r" y1 a, ~: N5 B) i' M# U& P4 f
9KQPF4MPW1JWM@BHVP2QS[F.png
6 C  d+ @; D8 S) `" c0 l
: s- o, C3 y& q& A5 p5 @0 u# S选择芯片型号" i; j2 L3 {! h* t
使用STM32CUBEMX选择芯片stm32f030r8,如下所示:. a5 C% W4 G' v; P  ~( L) @0 a- {

# Y8 K' n% z# a. ^* @ 20200604204408810.png ! X& B5 J: N% n; Y8 m
- t2 f& ?* v0 a9 z) b
配置时钟源' Z2 E' s$ K: D) {6 i
HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:8 Q, F3 E6 R  W( U: h9 ^3 u* f" n
% ?9 ?2 m; O% r% h" f4 f( z
F5}@MISQL[S(PNB%9Z}T3VL.png 2 X/ o' z7 A, k" a7 j. T% l( d

9 H( `! @' n1 D% ?& @配置时钟树
$ t5 G* ~. S; E" a% ]STM32F0的最高主频到48M,所以配置48即可:
( s4 v  m: B, K$ C9 Z! {6 b( k/ Z! q
I8H3V9GXZ_VBHG_EIXVCIDO.png + K: u! m( }+ }9 Y: I
4 v3 O/ e9 y( a& t) ~
中断口配置
  E# D/ c: @2 A1 P开发板上的PC13为蓝色按钮,故配置此端口为中断口。4 @% |$ m# l) H2 o; u0 Y
. _5 J/ `$ j% F. c! c, f1 c4 k
JLTQBLR(AYKKA{PXW$$VXDI.png 6 z& I. @2 c# C6 ~: e
W`{V$O86SXSOC18P~A(0ZQF.png - ]) K2 t/ d8 v  v/ Q
/ H1 x1 C- o1 k& o; ]! w
GPIO 口连接到 16 个外部中断 / 事件线如下图 。可以看到PC13应该是在EXTI13上。6 g: U4 K; g/ L% A
4 f/ Y, _7 }6 D1 p2 m$ A/ s" e
C7GX[FKX{PVATDE{)$UTO40.png * |/ \! t% ]. D% Z

2 D/ `7 Q8 l6 \5 w  C8 ^0 l$ _外部中断/事件控制器用于产生事件/中断请求的边沿检测器。每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发)。每根输入线还可单独屏蔽。挂起寄存器用于保持中断请求的状态线。
8 S2 b1 H6 a; y
) V' @3 b, x4 V1 u1 O( N @9K6RG~N[TDM]QKV8A~7[J4.png 8 c! Q. D  t" r, P0 g* _( ]
1 c% m. s9 K- W( G
所以需要配置中断口是上升沿触发或者下降沿触发。( f6 @, B0 C: \5 ~9 g9 {- p  z* G
& q" ]/ P) R; u; D/ |/ W/ {  P4 K  \7 ~
8L$E[BI%8K{1{~DVBR}X]99.png
# r1 |9 r, Y4 R0 e5 o) Z3 V% Q
9 x: }$ F" y" }# o) }- U: o. @查看向量表可以得知PC15应该开启EXIT4到15的中断。
5 h' m, D8 J9 Z+ |( R5 D: V: J( k# f. g
UHO~]`[UQGGA]9P]@K{~08T.png
  `, K) R$ E; g) u
/ m. r1 s# Z1 K2 R8 G {KGWI{GT1NHI@)F4P2D4~IV.png
- I8 i9 @# l* P( u
: }; ^2 G' S4 _GPIO配置3 K+ U$ k- ?- b4 R4 h; u0 J6 w0 K
PA5为板上LED灯,配置PA5为输出口,当中断发生时候改变IO口极性。
6 u6 y" m) A$ V3 f
' a9 Z. F) E$ i* {% c: D, o " S* p4 K0 O7 b# k2 Z* z) G

* H; ?2 O# e. ]- I, `+ T 374IFVZEG_3L)528G[_(A.png % d& W- F* s2 Z+ G3 T
% K, M/ C6 _) m+ [; ?* t+ J- a, l2 y
生成工程设置! S5 G, |8 ^5 f
注意在生产工程设置中不能出现中文,不然会报错。
6 ?2 j2 y4 Q% `! J
% u2 h+ a1 i& a' _6 Q DL8[QL10RAKJUM%_{WQTFU7.png
, z) I2 a. |% [* d0 g; Y3 ]; z- v5 h6 x5 D  ^( J
生成代码( }  N* D; J( ^9 g% [0 w' n

; \9 t1 N& n) v
I_2%3M0AA4`F7`038G09T43.png
' ]; r' m& ]5 j' ~
% H" V) n/ m8 N$ o8 ~配置keil
$ x1 @( B% Z) q  q. s( o/ j5 V

! q: S: S8 F: e$ S {[V)TQDEI_P4O)}VCQW3P`V.png - t; G* h/ i% M$ n' i3 m& g

% Z- p+ i8 T) }& L设置IO口模式,触发条件,设置 IO 口与中断线的映射关系
4 m5 ^- Y' U7 C
首先在mian.c的MX_GPIO_Init中,GPIO_Initure.Mode=GPIO_MODE_IT_RISING,这里设置为上升沿触发。Mode值为GPIO_MODE_IT_RISING(外部中断上升沿触发),GPIO_MODE_IT_FALLING(外部中断下降沿触发)或者GPIO_MODE_IT_RISING_FALLING(外部中断双边沿触发)。
& S$ z- S; ^4 S2 \* Q) E/ @GPIO_InitStruct.Pull=GPIO_NOPULL,这个为管脚悬空,没有上下拉。" {; R# c, i/ u
3 b# }+ `  J: e
20201202162231498.png
  \, p% L; c9 R; ]- o3 O
& o3 s5 Q- ]/ _9 U9 m7 W配置中断优先级(NVIC),并使能中断. U! f. |  d6 d4 c2 h# P1 \
同样的,在mian.c的MX_GPIO_Init中,设置好中断线和 GPIO 映射关系,然后又设置好了中断的触发模式等初始化参数。既然是外部中断,涉及到中断我们当然还要设置 NVIC 中断优先级。
4 |$ Q. Y6 W% j. F5 d! |- X* THAL_NVIC_SetPriority的中间0表示抢占优先级为0,最右边的0表示子优先级为0。# w; N9 |8 c$ S$ O0 r% V( P
& c- k; }8 o+ h+ @
1.抢占优先级比子优先级的优先权更高,这意味抢占优先级更高的中断会先执行,而不管子优先级的优先权,数值越低优先级越高。5 a0 g2 s! s* P0 B* e0 S2 n: Z
2.同理,如果抢占优先级相同,那么就会比较子优先级,子优先级更高的中断将会先被执行,数值越低优先级越高。
2 I  e0 M; r1 W, W) H4 L0 |  D$ |3.当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。
: I/ [# c8 d" q/ ?& S7 i
) N3 F  N% R1 m5 I( k0 v N4`10O3)0ST7YLINRB~CQ]V.png
/ B- _3 e+ k. Y5 a2 T
9 k- K4 U6 H5 s中断服务函数
6 W9 N9 \: b; t) Z配置完中断优先级之后,接着要做的就是编写中断服务函数。中断服务函数的名字是在 HAL 库中事先有定义的。STM32F0的IO口外部中断函数只有3个。
/ }+ Y# W* n0 A$ h" J8 Q6 X; f" v2 F6 H% s* }# O7 e/ h' v5 H8 |! ]
) ~' s3 @3 t; v4 h2 |+ k5 q- h4 L

# ^5 m# i1 U" k8 J1 j& i中断线 0-1每个中断线对应一个中断函数,中断线 2-3共用中断函数 ,中断线 4-15 共用中断函数。一般情况下,我们可以把中断控制逻辑直接编写在中断服务函数中,但是 HAL 库把中断处理过程进行了简单封装。6 B4 N! ?, L9 i7 n; e! O* f% ?
. {+ H; R% i$ S$ R1 \: \; a
EXTI4_15_IRQHandler
1 M0 K/ F3 S* O5 [/ h在stm32f0xx_it.c中,程序开始执行EXTI4_15_IRQHandler函数,EXTI4_15_IRQHandler函数只是调用了另一个函数HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
2 V1 p4 j; h/ w8 V$ m4 D) q( P! W
$ M7 I! d" d( ~5 B U6{{(PB~R9V3T{X$VCMUJW8.png $ Y* N6 h( a  L; O9 O
1 {- ^8 \* R4 d8 X1 c9 l- h
HAL_GPIO_EXTI_Callback" I' u3 F+ X. i- w: d/ t" n  @
在stm32f0xx_hal_gpio.c中,HAL_GPIO_EXTI_IRQHandler该函数实现的作用非常简单,就是清除中断标志位,然后调用回调函数HAL_GPIO_EXTI_Callback()实现控制逻辑。根据函数名Callback也能看出来这里才是真正执行具体功能的函数,该函数需要在mian.c文件中重写,通过判断中断是来自哪个IO口编写相应的中断服务控制逻辑。
" G$ x4 f& H% c' g- u  G( b! J1 W; P7 C- Q8 _; I
M~OESC%0VQRQ@NUUU98]D3B.png
" f( |- W/ U! [8 r4 `
# x9 i- N( r. i* z8 n+ l代码
1 R. _  t0 K1 M9 ]3 D# M在main.c中,重写HAL_GPIO_EXTI_Callback。/ E% a4 O& `* ]' H# A$ N$ c
, s2 v1 m  H/ i8 w# m  G
  1. /* USER CODE BEGIN 4 */7 P) t- L; L3 S( _  z2 Z. }
  2. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
    ) h1 \% _6 L( s& y
  3.     if(GPIO_Pin == GPIO_PIN_13){/* KEY */  
    $ n1 C5 b6 N* ]  j# h7 B
  4.         /* 翻转LED *// G( N5 N* W6 u
  5.         HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
    ) G$ c$ e( D7 O7 ?4 M
  6.     }
    1 ]. O* H. I% f
  7. }
    4 W$ f& E% d! |# _
  8. /* USER CODE END 4 */
复制代码

+ d2 M! s# }4 W$ @" u+ f& h; G5 \0 E; C) T0 K+ A- e
演示效果

9 l! k* W$ o6 Y5 v5 \LED灯随着按键按下改变极性。
7 w2 q; o* i( g$ u3 B$ {7 C) J) @$ O. V- A1 I9 a
20201202173231456.gif
( b. C" K# q+ D# |4 C: \
2 T. |/ o/ U, k) `9 c( @0 K2 h
赞 收藏 评论0 发布时间:2022-4-30 21:55

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版