找回密码
 注册
查看: 129|回复: 2
打印 上一主题 下一主题

Stm32中断优先级相关概念与使用笔记

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-8-1 09:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
一、基本概念! ?6 [0 i0 X6 G9 m
1ARM cortex_m3内核支持256个中断(16个内核+240外部)和可编程256级中断优先级的设置,与中断控制核中断优先级控制的寄存器(NVICSYStiCK等)属于cortex_m3内核的部分。STM32采用了cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。
# V- H4 E  d  W( z: h
) K9 l5 u# C, Y3 }( G
2STM32目前支持的中断共为84个(16个内核+68个外部),和16级可编程中断优先级的设置(仅使用中断优先级设置8Bit中的高4位,见后面解释)。《参考最新101xx-107xx STM32 Reference manual, RM0008》。
& a- _5 H/ i' W' H$ r' [; ?

9 U, n, y( |2 |) R; M$ m) ?6 Q
以下主要对外部中断进行说明。

) c8 r; ^, V1 k* _$ B

% X' o9 W/ O2 I6 t3 q
368个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是1732位的寄存器,它们是NVIC寄存器的一部分。

7 g; {# I5 e/ I

# C& p% \# I; t5 [3 w0 r
4.这4bit的中断优先级控制位还要分成2组看,从高位开始,前面的定义抢先式优先级,后面为子优先级。4bit的组合可以有以下几种形式:
6 z% L- e9 W3 I8 P* F8 U, c
5 T/ v' j" t# _' e. x$ H% v  `

1 Z" g" ]: v8 }
分配情况

  t. V7 n+ U( ^" M% w6 ^: y
. N! w  K/ T0 L& p

* S. q/ d; H! O7 l: U* ^
# `0 a2 A/ y% ~8 I# u
7

, l7 ~6 Y* s. ^

" d0 K! R! M3 [1 R
0:4

3 j. m$ l& O. b8 t" N

7 ?0 ]' y$ C8 u% n/ F  {- ~
无抢先式优先级,16个子优先级
, g. n; K9 ~+ L. G5 }1 r
; S) l5 e, N* ^
6
) Q6 M* _; R0 M4 G# M

+ S: B  q6 F; U" d& w1 ~
1:3

  A8 G7 s  D( Z2 z. C- r" u
% m! \0 L, y+ B" h2 Y. u
2个抢先式优先级,8个子优先级

) x6 N, E6 `& p; F9 r* |: C

2 T% \$ P# `: J/ k$ K
5
+ V; c1 w" H" j, U

. l& a& u+ j6 l1 }
2:2

4 \- C1 D4 y( ?' E% J5 L  i6 S
  O3 K4 ]$ l( M
4个抢先式优先级,4个子优先级
' o8 O2 [/ h4 S: n2 s" k

% ~' q/ w, F$ K! P% g; J' i
4
8 v& b8 ^- T. N$ ?& z" ?
. o$ F' t/ O/ [" W+ {
3:1
$ x7 D4 Z3 W; ^9 T$ {& w! L
) z6 q/ m4 @$ p. K
8个抢先式优先级,2个子优先级

+ C8 c! |! G( `; y
0 \5 c- K" b+ R: o2 @
3/2/1/0
) ?" [( Q1 f: ?. {* R. n7 L8 ?
  r0 v$ J1 P6 A) \0 c; W6 l! a, I% ~
4:0
* y8 V9 {& ^2 ^2 C. S* Q

' c# ?: K, c8 T% I$ H
16个抢先式优先级,无子优先级
* c& \, t) ^: d, X3 Z- D+ I, ~

2 S0 _0 ]5 }  l# X

% w; a, x3 X7 [/ ?* u) A
5.在一个系统中,通常只使用上面5种分配情况的一种,具体采用哪一种,需要在初始化时写入到一个32位寄存器AIRCApplication Interrupt and Reset Control Register)的第[10:这2个位中。这3bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。比如你将0x05(上表的编号)写到AIRC[10:中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。

& u. A$ H# X0 T/ X6 Y' S0 `  p, `: X

9 o  _) \; O, B$ C' P' B( \; L! W2 g
6AIRCPRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRCPRIGROUP,也就规定了当前系统中只能有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级,他们分别为:

2 G  i- M% l' p) V  H0 S% [3 ]
[7

' j! b. H6 F! y" N9 A5 p
3 B& Z# T) F5 L- y% C6 v
+ n5 e$ J0 n1 X% P0 t) B
[5

) R1 s0 m- c' ^1 @- w
2 P, U% H7 V, ]

7 P) `+ j# Z) ]

) V* _, U% J8 P  l
[3

3 t2 y- U3 A4 ?) H/ m0 j
. q" h! a- _0 y' [3 }% Y
00
% r' A5 c1 M' D$ F7 {  V

# F0 A0 K7 E3 G$ |6 }1 l# o
0号抢先优先级
9 R; Z2 S$ z* @$ i, ^$ \

1 O9 z  [, H/ J4 I- [; D
00

" {: t7 t- O/ c* q1 W' v
1 {7 P8 K6 Y$ f
0号子优先级
' f/ U( S( D9 u  \8 v/ Q1 k+ }+ ~& O
' @+ x; y$ y* k! c8 [) W
无效

+ H) S& N. f2 F; N, c+ k- m
1 y  T- G/ V1 d* A* o
01

5 X. ^* r1 p9 }: J4 P! W

: U$ t" c+ I9 k1 x
1号抢先优先级

& U) w; G! e7 k& ?( r! |9 k

5 Y, A. x* ?0 b, D' W
01

6 f& K# q0 l, [$ C
2 S1 r& B5 q% d! a' f
1号子优先级

6 y, ?0 Q& T( x, U2 L2 |( T2 A

; z/ r) V! Q5 Q# j7 x
无效
3 l5 A3 {; ]0 }" f( n

9 \7 o" A) ]6 |+ E8 v+ |
10
/ b  ?' H' U$ A2 q

4 C2 l; ^: }! D/ ^
2号抢先优先级

% `! f* w% m5 E% s+ @: ?
4 U4 r- \+ z3 P# F1 \
10
1 e% R2 ]0 u* |& D

: O4 l; ]' r; j: P- ?0 c
2号子优先级
# C6 k% I0 v) O& a. L3 X

/ m* A) D: a" b# n
无效

6 l) P- S% q) \" W! H
) h3 U  W. q  [8 t/ q) w% U; w& r
11
8 r7 z& }# v, J& Y, }* F' K3 Y
& K+ r5 r. q2 b4 @
3号抢先优先级
+ ^  n$ b1 ^5 C' N4 [  }; _

' D  k/ ^$ B/ V0 W& Q; G8 B
11
, o! X; y9 m% e/ j

3 M, h: y3 I3 j1 C) _2 t$ t9 z5 j
3号子优先级

5 u6 X! T3 F! o) q8 [' `
6 K5 t! j) Q3 q! ^6 w9 s  X& F
无效

- K( u/ T% l8 w& C8 t
* h6 R0 x$ j9 ~& g8 K% F- M; w3 d8 k
7.如果在你的系统中使用了TIME2(中断通道28)和EXTI0(中断通道6)两个中断,而TIME2中断必须优先响应,而且当系统在执行EXIT0中断服务时也必须打断(抢先、嵌套),就必须设置TIME2的抢先优先级比EXTI0的抢先优先级要高(数目小)。假定EXTI02号抢先优先级,那么TIME2就必须设置成01号抢先优先级。这些工作需要在AIRCPRIGROUP后进行设置。

2 s) V. T& k2 }5 }/ f$ Q/ Z, p. H

- r. E  o3 }: s1 q$ Y
8.具体优先级的确定和嵌套规则。ARM cortex_m3STM32)规定

  v  q  N+ k, i' I: \; ^3 @
a/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。

0 P( i# U" f! B+ V% V
b/ 2n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。
+ @/ k9 e8 g' o7 |' w" ^
c/ 2n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。
3 n* E  z5 f6 ^$ w2 A
具体一点:

( u+ Q6 {/ u  C
0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为234号的中断;…..构成中断嵌套。
" \; x8 R5 D& o* T% _
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。

" p: A5 M7 T# A3 N3 |" [- {: G

& {$ }! w/ S( U! l3 H$ P
9.上电RESET后,AIRCPRIGROUP[10:,因此此时系统使用16个抢先优先级,无子优先级。另外由于所有外部中断通道的优先级控制字PRI_n也都是0,所以根据上面的定义可以得出,此时68个外部中断通道的抢先优先级都是0号,没有子优先级的区分。故此时不会发生任何的中断嵌套行为,谁也不能打断当前正在执行的中断服务。当多个中断出现后,则看它们的中断向量地址:地址越低,中断级别越高,STM32优先响应。注意:此时内部中断的抢先优先级也都是0号,由于它们的中断向量地址比外部中断向量地址都低,所以它们的优先级比外部中断高,但如果此时正在执行一个外部中断服务,它们也必须排队等待,只是可以插队,当正在执行的中断完成后,它们可以优先得到执行。
3 z1 s3 l3 k2 ~0 b+ W

, l6 s; H5 c4 ?) }1 J2 `5 Q

) E0 X+ `% w: ?3 I, v3 V
了解以上基本概念还是不够的,还要了解具体中断的控制有那些途径,中断服务程序如何正确的编写。下面的描述主要以TIME2通道为例。

0 M1 p6 I; R- M3 S8 n4 M
$ B+ @9 v% i& @
二、中断控制
& Z' q( r& O7 P' {2 A$ N
1.对于STM32讲,外部中断通道位置2835号优先级)是给外部设备TIME2的,但TIME2本身能够引起中断的中断源或事件有好多个,比如更新事件(上溢/下溢)、输入捕获、输出匹配、DMA申请等。
/ C& n) o' s6 t
(题外话:就一个通用定时计数器,比8位控制器中TIME要复杂多了。学过AVR的,可能对输入捕获、输出匹配等还有概念,如果你学的标准架构的MCS-51,那么上手32位控制困难就更多了。所以我一直推荐学习8位应该认真从AVR开始,尽管51有很大的市场,价格也相对便宜些,但从发展的眼光,从后续掌握32位的使用,AVR是比较好的选择。)

/ K# X5 E# H3 n
7 s/ \8 }4 ]( `+ E0 n( `
   所有TIME2的中断事件都是通过一个TIME2的中断通道向STM32内核提出申请的,那么STM32中如何处理和控制TIME2和它众多的、不同的、中断申请呢?

0 d  b( Z. u5 k9 ~9 r
$ |" ?$ }# s3 `. I8 U# ~
2cortex_m3内核对于每一个外部中断通道都有相应的控制字和控制位,用于单独的和总的控制该中断通道。它们包括有:
+ }# X0 I2 a: G
中断优先级控制字:PRI_n(上面提到的)
+ f9 d! @: i3 s* `# X; W
中断允许设置位:在ISER寄存器中
) K, w0 M; I2 O3 c' H  N8 M
中断允许清除位:在ICER寄存器中
, S, [. C( l2 A" l; ^
中断悬挂Pending(排队等待)位置位:在ISPR寄存器中(类似于置中断通道标志位)

. f) T7 m* N9 o. H4 J) m( i$ ?) D
中断悬挂Pending(排队等待)位清除:在ICPR寄存器中(用于清除中断通道标志位)
7 X5 @* e* Z) E5 t
正在被服务的中断(Active)标志位:在IABR寄存器中,(只读,可以知道当前内核正在处理哪个中断通道)
" a4 Z' K8 q8 a

* X/ b' k  V" D/ B5 _9 r/ D& x
因此,与TIME2中断通道相关的,在NVIC中有13bits,它们是PRI_288 bits(只用高4);中断通道允许,中断通道清除(相当禁止),中断通道Pending置位(我的理解是中断请求发生了,但当前有其它中断服务在执行,你的中断级别又不能打断别人,所以Pending等待,这个应该由硬件置位的),中断Pending位清除(可以通过软件将本次中断请求且尚处在Pending状态,取消掉),正在被服务的中断(Active)标志位,各1bit

( |+ d9 ?' d: O4 C4 S) @
8 O( ]* g  P5 ]* U$ \: T
上面的控制字和控制位都是在NVIC中的寄存器组中,可惜的是在STM32中竟然不给出任何的解释和说明。

6 T  ]1 w, }5 z) J
# t. Y) j8 _2 I9 v$ O
3.作为外围设备TIME2本身也包括更具体的,管理自己不同中断的中断控制器(位),它们主要是各个不同类型中断的允许控制位,和各自相应中断标志位。(这个STM32的手册中有详细的说明了)

( c: Z/ m; l- b( Q+ h$ P: g

, ^( y- y4 ?) S* u. e, E
4.在弄清楚23两点的基础上,我们可以看看TIME2的中断过程,以及如何控制的了。

1 p# J5 b: A2 O' J9 c* t
- e8 y+ d. F5 q# s9 N  [4 N, ^
a/ 初始化过程
7 I) r8 W! m* b$ p& P& O1 r8 h$ O! K
设置AIRCPRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4bits中占用的位数)
: |  m% |7 u- _' K; B% P8 r
设置TIME2本身的寄存器,允许相应的中断,如允许UIETIME2_DIER的第[0]位)
$ r$ h: Z+ T4 s% [' t
设置TIME2中断通道的抢先优先级和子优先级(PRI_28,在NVIC寄存器组中)

, G7 p9 r# u' f2 F! u4 [
设置允许TIME2中断通道。在NVIC寄存器组的ISER寄存器中的一位。

$ |5 u0 ^& t% R' ?- F$ F
% J5 Z' W2 r4 D% H" t, \  M
b/ 中断响应过程
6 y3 _* e2 B  ^* Z- }
TIME2UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。
9 V) X" k/ E( f  U* V$ V
此时硬件将TIME2Pending标志置位,相当与中断通道标志置位,表示TIME2有中断申请。

. o3 y! z5 K! G7 L1 D: O7 _
如果当前有中断在处理,TIME2的中断级别不高,那么就保持Pending,当然软件可以通过写ICPR寄存器中相应的位把本次中断清除掉。

9 z8 P1 M2 M8 Y  h) `' }/ j9 U
当内核有空,开始响应TIME2的中断,进入TIME2的中断服务。此时硬件将IABR寄存器中相应的标志位置位,表示TIME2中断正在被处理。同时硬件清除TIME2Pending标志位。
! ^6 ^( `! M  i+ I" M! }" `6 A

. p* Z" }$ z7 ~% }/ c
c/ 执行TIME2的中断服务程序

, B% x0 G  |- t, j
所有TIME2的中断事件,都是在一个TIME2中断服务程序中完成的,所以进入中断程序后,中断程序需要首先判断是哪个TIME2的具体事件的中断,然后转移到相应的服务代码段去。
  {$ `5 p+ \6 p6 I) T
注意不要忘了把该具体中断事件的中断标志位清除掉,硬件是不会自动清除TIME2寄存器中具体的中断标志位的。
9 l# B( d8 y( n( [; t4 s

0 W2 C. W0 {: A4 @
d/ 中断返回

/ |% a4 D- O- Y9 X6 o8 A, ]; [; H
执行完中断服务后,中断返回过程,在这个过程中需要:

4 R1 _6 L% G# }% b: E' J
硬件将IABR寄存器中相应的标志位清另,表示该中断处理完成
) ~) @0 C* D" F
如果TIME2本身还有中断标志位置位,表示TIME2 还有中断在申请,则重新将TIME2Pending标志置为1,等待再次进入TIME2的中断服务。
7 `) x4 r2 i8 r8 k- Z! D

3 K2 z: V; W% y- ]; @7 k: A. y, A
注意:以上中断过程在《ARM Cortex-M3权威指南》中有详细描述,并配合时序图说明,可以参考。
% a; c/ s: l& O% B+ \. C

+ j# Z1 ~) n" T' i7 D
如果以上明白了,那么可以在ST提供的函数库的帮助下,正确的设置和使用STM32的中断系统了。
) {: d/ L1 b0 V

1 r4 [+ \- X& @; T$ O
如果你要了解更深入的东西,或者直接对寄存器操作,还要继续望下看。

/ H' k3 B& m9 b7 v# v" _. c; u
* [5 a5 ^( A# ?" e" ]7 G
三、深入NVIC
1 D% V. f& t, N( j  u8 w9 l/ Z8 Q% {
3 ?$ ~2 e8 \" y/ z: x5 L& O
1. 看看Cortex-M3中定义与NVIC相关的寄存器有那些

6 S2 {" F' o) r3 Y0 o/ x8 B5 j
SysTick     Control and Status Register         Read/write          0xE000E010
( O1 f& K. d. V, r
SysTick     Reload Value Register               Read/write         0xE000E014
4 _! Q# |6 f! G4 K! c; G: e% V
SysTick     Current Value Register              Read/write clear    0xE000E018
& U9 N% \0 U# n, D. D. X0 B# f
SysTick     Calibration Value Register          Read-only           0xE000E01C
) t  S* Y* W% @2 y8 X

: O' w2 V6 \2 H$ j' d2 h% e% E6 L- X4 [
Irq 0 to 31     Set Enable Register             Read/write          0xE000E100

9 G" }  J, j& f' a& K+ T. Z: j6 w5 n
. . . . .

, f) v. P# ^0 a" ]) O) ]8 O
Irq 224 to 239  Set Enable Register             Read/write          0xE000E11C

( k6 e  N$ K3 }
" h; q6 X  L6 d7 _: a" m" o' I- o4 d5 T$ Y) [; u, g5 K4 _
Irq 0 to 31     Clear Enable Register           Read/write          0xE000E180

* Q( g- D& Y2 w* @
. . . . .

0 q  D  P  c$ \  ~
Irq 224 to 239 Clear Enable Register           Read/write          0xE000E19C
" B) Y3 a/ A; t, W0 k

4 t6 \" ^6 t& j' S
* c$ X6 L* R' d9 u8 Y: i% T- e) }+ [9 y
Irq 0 to 31     Set Pending Register            Read/write          0xE000E200

2 U1 h; G  J' o, G5 s
. . . . .

/ T; ^* S2 O* T! _( O# K" D  ~- r
Irq 224 to 239  Set Pending Register            Read/write          0xE000E21C

' i! ^7 m! Y8 C- i4 f. F8 C
3 K& z% a" N, x& d  y  A' @" z5 J- T: o* n% z) ]& c4 H& s- ?
Irq 0 to 31     Clear Pending Register          Read/write          0xE000E280
/ q0 ~9 X$ v  D6 P
. . . . .

. V$ N3 A. o+ I8 X' G6 l
Irq 224 to 239  Clear Pending Register          Read/write          0xE000E29C

% R9 L, a9 N; \, t) C
9 L% G: C! F* c9 R8 L
( q. R# I5 O+ C2 W8 r# E
; d  R' f5 m% v  x# G" d- Q: x1 j6 k2 d) b( U2 k$ O, v& [
Irq 0 to 31     Active Bit Register             Read-only           0xE000E300

# l  E" l/ }: I  X* H
. . . . . .

! }  L. g' Q( w& b) L
Irq 224 to 239  Active Bit Register             Read-only           0xE000E31C
; N3 C3 ]3 N8 D% ^

6 q6 v8 |3 j9 _1 o9 p9 \6 I% x
  }8 ?; L1 P7 M5 @" F7 m9 C, R
Irq 0 to 3      Priority Register               Read/write          0xE000E400
6 m* M$ D. z& b9 \
. . . . .
8 u2 H1 a! M' `5 t2 j6 l
Irq 224 to 239  Priority Register               Read/write          0xE000E4EC

& A$ e& E7 M9 q8 ~, H& Q' i
0 {. o( _! \/ H; y; F' m) ^3 m% n5 ^. a
CPUID Base Register                             Read-only           0xE000ED00
8 g3 i5 A3 L* w6 c- t
Interrupt Control State Register        Read/write or read-only     0xE000ED04
0 @! N1 M' U  M- l
Vector Table Offset Register                    Read/write          0xE000ED08

1 e1 b2 ~& w- C3 \
Application Interrupt/Reset Control Register    Read/write          0xE000ED0C
) G4 B. ?9 x4 \8 ]
System Control Register                         Read/write          0xE000ED10
- I5 R1 U+ l( n2 V
Configuration Control Register                  Read/write          0xE000ED14
4 |- `% e* G* O% D5 d8 Z9 ]4 r+ k
System Handlers 4-7 Priority Register           Read/write          0xE000ED18
" N; e& q8 d) a! |6 X* H1 y
System Handlers 8-11 Priority Register          Read/write          0xE000ED1C
4 [+ s: M6 _+ U! E8 {9 z
System Handlers 12-15 Priority Register         Read/write          0xE000ED20

4 \5 m; u' A+ {
. . . . .
: ^4 \% a2 y  w! J  A- F9 U. {" P

0 N+ w- o# B9 `
2Stm32中用了那些
  q! b1 W7 c% k: W! q

, ~& _9 \% o* P; F( |- p
下面是从ST公司提供的函数库的头文件得到的,库是v3.1.0

0 r# v3 U2 M5 k* k
/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
9 @% H0 J2 u% E4 \2 @  N
typedef struct
; }! n" `# g' z. p2 J; z7 Z
{
6 u' ]3 w1 ?# ^
  __IO uint32_t ISER[8];                 /*!< Interrupt Set Enable Register            */

0 J. T, R* c2 l  W6 b# M/ [; K
       uint32_t RESERVED0[24];

+ F" f2 m" I2 t+ `% ^, x4 k1 A
  __IO uint32_t ICER[8];                 /*!< Interrupt Clear Enable Register          */

5 J. g! J5 t9 C0 I, Q
       uint32_t RSERVED1[24];
1 D$ o1 H5 D5 y% r% v
  __IO uint32_t ISPR[8];                 /*!< Interrupt Set Pending Register           */

$ S8 h& X' J# U2 S% N1 h* ^) ^
       uint32_t RESERVED2[24];
% R$ `+ B' Z/ H, U
  __IO uint32_t ICPR[8];                 /*!< Interrupt Clear Pending Register         */
' O7 q. H# k2 x# O8 i; H5 j
       uint32_t RESERVED3[24];
& M# Y, ]/ E- M
  __IO uint32_t IABR[8];                 /*!< Interrupt Active bit Register            */

2 Z; Y- h# X7 ^! X8 R2 J  p0 z
       uint32_t RESERVED4[56];

3 f& _' q  G" c0 n, Q; Q. e
  __IO uint8_t  IP[240];                 /*!< Interrupt Priority Register, 8Bit wide   */

1 P- [; V( P( a9 s0 c0 ^
       uint32_t RESERVED5[644];
* t$ o5 _$ q8 P) p
  __O  uint32_t STIR;                   /*!< Software trigger Interrupt Register      */
" J" b/ o# S2 b1 C, z5 v
}  NVIC_Type;
: s1 I6 n8 b4 r* P
: U( I6 J; I/ z8 g/ D, j
a/  寄存器ISERICERISPRICPRIABRSTM32中都使用的8个(实际3个就够了,后面的将来还要扩充?)。这些32位的寄存器中每一位对应了一个中断通道相应的标志。
. B" o8 r* z7 K# m! j. d
比如地址在0xE000E100的ISER[0]这个32位的寄存器,第0位是中断通道0的允许位,第2位是中断通道1的允许标志……32位是中断通道31的允许位;接下来地址在0xE000E104的ISER[1]则是中断通道32-63的允许位。ICERISPRICPRIABR的结构相同,只是含义不同。

6 |# d! Q! Z9 g5 n6 D' m3 E
, R- T2 N: L2 J0 o
注意是对这些寄存器的操作:写1表示置位或清除,写0无任何影响。
! W' L/ E7 v9 r$ O: @3 m4 g
# r7 O6 p  @3 T3 k& P8 G* x( |

5 @9 W4 N) J( K
例如:

* q9 G1 n( I* n) p$ k' ^+ f
对0xE000E100的ISER[0]的第0位写1,表示允许中断通道0中断;

7 V$ k& C. O5 X( V
但对0xE000E100的ISER[0]的第0位写0,则没有任何作用,该位保持不变。

# b/ r* X) U: U" c. i6 L
如果要禁止中断通道0的中断响应,那么就必须:

' ^/ w' K( {3 \" S) L2 n
对0xE000E180的ICER[0]的第0位写1,表示禁止中断通道0的中断;
' ~' O! d  q" w1 k! N: ^2 e
对0xE000E180的ICER[0]的第0位写0,也是不起任何作用的。

9 p" t! h; F7 Q" O0 K; H' K/ @- P; C+ u

( S2 ^. y2 N* f: n5 w! _
b/ IP[240]用于定义240个外部中断通道的优先级,每1个字节对应一个通道。4个通道的IP[]构成一个32位的寄存器。在STM32中最多有68个外部中断通道,每个IP[]1个字节中只使用高4位(见前面介绍)。IP[]的结构如下:
5 c, W: M) q. ~1 \1 R' y! i

) _3 v5 E) D6 f  s, b
2 ?+ E$ {7 p9 L4 `  y# k
, |9 i, Q0 U; f) o

9 B6 \& y9 c, {* E- W2 Q2 I* `( O
31:28

4 n  E1 S6 @' u
2 {" p) e9 D& _
27:24
8 Y$ M" j+ v; ]5 _

* {+ O- R! t) n% e8 A8 h4 W9 b; H
23:20

2 u0 L0 A7 g7 s/ h

4 v% w; l" Z  j- ]/ ]
19:16

  H9 M! b7 E, R/ Q
; k0 n2 U! d% u4 g* a+ ?4 l
15:12
3 g# B1 _* u4 O$ D! Y
+ v: ^  M3 |5 u
11:8
& ~* L# m/ R% U0 w  [: {% N0 r
1 o( s3 E/ S7 B! o" H
7:4

. |( p0 D6 O, {* H" g/ \
/ ^+ {6 P- p8 Q0 Y  Z# u9 j
3:0

8 f: h7 K' v& h6 o$ c2 k- a
* K& z; S6 v1 _' e, s# S+ ~2 @

0 V5 T$ O  `# f8 x" c$ |$ w" L4 f2 _, u3 [) W# F& N5 _8 K
E000E400
: a( j7 o' ]1 T' ~
4 q0 o8 N1 ]# h- z- O8 K
PIR_3

. g: p3 w) r6 a4 }$ W. v

$ d- l( X* N; Q2 `  }
PIR_2

$ B  N7 f  M5 A- `6 o

4 B, U' v5 c7 V- Q) r& F
PIR_1

+ z: M) {( o" u/ p8 s

8 Q4 N( \. K( ^  v7 I3 ?6 z
PIR_0

: R3 q. I( U2 N: g# r; C. G

) D6 q& I4 r# o, t% v/ F6 y% ]
每8位的高4位有效,灰色位表示无效
) C/ z" p) {2 L+ ]% y
& \0 t; Q" l- f- l, u
E000E404

- O6 h/ B$ y& `4 t

+ U9 ?, W/ a% H& b- a
PIR_7
. E8 P( d9 |- b% a- B' F
7 N1 G) l8 }+ y: n4 d
PIR_6

: I: c# x6 u# i/ a/ g

5 r+ h9 J( ~: B0 j* V. a
PIR_5
2 ^, C6 r) R! d+ L: `& Z

3 o) \; X; O% I. F4 Z% L4 ?- P8 e4 S
PIR_4
/ w( Q( \3 _  K+ y7 S

$ o0 j  X0 g9 c( r7 h
……

# W6 X, L! G, y+ o1 k
* D6 h$ P2 f6 e" J  ~
……
" @( C% Y3 ~+ J8 i+ J% R
' t4 F: ~1 w5 `  c2 Y9 r0 d
……
, T4 m, T+ p& A; g2 Z8 i

# U4 I7 J( x: x4 M! g/ k" S
……
; N) Z& A, `0 M/ y% X7 v5 R- w) d2 ]

0 F: M  M. a* N9 S9 F* v" Y" S
……
4 N# B0 {& z# X4 ]3 n
8 c2 R$ n" Y& z4 k% t
8 \9 h& i0 i/ w+ d# _% {1 d

8 w0 y( K; W" a0 o: Q" Q
c/ 在ST公司提供的函数库的头文件中另一个数据结构中,还有一个寄存器需要关注 :
' s. v; B& }' u/ z

8 z3 j3 P: P3 l" C: U5 h" J( }/ }. g$ [7 P8 f  W  H: [
/* memory mapping struct for System Control Block */

; T6 n, w7 \. b) K' u1 d
typedef struct
  k" ~% B2 a8 E/ z3 j1 T4 @- p
{

# {9 ^: a3 ]) j( b& ~. {9 ?
__I uint32_t CPUID;     /*!<CPU ID Base Register */
/ t5 ^; X  Q' D& h3 z1 @
__IO uint32_t ICSR;     /*!< Interrupt Control State Register */
' i- a3 j& B: d3 V& y
__IO uint32_t VTOR;     /*!< Vector Table Offset Register  */
3 g+ }; o5 i6 e  W! ^9 T
__IO uint32_t AIRCR;    /*!< Application Interrupt / Reset Control Register  */

- r( q+ V  f. ]
__IO uint32_t SCR;      /*!< System Control Register */
4 m# l3 |/ a2 _1 [9 t
__IO uint32_t CCR;      /*!< Configuration Control Register */

) ~2 x# f. [7 q/ w
__IO uint8_t  SHP[12];  /*!< System Handlers Priority Registers (4-7, 8-11, 12-15)*/
4 _  t6 O( K2 B2 [! c5 D4 X
__IO uint32_t SHCSR;    /*!< System Handler Control and State Register */
% g- g/ Y. u, d
__IO uint32_t CFSR;     /*!< Configurable Fault Status Register */
+ @1 h0 G/ @( d
__IO uint32_t HFSR;     /*!< Hard Fault Status Register */
8 N; k* u% T* j/ \+ S! K$ q: p
__IO uint32_t DFSR;     /*!< debug Fault Status Register */

' p. B/ K; Y+ M5 L' F
__IO uint32_t MMFAR;    /*!< Mem Manage Address Register */

& W; Z2 z4 O  G. @& B
__IO uint32_t BFAR;     /*!< Bus Fault Address Register  */
/ j- G. |3 ^  K3 q, Y- B
__IO uint32_t AFSR;     /*!< Auxiliary Fault Status Register */
& h9 N4 a, S' Q" M1 Q( p7 I
__I  uint32_t PFR[2];   /*!< Processor Feature Register  */
1 E2 W6 z, M2 l  r) j, b; i
__I  uint32_t DFR;      /*!< Debug Feature Register */
; K2 g3 g* {* Z/ a( h1 X  \
__I  uint32_t ADR;      /*!< Auxiliary Feature Register */
7 W/ \7 ~9 h. s: k
__I  uint32_t MMFR[4];  /*!< Memory Model Feature Register */

% P7 A) w5 u+ ^0 J
__I  uint32_t ISAR[5];  /*!< ISA Feature Register */

) e0 \& [  \" I1 }1 Q9 [
} SCB_Type;
2 \& X" s* E- n0 `- T- G

! B: P" O! b& p% Q# A$ ^8 \1 n* y' s' v
# x7 H$ y+ ^* [2 Q+ M
它就是地址在0xE000ED0C32位寄存器AIRCRApplication Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4bits,起可能的值如下(来自ST的函数库头文件中的定义)

! x; J- o. ?3 j) U" w

7 c- c6 d' i4 J5 v9 a
#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority

. Q$ W" k  f$ ?, X: a
                                                            4 bits for subpriority */

0 r) l7 |, l4 m/ G6 C0 s! b9 B! Z
#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
) L$ Y/ B) O7 w0 Q: C/ @
                                                            3 bits for subpriority */
" \4 {# Y: S4 H
#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority

" F  n$ q, C& g6 Q
                                                            2 bits for subpriority */

' L2 n' k9 ]/ u) N
#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority

. V. _; s5 S1 z+ Y0 Y
                                                            1 bits for subpriority */

; w1 N, N" z/ U  g' F
#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority

# K5 f$ F3 ^/ N# j8 h
                                                            0 bits for subpriority */
: e. G# T( g& N( B
% b2 ^4 ]$ Q$ i. H& f6 N( @8 t& z
1 m) g* T, b9 T. t
由于这个寄存器相当重要,所以为了防止误操作(写),因此要改写这个寄存器的内容时,必须同时向这个寄存器的高16位[31:16]写验证字(Register key) 0x05FA。
& a: R' G; B9 q$ |
9 [% ~0 |) Z7 q$ |% ]* g
, _- K- l# M# R2 `8 J" D  s
例如:SBC->AIRCR |= (0x05FA0000 || 0x300);    // 设置系统中断有16个抢先优先// 级,无子优先级
( N  N' o5 o* M2 q

  S/ ]3 |8 z- w9 A' O2 N. H4 y* h( S& v, {
) P, @! g1 f; N1 g5 \
d/ 下面的定义与SYSTICK相关,有时也会用到的。

0 y+ v4 N4 _/ C1 Q8 O- u4 q+ ]! F1 q* D
/* memory mapping struct for SysTick */
- m, k, t! i6 T8 Y/ v2 [
typedef struct

" W0 H6 q: ?/ Z# Q2 ?; Y
{
4 p5 m5 H) X# w! w; v; x* D9 O
  __IO uint32_t CTRL;       /*!< SysTick Control and Status Register */

3 g9 i* b9 o. p8 y) b( H
  __IO uint32_t LOAD;       /*!< SysTick Reload Value Register       */

2 }- g0 s8 }: J& u' Q5 r6 l3 J; E
  __IO uint32_t VAL;        /*!< SysTick Current Value Register      */
1 I4 _- j' T) ~( Q+ J$ h
  __I  uint32_t CALIB;      /*!< SysTick Calibration Register        */

+ p6 e) U5 o6 P: L! l% p! `$ P' f
} SysTick_Type;

$ r: L) b$ `3 W& z

该用户从未签到

2#
发表于 2022-8-1 10:48 | 只看该作者
在一起互相交流学习,共同进步

该用户从未签到

3#
发表于 2022-8-1 13:34 | 只看该作者
多多分享实际的例子、有实际用处的。看看,学习。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-6-3 04:50 , Processed in 0.125000 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表