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

STM32学习笔记03—中断架构

[复制链接]
STMCU-管管 发布时间:2020-10-27 14:16
STM32学习笔记03—中断架构

' V9 x  R" X* k; g: m: c  m/ }( Z2 @

/ w' p8 C$ V7 |8 \% A3.1 STM32F103中断概述; U8 D0 H+ w. W7 X2 r: t
       Cortex-M3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32并没有使用Cortex-M3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。而我们常用的就是这68个可屏蔽中断,但是STM32的68个可屏蔽中断,在STM32F103ZET6中只有60个。: N* m5 t7 c: G7 u' E) t
9 P+ q! U" }5 P9 v& ~' ?9 {; x

3 ?0 D' f7 @/ t3.2 STM32F103中断优先级0 o) K$ y6 E9 n; U# x
3.2.1 优先级结构, m8 C( i% D- Y# k7 ~8 I% e( t
       STM32F103的中断分为抢占优先级和响应优先级两种,这两种优先级的顺序是抢占优先级高于响应优先级,假设存在两个事件,那就会存在以下几种可能:& k$ @' k) t' k' @

, w) g; @* o4 O$ f6 X
7 W4 S# x' a0 m: Y6 K
(1)情况1:事件1和事件2的抢占优先级都是1,事件1的响应优先级为1,事件2的响应优先级为2,那么事件1和事件2同时发生的时候,CPU优先处理事件1,然后处理事件2;/ O2 {$ y6 _" [, r4 K- y: j. I

, W3 |, d6 {8 H/ \  N/ a
) x$ x) F6 U! ~6 E/ f' B
(2)情况2:事件1和事件2的响应优先级都是1,事件1的抢占优先级为2,事件2的抢占优先级为1,那么,事件1和事件2同时发生的时候,CPU优先处理事件2,然后处理事件1;" Y) y9 `' g" T0 L: J& V" M* w
  X4 K+ k4 q# r' Z8 O& l

3 g$ P/ W0 y8 e# [(3)情况3:事件1的响应优先级为1,事件2的响应优先级为2,事件1的抢占优先级为2,事件2的抢占优先级为1,当事件1和事件2同时发生的时候,CPU优先处理事件2,然后处理事件1;
$ _3 o! q6 ~. R( B% v
& B* `! d5 x. Y( E
# a1 Y( A6 J( h1 j
       通过上面两种情况,我们可以发现,当抢占优先级一致,谁的响应优先级的数小,谁的优先级就高,中断同时发生的时候CPU就先处理谁;如果抢占优先级不一样,那么无所谓响应优先级,谁的抢占优先级数小,优先级就高,中断同时发生的时候CPU就先处理谁。
& P" _& j" _! e
8 b* Z3 j( B* L/ X; a
7 j! r: E' g! N' ?2 @$ {
       STM32F103的抢占优先级和响应优先级各有4级,即0~3,根据乘法原理,也从侧面反映了16级可编程的中断优先级,并且抢占优先级和响应优先级的数量是可以设置的,通过中断分组来配置,中断分组和优先级数量的对应如下表所示。, G+ y& o/ ^7 L" u5 `# M
1.png
- G% H; o8 {( ^, H
3.2.2 相关寄存器; g+ {. q  G9 V, a0 C% L
(1)中断应用和复位控制寄存器:AIRCR
  T' x0 B! K  J- v" V
2.png

& y) H1 j+ k2 W% d' T( w/ {9 nBit 31~Bit 16:激活代码,写入0x05FA激活寄存器
4 L9 l/ [; g- ?
& E( q2 \% \( W2 w# ^! p' KBit 15:指示数据的字节序(这只能在重置后更改)( P6 W- u8 w3 U' T( A- f+ y$ w
. w( d% ]0 X% n0 I" `! L9 `
              0:表示小尾数
! Y' l" l: ?5 ?+ t0 b( p2 o1 ?# O9 z  `9 P) t4 _
              1:表示大字节序& Q0 h' @- n* v# M

0 s2 X# @2 n$ o" jBit 10~Bit 8:中断优先级分组
7 G: j/ E3 q3 s5 |6 f" K9 F5 H
  `- e, b0 C; {) b; l5 X& h* ~8 h# |Bit 2:请求芯片控制逻辑产生复位
2 Q3 a. V( Z+ O4 q, a: v
( ?( P( Q" x' B% P, |Bit 1:清除所有活动状态信息中的异常
2 p! L: w5 G  `6 F' d" T4 _
# f* t" y9 U' j9 n# `1 s) DBit 0:重置Cortex-M3处理器(调试逻辑除外)! i( Z3 |: `8 R; k$ S0 S+ p/ {( t

+ V0 X- L+ s, d2 d  O(2)中断使能寄存器组:ISER" p( E: }7 m( [  a4 Z
2 C  z% e. J' b
       在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是不起作用的。
! S; |* _/ c+ s  y$ M- x- X/ @* `/ ]' n) N
(3)中断优先级控制寄存器组:IP) y$ v( e, t/ p: h
3.png $ i6 C. Y6 [  k& f" x, y5 y
对于STM32,优先级控制寄存器IP一共有68个,对应着68个中断,每个寄存器的结构都是相同的,如下图所示。5 c" q$ x+ e  Z9 k2 q0 _- E" w. P
/ i4 M' H6 D/ A- \. F1 z( [
9 B0 ~0 e& u$ J, g. x1 i
Bit 7~Bit 6:抢占优先级0 p; |) d2 B: u; U- t

5 J2 S! e. H  w# ]8 eBit 5~Bit 4:响应优先级' H, b2 f/ i' I6 h

, X7 `5 \, ]$ t! l3.2.3 中断优先级配置函数! a* R) O8 f7 z  W

. w3 e* E$ y, W
  1. /***************************************************6 P4 G, d: `- @: g* H% C
  2. Name    :NVIC_Init
    6 R" Q1 a8 h0 Q
  3. Function  :设置NVIC; P& W. Z; D' W  e7 b, x& P/ p
  4. Parameter  :/ K: W7 c" t5 t
  5.       PrePriority  :抢占优先级" D# \( O, S7 x" T# [
  6.       SubPriority  :响应优先级' e, J5 [9 m- [* n5 h: p6 Z# G
  7.       Channel    :中断编号' X' x; w/ [' y1 [: @7 G3 }, W) m
  8.       Group    :中断分组 0~47 `2 _0 _8 y$ n' I- l
  9. Return    :None
    7 }' t" |! v  w$ B" \# E
  10. ***************************************************/) L% C5 j2 }  j. H$ y
  11. void NVIC_Init( u8 PrePriority, u8 SubPriority, u8 Channel, u8 Group )1 Z. P+ r6 e- r  I$ ^% N2 s
  12. {
    0 @* T3 e" i* C' o
  13.   u32 temp, temp1 ;
    - A1 `' v- S! i9 N- X6 x* z5 n
  14.   //设置分组
    & m' ?/ [/ h& D
  15.   temp1 = ( ~Group )&0x07 ;                  //取后三位
    ; z' }& X3 y* b) F0 j) ~$ X
  16.   temp1 <<= 8 ;  t, m$ O8 E5 H. {0 V( B- n, L% D
  17.   temp = SCB->AIRCR ;                    //读取先前的设置
    / h0 @  o7 x+ B' h: g  S
  18.   temp &= 0x0000F8FF ;                    //清空先前分组
    2 W' q, F" l! D/ P" _/ R! v
  19.   temp |= 0x05FA0000 ;                    //写入钥匙
    6 W) |. F8 k$ C" [9 D! h
  20.   temp |= temp1 ;     3 V; p' K2 `" Q( @: \# p
  21.   SCB->AIRCR = temp ;                    //设置分组+ l) Y7 c3 r& n' }
  22.   //设置优先级
    7 S- a5 M3 D# ]4 v
  23.   temp = ( u32 )PrePriority<<( 4-Group ) ;
    ; C+ ?0 ~% e# m$ b, e0 x
  24.   temp |= SubPriority&( 0x0f>>Group ) ;) m, m  J, v( v% H% o% p
  25.   temp &= 0x0F ;                      //取低四位
      U% b. M# {- t- l" A6 f$ A7 ]# @+ M
  26.   NVIC->ISER[ Channel/32 ] |= ( 1<<Channel%32 ) ;        //使能中断位. K  L& i' [9 R! J( s; y
  27.   NVIC->IP[ Channel ] |= temp<<4 ;              //设置响应优先级和抢断优先级
    # W" U$ n! `) j& Q7 `1 j
  28. }% Y" u/ D! G7 K
复制代码
1 C. ?# {" }0 P$ K1 A

. z, z, I( ~" X% O% _+ t4 W' N3.3 外部中断EXIT结构
5 [1 ~: D2 C/ @4 }: E- ]% l3.3.1 EXIT概述  S" p% e: v- x* [! W
       外部中断/事件控制器由连接线设备中的多达20个边缘检测器或其他设备中的19个边缘检测器组成,用于生成事件/中断请求。每条输入线可以独立配置以选择类型(事件或中断)和相应的触发事件(上升或下降或两者)。每条线也可以独立屏蔽。; t7 z9 x  }- G; k, `5 {

! z/ ~1 I1 ?) Q  z0 r+ a0 V       对于STM32来说,每一个端口都可以配置为外部中断,根据中断信号的类型都可以单独配置上升沿触发或者下降沿触发,中断服务函数相互独立。8 z$ j" H; y: S6 @
' P7 ]3 R" d1 c) i8 o- i; S# K+ p
3.3.2 EXIT相关寄存器
; |; h/ |- H; M$ c: n8 z5 H(1)中断屏蔽寄存器:IMR
  y) @. ?/ o/ ]% {  I/ L  F& T0 M8 e
" I$ k% u, L. @4 t 4.png & E0 n# V! S: u: s  y
it 19~Bit 0:线x上的中断请求配置位
; e+ h; _; M* \2 a3 `6 ?( Z7 r
% A# O# G0 o0 b       0:禁止输入线x上的中断请求" `; H5 I% ?. a" m$ T
       1:允许输入线x上的中断请求
9 g- p& g3 V& j6 N- |1 b/ W+ u4 q! g5 d1 x' v+ D# E: b  \
(2)上升沿触发选择寄存器:RTSR
. O+ p+ p0 z$ @- e# I; Z! w5 w
0 a/ T" z. A) n8 m5 ^ 5.png
" ~+ o  M- H& q1 {) T# u# lit 19~Bit 0:线x上的上升沿触发事件配置位
7 q' p6 y# {) K0 r  d. X) s7 g: C1 q# j6 v
       0:禁止输入线x上的上升沿触发
1 r: }6 \8 u4 W" Q       1:允许输入线x上的上升沿触发& l2 ^! }; c2 J, J0 j: h
0 D  O, P6 ]6 Q9 a" f8 L1 O
(3)下降沿触发选择寄存器:FTSR1 W' A! k. h- w* l9 @+ C7 H. h
; G9 x( M6 L8 `: n. }3 @6 Z
6.png 2 v/ o6 u; D7 o3 P& r
Bit 19~Bit 0:线x上的下降沿触发事件配置位
% \6 \) ]/ [3 D8 U! {" Y: F
$ J( y' u1 d, v9 U- Q3 n1 u3 H       0:禁止输入线x上的下降沿触发3 r/ ^. }6 W7 ~: D
       1:允许输入线x上的下降沿触发- ]" ^6 ~' c! l5 u, |& r
(4)外部中断配置寄存器1:EXTIXR1
7 V  ^# c2 D/ s5 H, R7 o' u+ T. o1 B3 {$ L' i1 B* p  U3 b
7.png 6 d, Z( d* x! |) s2 V$ z
EXTIx[3:0]:EXTIx配置(x = 0~3)- Y$ j# L* h' ]* S/ G2 _& t& Z
, X5 e- n' L' p9 J/ z
0000:PA[x]引脚                 0100:PE[x]引脚                 0001:PB[x]引脚                 0101:PF[x]引脚+ e" ~. k- v" q
0010:PC[x]引脚                 0110:PG[x]引脚                 0011:PD[x]引脚
+ p7 ]0 W/ I2 N1 T# F& x6 v
8 X5 a# R8 c+ T0 q1 {! W+ |# I(5)外部中断配置寄存器2:EXTIXR2
: g0 Q( {- H3 o0 f& E- \* ~2 g
( p3 n" o, A3 b9 J/ H4 H 8.png
6 s. t1 c0 `% M
EXTIx[3:0]:EXTIx配置(x = 4~7)
7 I' w& S% U) n) z3 v) Y- A: s0000:PA[x]引脚2 U5 F* ?8 {; ?# s, e8 u
0100:PE[x]引脚
0 I1 ]4 E/ C" i' u0001:PB[x]引脚8 a' |. \' D) b9 Y1 V+ x' ?
0101:PF[x]引脚
1 G2 `" i8 y8 L3 t: k3 Y5 h0010:PC[x]引脚
5 l! z( u2 v" R0110:PG[x]引脚
+ Y8 o1 Z& K1 H: z  q" C0011:PD[x]引脚3 m! W8 T& m, w
5 N! ^7 p2 Y8 @# C5 c
(6)外部中断配置寄存器3:EXTIXR3: [3 f; U: e, e& v! s
: W4 F7 Z# ?  m( H
9.png
5 B+ i; p( Q- _; w7 B# C- V% |EXTIx[3:0]:EXTIx配置(x = 8~11)
# e* [2 z3 b7 w$ |3 h0000:PA[x]引脚
6 z8 Z; O* ]7 k0100:PE[x]引脚
( O' G/ i- G- h  M0001:PB[x]引脚" A- k1 s, e! i1 B- G7 r; ^3 u8 E4 K
0101:PF[x]引脚
- z0 z7 [+ I6 U+ H7 ?/ S0010:PC[x]引脚
  r4 v$ U$ V6 L0110:PG[x]引脚( E' b* q7 k/ c' y
0011:PD[x]引脚3 x' o" G: r1 S# f  w
: O- v$ @7 l" }
(7)外部中断配置寄存器4:EXTIXR43 _6 F$ p8 L2 |1 q& Y  R
  O& Q/ |  \  L2 g
EXTIx[3:0]:EXTIx配置(x = 12~15)- S5 c" z# x, B5 |2 F4 |' @- {8 m
10.png & J1 j" t# {; p3 `6 J. j/ {$ x
0000:PA[x]引脚
" A; G- q1 r. e. X2 Y; `' X0100:PE[x]引脚: d# y7 R$ h# h4 @
0001:PB[x]引脚
; @) o% ~/ @1 e0101:PF[x]引脚
4 I5 A  [$ N: M9 C; j" j0010:PC[x]引脚
6 D" e6 P* o( r0 |) M0110:PG[x]引脚2 j; S9 \+ j/ h& _! G- T5 R
0011:PD[x]引脚, v! r( \; ^* s: N$ g& O- u: a" u
$ a% i0 Z  {1 z4 L$ T
(8)APB2外设时钟使能寄存器:APB2ENR
$ k. U. `9 y3 H' [! Y% f8 m3 B! m  s6 o; z5 F+ B# o$ i
11.png
0 U/ G  U( }! C; F; `4 V3 r% UBit 14:USART1时钟使能(写1开启,写0关闭)
2 ~+ H* D6 Z. B5 K9 u# x- m; tBit 12:SPI1时钟使能(写1开启,写0关闭); P' c" S% Z8 L6 V5 f1 ]# h6 L/ M0 B
Bit 11:TIM1时钟使能(写1开启,写0关闭)( P. M9 [0 Q8 _: c# Z+ }* @
Bit 10:ADC2时钟使能(写1开启,写0关闭)6 s* D1 `( o6 X$ T. p; e& }
Bit 9:ADC1时钟使能(写1开启,写0关闭)- Y. I2 R7 X% D% Y& m) [% w
Bit 6:GPIOE时钟使能(写1开启,写0关闭); E- n; x: Q5 Y9 n. q+ w
Bit 5:GPIOD时钟使能(写1开启,写0关闭)
& {6 p0 D2 X* @: a( OBit 4:GPIOC时钟使能(写1开启,写0关闭)
  C/ R) ]( E" B3 p" UBit 3:GPIOB时钟使能(写1开启,写0关闭)1 L, v' O- U; X) k% B# E7 p- q5 G; z
Bit 2:GPIOA时钟使能(写1开启,写0关闭)& Q# a% G, U) m! y. u9 X+ [
Bit 0:辅助功能IO时钟使能(写1开启,写0关闭)/ v0 `1 y" z& ^8 P
; [' r/ l* b' h9 v
3.3.3 外部中断配置函数
" U* C& t  }7 g
/ ?/ Q3 V1 q" A" k. a0 U. R; N+ h' S' `3 E. K( N

  1. 8 v+ F3 }  l  C- G, o7 W& T
  2. /***************************************************
    - c/ S4 J+ U; ~* J9 _/ ^
  3. Name    :EXIT_Config
    + d  A# V- D' F( Q3 ^* j3 r& t
  4. Function  :外部中断配置7 L( X3 I% L4 q
  5. Parameter  :/ ~) w. O0 S: ?
  6.       GPIOx:0~6,代表GPIOA~G
    + R! ?) R8 [, e/ M* b$ p9 [  y
  7.       BITx:需要使能的位
    ' X1 E) ^1 f  I
  8.       TRIM:触发模式4 U4 X. }; Q/ q) s' O0 |, T- G
  9.         1:下升沿; q$ m! Z' ?. s1 g  Y% g5 ?7 p
  10.         2:上降沿
    2 \$ u: l, j4 f
  11.         3:任意电平触发
    9 S# [2 d& ~6 a: N3 {0 G5 V$ m; W
  12. Return    :None
    1 A8 [% k4 A0 N$ Y$ E' u
  13. ***************************************************/
    % H' O6 V9 ]5 R7 Q) U, z, L
  14. void EXIT_Config( u8 GPIOx, u8 BITx, u8 TRIM )
    * M0 ~: k/ k3 U, a" W$ _
  15. {
    $ p6 _& y* l8 s/ s. `  o: g
  16.   u8 EXTADDR ;, B/ e& B9 j* r% r3 S8 T- U9 ^
  17.   u8 EXTOFFSET ;- ]% ~0 y5 @4 ?1 I
  18.   EXTADDR = BITx/4 ;                      //得到中断寄存器组的编号
    . R% P3 w2 P7 d8 J0 R- `
  19.   EXTOFFSET = ( BITx%4 )*4 ;
    . d0 Q/ T) {& s! \4 |
  20.   RCC->APB2ENR |= 0x01 ;                    //使能io复用时钟       7 ~# X# @+ g& i# {. }$ ^
  21.   AFIO->EXTICR[ EXTADDR ] &= ~( 0x000F<<EXTOFFSET );      //清除原来设置
    * V' i$ S. l" Y3 {! I( u8 b8 T2 r
  22.   AFIO->EXTICR[ EXTADDR ] |= GPIOx<<EXTOFFSET ;        //EXTI.BITx映射到GPIOx.BITx* X1 i/ z: @# z
  23.   EXTI->IMR |= 1<<BITx ;                    //开启line BITx上的中断/ R' v1 n8 e4 x: {/ g4 e
  24.    if( TRIM&0x01 )  EXTI->FTSR |= 1<<BITx ;            //下降沿触发2 p% e8 W. |( m# P6 z
  25.   if( TRIM&0x02 )  EXTI->RTSR |= 1<<BITx ;            //上升降沿触发$ k' G% H  Y( j' h1 P+ [2 e
  26. }
    / ?9 q4 ~4 D8 q7 e9 n( ^
复制代码

: Y" b+ s% `2 {0 n2 t5 m- ?; L$ j' A0 }# ]3 ]
3.4 其他文件的添加
" j7 g  }& |5 e3 l3.4.1 寄存器定义文件
  K% t2 B4 ~1 P% M( y. X( S(1)添加用到的NVIC寄存器组和EXTI寄存器组的定义。/ k& C" O8 Y0 ?

4 [! ?2 Y" [8 u6 q$ |4 Z5 D7 P 12.png
; ~1 S6 G4 ?1 d) j(2)定义寄存器组地址
4 E0 j* R, H& T: n7 u 13.png 9 W. p$ r8 Y$ i/ Q$ G  s. P: O
3.4.2 sys.h文件
/ G; ?* j/ g( }8 V# `3 O 14.png ! B+ p7 F+ R( h) s, p3 }
上图就是添加子函数声明,为了用于其他文件调用。* F( V4 `+ ?! ~5 A# B1 E# ~
& }  i0 V: J4 }/ ?1 Q8 t) T
3.4.3 sys.c文件
' I$ l# o# p5 r2 U& M; h(1)在STM32时钟配置函数之前增加复位时钟和中断的功能,最终函数如下图所示。
/ l; k( ^  d1 @ 15.png
; f: {( q/ \# O) u+ _4 y% B) F(2)添加刚才的两个子函数
, M1 v+ B" l: D, X: `: @) v 16.png
3 ]* a* e1 z* F2 Y; G至此,sys文件里面最基础的函数就全部添加完毕了。9 v) Z1 i; @/ g& M# z: D9 K- Z
( q2 N3 ?0 B: V$ L! m
. x2 t* d! F" d2 X9 [5 B
上一篇:
" Y+ ?2 G9 g) f) q" a  @$ `STM32学习笔记02—时钟树架构
( X% ?! T4 d* B  p
$ R, t# ]% r& F; R% n
收藏 1 评论1 发布时间:2020-10-27 14:16

举报

1个回答
开发者 回答时间:2020-10-28 16:57:02

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版