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

STM32学习笔记03—中断架构

[复制链接]
STMCU-管管 发布时间:2020-10-27 14:16
STM32学习笔记03—中断架构
( N$ V) x0 \" c' U8 f

2 A: F  u1 u* i0 U
( p+ ~* w6 w* Y1 K  Y: V9 U& \
3.1 STM32F103中断概述
7 T) |1 T/ n) C1 E& q       Cortex-M3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32并没有使用Cortex-M3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。而我们常用的就是这68个可屏蔽中断,但是STM32的68个可屏蔽中断,在STM32F103ZET6中只有60个。  G+ n3 y5 g% c1 K. D5 c

+ r/ M* D, h. K: P1 V
% n0 b! @. I* [" r2 h' Z1 x
3.2 STM32F103中断优先级
( y# p3 ^) z  @% p3.2.1 优先级结构
+ R& U  a: v. ^' n" ?" S- R2 G       STM32F103的中断分为抢占优先级和响应优先级两种,这两种优先级的顺序是抢占优先级高于响应优先级,假设存在两个事件,那就会存在以下几种可能:5 f- f" r  B$ V6 I% _0 E$ x

* l9 Z; h% k% B( }& @  g, w0 W+ N
, P5 G. e5 m* }. a# _! Q, i& t
(1)情况1:事件1和事件2的抢占优先级都是1,事件1的响应优先级为1,事件2的响应优先级为2,那么事件1和事件2同时发生的时候,CPU优先处理事件1,然后处理事件2;2 G# x$ v  ?; U; q3 S

; S, ~' H. \' ]- G+ u& V* W- g
6 m6 g5 |9 {, _- G- p# U
(2)情况2:事件1和事件2的响应优先级都是1,事件1的抢占优先级为2,事件2的抢占优先级为1,那么,事件1和事件2同时发生的时候,CPU优先处理事件2,然后处理事件1;
. H/ C6 a* R2 U, {0 Y
) w4 E8 @; y9 \. M8 ^; d' z

) @# ^& t# M# t(3)情况3:事件1的响应优先级为1,事件2的响应优先级为2,事件1的抢占优先级为2,事件2的抢占优先级为1,当事件1和事件2同时发生的时候,CPU优先处理事件2,然后处理事件1;
8 x, J2 f0 D5 O( K7 u. F2 c
9 I! w, A% u% f4 v5 n

8 m. J3 K7 [' I& S: R- v       通过上面两种情况,我们可以发现,当抢占优先级一致,谁的响应优先级的数小,谁的优先级就高,中断同时发生的时候CPU就先处理谁;如果抢占优先级不一样,那么无所谓响应优先级,谁的抢占优先级数小,优先级就高,中断同时发生的时候CPU就先处理谁。8 s  i6 W- z! y3 T9 E1 N5 G
$ Q9 I. U& I3 w/ ]& R% B

$ G/ I+ Y( v$ [% r       STM32F103的抢占优先级和响应优先级各有4级,即0~3,根据乘法原理,也从侧面反映了16级可编程的中断优先级,并且抢占优先级和响应优先级的数量是可以设置的,通过中断分组来配置,中断分组和优先级数量的对应如下表所示。  J  E+ W  A' x: A( a
1.png

5 d( `) I9 r7 F, P/ w3.2.2 相关寄存器
$ i$ |9 Q: U% g1 X! B2 y6 K8 ^% U% Q(1)中断应用和复位控制寄存器:AIRCR
; j# ^$ w! G- }1 Q1 f- O1 E7 j$ _5 H% H
2.png
4 t2 z# g: E4 K- g
Bit 31~Bit 16:激活代码,写入0x05FA激活寄存器  v2 O) I5 e0 J

, d; t$ `: D& s& A6 S; c% R- f/ YBit 15:指示数据的字节序(这只能在重置后更改)" _" M% J5 \& [. C4 C5 V
* b. m8 O; Q8 O2 f- `, k9 s2 a
              0:表示小尾数
& B6 m8 g* ]2 r1 N5 d0 H* m$ R5 |1 G' P0 B! V9 a
              1:表示大字节序" i5 P4 Z$ R4 W6 ]6 \# e, h/ X/ P
  V( n: Y/ a7 f, p: m
Bit 10~Bit 8:中断优先级分组5 J$ x# _7 w6 _& K
) f3 ~. k' ~% R3 y- F
Bit 2:请求芯片控制逻辑产生复位
6 l: l' N+ S( V) X
: N; G& R# A- I. ^# X' [Bit 1:清除所有活动状态信息中的异常
6 e4 x7 s! h* Z0 M$ `* P# R% u* V) [$ a! t, x0 d! G& a
Bit 0:重置Cortex-M3处理器(调试逻辑除外): U: w: }7 c# P( I8 w5 ~& T3 X% D9 g
: a; K4 p) _9 _$ ]8 f) [
(2)中断使能寄存器组:ISER
2 O+ z: g( H: l% X" L+ E8 l
) N( O; I: R& [2 S5 A$ C0 u       在STM32中,ISER寄存器一共有3个,ISER[0]的0到31位对应中断0~31,ISER[1]的0到31位对应中断32~63,ISER[2]的0到3对应中断64~67,如果需要使能某个中断,必须设置对应的ISER位为1,要清除的话可以设置ICER寄存器组对应位为1,或者对ISER写0,但是对于ICER寄存器组写0是不起作用的。' t- r3 q! F- _7 r' P' t, L

& T: q: R5 ?) b( ?(3)中断优先级控制寄存器组:IP0 F6 ?5 T  Z) y. _/ K5 X
3.png
1 R  k7 a" P% p对于STM32,优先级控制寄存器IP一共有68个,对应着68个中断,每个寄存器的结构都是相同的,如下图所示。
5 z9 s" K0 |! j/ f. ~+ B' \3 j  m6 ]5 _" o! y' T

/ k0 n0 S0 I, ]5 n+ j4 |' j7 cBit 7~Bit 6:抢占优先级: i9 h$ Z% C8 ~3 p. y

8 t" B6 d; ~% |) |: O3 U" }( WBit 5~Bit 4:响应优先级; Z" M& n% ?2 d1 |* p) e
0 M9 K8 f0 x9 N. B, y  N! j0 c6 p+ g
3.2.3 中断优先级配置函数
0 A6 d: M" D5 v4 {+ {& M. h+ Q
; c8 g) [4 V- ]& N
  1. /***************************************************
    6 {3 X# t2 \$ L2 R" o' S
  2. Name    :NVIC_Init
    ! l& ~' T; Z, ?4 y8 g2 r1 P# B
  3. Function  :设置NVIC% s9 I) d; E' N6 L# R6 @6 x- g
  4. Parameter  :
    ! T( y/ D5 n: G5 s
  5.       PrePriority  :抢占优先级+ e6 q& q" ^& t2 T8 Y. q' S" _$ V
  6.       SubPriority  :响应优先级
    5 G) a' h& ^9 u5 r6 k
  7.       Channel    :中断编号8 M: f$ V+ f- j( [7 A. h
  8.       Group    :中断分组 0~43 u4 V" f; b9 x0 `) ?" k" i. |
  9. Return    :None
    4 ^0 W8 O4 F6 {: i3 ~
  10. ***************************************************/
    , p4 a8 Q; d& p
  11. void NVIC_Init( u8 PrePriority, u8 SubPriority, u8 Channel, u8 Group )
    * g6 ^2 t/ A) B3 O% G
  12. {# V, B9 m; }. O6 w7 U
  13.   u32 temp, temp1 ;) ]) [, ^+ [# J2 ]
  14.   //设置分组
    0 Y% a: ~6 Z! V$ I0 v
  15.   temp1 = ( ~Group )&0x07 ;                  //取后三位, B, q& \' ^! d, n2 ]
  16.   temp1 <<= 8 ;
    1 P' T5 Z' a0 W: b6 w+ b& M
  17.   temp = SCB->AIRCR ;                    //读取先前的设置0 W5 l3 }' T# [3 q
  18.   temp &= 0x0000F8FF ;                    //清空先前分组( |3 }" `, K. t$ i8 y
  19.   temp |= 0x05FA0000 ;                    //写入钥匙
    9 M  j: _' G6 [$ C* t5 N  {
  20.   temp |= temp1 ;     
    ) o6 S; w8 x& y) h+ U: D
  21.   SCB->AIRCR = temp ;                    //设置分组4 m% N4 q1 e/ K/ t
  22.   //设置优先级
    - I8 Y4 G7 F  x* v$ y
  23.   temp = ( u32 )PrePriority<<( 4-Group ) ;
    8 E: t" y) t* z
  24.   temp |= SubPriority&( 0x0f>>Group ) ;
    8 Z  Q- I. q$ ~5 w
  25.   temp &= 0x0F ;                      //取低四位
    * i9 x, [3 k+ p, ?2 N! w. F' x
  26.   NVIC->ISER[ Channel/32 ] |= ( 1<<Channel%32 ) ;        //使能中断位$ F: I. j5 w6 l6 F' V2 B, P/ v
  27.   NVIC->IP[ Channel ] |= temp<<4 ;              //设置响应优先级和抢断优先级/ v. |8 Z7 z. Q9 v( c6 }' W
  28. }
    / B% E1 x3 L# h1 c+ J" K2 j
复制代码
' b/ z# j( I8 I9 a  b3 }( \& t

. J. H9 p/ U. Q8 z% Q: E$ @+ V3.3 外部中断EXIT结构
( {! N- V" x( x: y# J( z: \0 B3.3.1 EXIT概述& m" a  w& E; }$ }$ |- [
       外部中断/事件控制器由连接线设备中的多达20个边缘检测器或其他设备中的19个边缘检测器组成,用于生成事件/中断请求。每条输入线可以独立配置以选择类型(事件或中断)和相应的触发事件(上升或下降或两者)。每条线也可以独立屏蔽。
3 A# e: g* |4 R# I" W- I$ o
: V$ \# l+ N- ^5 i! r; s3 s       对于STM32来说,每一个端口都可以配置为外部中断,根据中断信号的类型都可以单独配置上升沿触发或者下降沿触发,中断服务函数相互独立。
4 I3 K* }8 n' Q8 T) Z3 J9 _% u5 ?1 z
3.3.2 EXIT相关寄存器
" j8 i" v& ~/ u5 B, t(1)中断屏蔽寄存器:IMR
' Y; t; S8 Y1 F4 k, v8 h- l" ~8 P8 C- p+ C. Q
4.png
% ^/ q1 m; X: V9 Y+ J: `5 I) l3 v# Jit 19~Bit 0:线x上的中断请求配置位  k6 U8 u# o' ~( @  I: F/ h
4 _$ V+ ?: z. J8 e: r4 |+ D
       0:禁止输入线x上的中断请求
: T) }" E3 N* ?. S$ {       1:允许输入线x上的中断请求
8 ]3 i; Y+ L. D  ]' y* h# F6 n
+ s# i. l. y/ C8 Z(2)上升沿触发选择寄存器:RTSR
0 O, |7 [- H: R" `* X) U. b& X9 O. l& l/ x$ @# \# }) P6 c
5.png
- h2 c" |& \9 l( H2 z1 Uit 19~Bit 0:线x上的上升沿触发事件配置位
# T/ o6 v  }& h7 P2 q5 N8 A* o; o7 P3 x+ R
       0:禁止输入线x上的上升沿触发
' R, E8 f: I7 a3 X" @! X. G       1:允许输入线x上的上升沿触发, M, s" J& l) q$ p1 {9 n

: W( j2 v- ?  D3 f(3)下降沿触发选择寄存器:FTSR! B8 f6 p7 h. J7 F: G& ]! @2 ]* b

2 m8 A* L4 G  U 6.png
  N, H- ]7 o1 ]6 i5 l* Q* WBit 19~Bit 0:线x上的下降沿触发事件配置位* W1 O3 ~$ d2 n7 j' i0 s) V
' s: Z& h* Z+ ~7 u
       0:禁止输入线x上的下降沿触发
6 p6 j2 }) H1 [       1:允许输入线x上的下降沿触发0 ]; L! L1 m5 i: I
(4)外部中断配置寄存器1:EXTIXR14 Y; N8 |. ~( m7 x5 g. V5 d
1 D5 ^- Y* w+ M: u" _  }& h! K
7.png
$ t- ]( p; b4 r1 J! TEXTIx[3:0]:EXTIx配置(x = 0~3)3 q+ W. M! N( b3 n$ ^( D
( k/ ]2 ^' c- b, T3 z
0000:PA[x]引脚                 0100:PE[x]引脚                 0001:PB[x]引脚                 0101:PF[x]引脚4 B  R+ S6 p( l8 v+ X# h
0010:PC[x]引脚                 0110:PG[x]引脚                 0011:PD[x]引脚
% `4 T# o& o. X5 ?2 |1 N1 A& R) N9 G1 q4 M$ w% @! ]( D# ~# }
(5)外部中断配置寄存器2:EXTIXR2$ b0 G" [4 K, Q) w" Y0 J
3 N+ ]. U4 c$ Q
8.png
: D8 w9 E! L4 j
EXTIx[3:0]:EXTIx配置(x = 4~7)( O' U6 J. l, ^# z6 R
0000:PA[x]引脚& P7 Q( X/ w, A+ o3 ^' [
0100:PE[x]引脚4 Y7 z$ R: z9 v1 B( E1 k, y: W) o
0001:PB[x]引脚
" P6 C' X5 c. x) B0101:PF[x]引脚. S) A3 W* A4 L5 k
0010:PC[x]引脚
  {3 Q! q# x" l) L6 M( R8 ]/ Z0110:PG[x]引脚0 Z8 O" h: G. c% u4 p0 [  Y
0011:PD[x]引脚
  f1 x1 `# M3 ]1 V4 ]
! T  b! P  H( ?, s/ T/ a2 h0 W; a(6)外部中断配置寄存器3:EXTIXR3( D/ \4 }6 X8 n0 V# B* F

' `/ X2 D9 g( ^' L6 a 9.png " `1 e- T/ `3 E  O
EXTIx[3:0]:EXTIx配置(x = 8~11); k+ j% u) ?; J, n, a% P
0000:PA[x]引脚7 w. Z' b' j) R
0100:PE[x]引脚
& U7 N4 P8 I* Z1 F0001:PB[x]引脚
3 r! `& m0 z* W. Z7 r0101:PF[x]引脚& x) r* S0 [! u$ ^7 Q* x
0010:PC[x]引脚
0 O8 z3 m/ r: l0110:PG[x]引脚
" f8 f- q* h  b0011:PD[x]引脚
4 @3 G4 M2 [* k  b/ q
! B/ ?4 |' E+ ^* k$ t" o6 |(7)外部中断配置寄存器4:EXTIXR4
! G& U% y* y( N  I) f9 M0 s/ ~9 n1 {' s) x
EXTIx[3:0]:EXTIx配置(x = 12~15)0 o/ F* {: [0 H, g8 M6 b) Z* [6 u( ]: Z
10.png " U6 x; u! ~, i4 ]% |1 ^
0000:PA[x]引脚7 S  ^) r8 z& ?" j( H/ |
0100:PE[x]引脚: n2 l! X' W6 Q
0001:PB[x]引脚
7 r: v! T+ D# c3 F0101:PF[x]引脚/ V/ {; ^1 H$ _
0010:PC[x]引脚2 }' M9 K$ a9 o0 R! _6 V
0110:PG[x]引脚( v, E8 C- ]7 H) s
0011:PD[x]引脚) A4 [- q4 z. I2 {. Z

$ l  \9 S+ G8 J" v2 n1 b. G(8)APB2外设时钟使能寄存器:APB2ENR
  A6 q7 [4 x' @4 b3 x
8 M. \2 ?* w- g2 E 11.png + |8 n7 r  N2 ]/ r2 {) ^6 v6 D
Bit 14:USART1时钟使能(写1开启,写0关闭)
. V& o" o1 z" }2 G' XBit 12:SPI1时钟使能(写1开启,写0关闭). P- Y5 ^# a7 n! D# x+ a" ~. B
Bit 11:TIM1时钟使能(写1开启,写0关闭)8 U) \1 C$ b- V& N8 y  \/ Q6 o
Bit 10:ADC2时钟使能(写1开启,写0关闭)
8 i  f4 |& J& c$ p6 d* F" JBit 9:ADC1时钟使能(写1开启,写0关闭)1 N0 u4 Z0 ]9 y. J, u4 ^5 P% u
Bit 6:GPIOE时钟使能(写1开启,写0关闭)/ N$ J" |7 z$ A2 {" q% h* y: o
Bit 5:GPIOD时钟使能(写1开启,写0关闭)
0 t5 @8 D& C% ~7 F+ v6 WBit 4:GPIOC时钟使能(写1开启,写0关闭)- ~5 S' ]* Q" V1 E! D$ g! p
Bit 3:GPIOB时钟使能(写1开启,写0关闭)
/ V0 e9 R: a* x2 g0 SBit 2:GPIOA时钟使能(写1开启,写0关闭)
! q7 f# t- H- l  ^+ lBit 0:辅助功能IO时钟使能(写1开启,写0关闭)/ U5 W6 i. U3 [: I7 ]

& }, P+ {/ w8 x6 ^3.3.3 外部中断配置函数
4 X! j4 ?3 m/ n4 Z$ u, A3 f* g" G6 d( E/ g4 f* C/ e
3 A& p6 y# K' \. b# t& o& z8 U
  1. + v3 `5 a( X2 C, p$ C1 K
  2. /***************************************************  z! Y0 A; e: n& K  s% j+ k* C
  3. Name    :EXIT_Config; n0 A% ], }$ F2 [/ I
  4. Function  :外部中断配置
    - u5 b* |$ c' _/ g
  5. Parameter  :) o3 T' j: U( w7 y. ?- h1 E
  6.       GPIOx:0~6,代表GPIOA~G+ t0 b" e! h3 G8 C, g
  7.       BITx:需要使能的位
    ' ~' a* F' g' d  y$ b: N8 X( i
  8.       TRIM:触发模式
    " h1 d1 H/ `0 N5 L! h5 m
  9.         1:下升沿
    " m; J  x3 C  w& T" E
  10.         2:上降沿. i! }9 y$ u4 P) B
  11.         3:任意电平触发
    ' G1 `2 p; @4 v
  12. Return    :None
    2 l  q- H* G4 k) n. N
  13. ***************************************************/
    / l( y7 h, R' \) F/ E
  14. void EXIT_Config( u8 GPIOx, u8 BITx, u8 TRIM )
    - N5 b- b2 Y) U5 P  F+ \
  15. {  n; R7 ?1 w1 }# f, E7 I5 z$ N& s4 T
  16.   u8 EXTADDR ;
    ' [7 s" ^3 G2 E! g' h
  17.   u8 EXTOFFSET ;
    1 x* P( x, L0 F, B- y/ b3 q
  18.   EXTADDR = BITx/4 ;                      //得到中断寄存器组的编号8 i2 f* V3 W  T& J6 W
  19.   EXTOFFSET = ( BITx%4 )*4 ;
    3 E3 j# J7 k- D- _( A
  20.   RCC->APB2ENR |= 0x01 ;                    //使能io复用时钟      
    3 |6 B) ]3 |7 H' ?- p
  21.   AFIO->EXTICR[ EXTADDR ] &= ~( 0x000F<<EXTOFFSET );      //清除原来设置% [/ K$ {0 S+ ^/ l$ h
  22.   AFIO->EXTICR[ EXTADDR ] |= GPIOx<<EXTOFFSET ;        //EXTI.BITx映射到GPIOx.BITx
    * s5 }" O$ I4 n; e3 A5 h
  23.   EXTI->IMR |= 1<<BITx ;                    //开启line BITx上的中断
    7 L' Y- v  s! W9 l! i
  24.    if( TRIM&0x01 )  EXTI->FTSR |= 1<<BITx ;            //下降沿触发
    & y' E! ^' Z! _/ H4 D' {3 K; I
  25.   if( TRIM&0x02 )  EXTI->RTSR |= 1<<BITx ;            //上升降沿触发
    ! f! Q5 O5 p+ J& T8 T' m
  26. }( ]7 W% }# K. E$ m9 r9 N
复制代码

! z: P: s7 ?, F# Y" E
" u% Q6 F2 n8 h! Q3.4 其他文件的添加/ P8 M+ B2 O8 |) W' c3 h' C
3.4.1 寄存器定义文件
5 Z& h" S) C8 F& z" Z' w(1)添加用到的NVIC寄存器组和EXTI寄存器组的定义。) o: V* B5 r( k0 y. L( [: C1 O& X
  [/ ?  W7 y$ k  ]4 h7 ?2 ], }( c" z
12.png 2 w. g5 P6 C5 q+ p1 |' j# m
(2)定义寄存器组地址5 Y$ _1 B! _/ u8 P
13.png
/ Y) e5 J- J: U  I7 c8 @0 {3.4.2 sys.h文件% B* H8 A# E8 ^8 }
14.png ) z* U( C; d. J- h6 O% u" D% {
上图就是添加子函数声明,为了用于其他文件调用。. c$ J& B9 W6 x6 a

6 q2 R: c0 [* a0 U1 v  H3.4.3 sys.c文件
/ L; Q+ f0 @7 |! ]/ v  F0 E( w(1)在STM32时钟配置函数之前增加复位时钟和中断的功能,最终函数如下图所示。
# Y  `6 g$ I# X7 k 15.png 7 [, t. U" G, k( `2 o
(2)添加刚才的两个子函数
) ]* G1 q5 y) R+ l  c 16.png 4 W0 x9 D- z  X
至此,sys文件里面最基础的函数就全部添加完毕了。
0 K, D- e. p( c3 Y# |$ x
0 L3 S3 Z( C* u8 }$ Q# t* R$ O
- @9 Y9 P7 c1 x2 q/ L上一篇:
. }6 M. g8 ?' pSTM32学习笔记02—时钟树架构) s3 b1 L* P% ~
6 F! u  ]2 {8 J
赞 收藏 1 评论1 发布时间:2020-10-27 14:16

举报

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