找回密码
 注册
关于网站域名变更的通知
查看: 149|回复: 2
打印 上一主题 下一主题

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
一、基本概念
% K, Z1 ^7 Q* R2 [
1ARM cortex_m3内核支持256个中断(16个内核+240外部)和可编程256级中断优先级的设置,与中断控制核中断优先级控制的寄存器(NVICSYStiCK等)属于cortex_m3内核的部分。STM32采用了cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。
3 s5 S# z, w) B, \1 B2 X' s* X

& G, {+ v5 `# D8 l& O0 z1 J+ j
2STM32目前支持的中断共为84个(16个内核+68个外部),和16级可编程中断优先级的设置(仅使用中断优先级设置8Bit中的高4位,见后面解释)。《参考最新101xx-107xx STM32 Reference manual, RM0008》。

1 R  f9 V+ q/ U4 j3 g9 l" |& c

$ j3 h( ?+ b0 l3 Q/ y7 @0 c8 ^
以下主要对外部中断进行说明。
2 H! V# Q6 K- o3 _, w$ H; j% F$ e
8 f7 P- l/ @1 x/ _# I; Q
368个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是1732位的寄存器,它们是NVIC寄存器的一部分。

% _% K" F  p$ i5 W
1 o+ q" `5 E7 k5 W# o
4.这4bit的中断优先级控制位还要分成2组看,从高位开始,前面的定义抢先式优先级,后面为子优先级。4bit的组合可以有以下几种形式:
6 Y' n( J+ g. G1 }* z7 J' l$ [

. U) }9 a( \% z2 s) A+ ?" M
' [; y& C8 [. r+ W; E: C* \' F
分配情况

* q- t5 I4 W) g# b. Z
0 ]& G: @  o7 C$ U' c8 N  S
4 q& p1 B% {& q$ ~# w

( ~8 h% H# s4 b  ^, c8 u
7

% R4 [& n$ L9 ?1 n! w- n/ _
# Y* S  M- _5 V5 E
0:4
% X$ z6 ?  _& X9 `) h

7 \& b% r  h# T, J
无抢先式优先级,16个子优先级

" A( M! t" E: |% r4 c  M
- b8 b6 O/ F% a& @1 d0 ^1 g
6
- [( b2 {2 @* _1 E

- s# ~! F/ K& u9 H  L9 S- c  [0 f8 s
1:3
0 i, ~% _# D8 J; p

' n% j& N+ Q0 {+ m7 h2 N9 a" _* q
2个抢先式优先级,8个子优先级

1 r* @& h: v# V  J3 d

2 ?& _9 ?* G& r8 p; H) M
5

% K; N6 D$ A: a$ K

6 t9 C! U7 _, ]
2:2

% e. q/ _* V: \, S* X  K; ^
8 `, o: W9 o; J+ l  D4 Z
4个抢先式优先级,4个子优先级

) V5 V9 ]$ g: q' O3 J$ f$ x

" i% H) z; \1 G4 G7 y
4
3 t) T. D9 q" |# g: Q5 P
8 j7 P7 {7 ~7 c# X8 O
3:1

/ C# @: x9 }5 E! M9 ~
3 L# w3 q8 S9 [% y5 U
8个抢先式优先级,2个子优先级
2 j. Y! j% Z; X% _  d
2 G6 y! N% b1 W: a& f
3/2/1/0

; j+ m6 _! j8 B: u7 J
5 L8 L7 j) V# Q
4:0

/ b8 R1 V+ S4 V+ H6 U# c- Y  ]: [

. t6 h7 p7 P3 R9 ?5 T
16个抢先式优先级,无子优先级

1 b. Y& {) r  f4 h5 y! E" q

3 L( ]6 }; N& z8 J  W
! K) ]& T1 |# [8 F$ p! _
5.在一个系统中,通常只使用上面5种分配情况的一种,具体采用哪一种,需要在初始化时写入到一个32位寄存器AIRCApplication Interrupt and Reset Control Register)的第[10:这2个位中。这3bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。比如你将0x05(上表的编号)写到AIRC[10:中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。

6 j" H0 Y& {+ x

! u0 L1 W" e5 b4 z0 k4 J
6AIRCPRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRCPRIGROUP,也就规定了当前系统中只能有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级,他们分别为:
! O' Q% Q! J! {4 z& _
[7

0 M6 `# @9 n2 G, {: @& n) T/ h3 a, K

" a7 J8 S; c5 f$ e
. b2 v/ [0 F+ {1 p4 w
[5

) {& N4 h7 ^9 |3 f, e6 \% [
0 K! r0 l5 f1 X

" a4 G* ~( t3 d3 s. M

. N4 I/ ?! [( u1 z: A
[3

; L' r4 S. x7 @, H% \1 n
9 U% W7 l3 c- e
00
1 g; ]  h1 z7 s/ s3 k% X( k* O
/ k# N1 H$ N$ D' d3 E$ H' I
0号抢先优先级

5 _( z  j& u* q/ U
4 i8 v1 v7 ~- I+ i* X1 K/ I  z9 c
00
2 Y4 Q! s1 ?7 C

, ?  Y2 q. L. Q
0号子优先级

0 @* x# }; e9 Z8 Y

( ]+ u& ^* s, k
无效
9 c8 g" O# X. S5 C2 h: l* }

1 L9 \# E- s& {- H
01
- L' \+ L2 s2 V0 D4 }

( d1 G) b" V8 x0 |; B
1号抢先优先级
) N. n1 t- H; V" D$ o( e

9 I8 n1 ~0 V4 [
01

- d5 U0 a9 F2 `

3 O2 ]* n( K# R1 [9 s0 D8 T
1号子优先级

1 D7 ?  T1 ]" |8 t- S5 D3 i

  x6 ^$ j: s9 W$ t
无效
' W( B' L- Z9 N7 M" O7 c" |' U1 L9 [1 W

' _6 k% y# L; E, O  Z: T! }3 K
10

( c) Y# H" h3 e, x
4 ^$ \3 s3 \) c* r- H+ ]* m1 W- R
2号抢先优先级

5 Y) {8 K7 U, v% w
$ F" G/ T5 b4 i# Z. s
10
* y" M0 @" L1 l3 _: L) O7 Z
7 \5 A- W$ ^9 Z5 Z
2号子优先级

! s0 x% H& j+ _# b* ~
$ T6 \! ~6 E8 K0 f
无效
* |/ j3 a3 i- }4 k! L9 J

; z; @/ V8 H# K# e" a0 `& ]9 }
11

6 T9 r) x9 Q  S8 d0 w3 T1 p
' D/ z; C# N/ I  C3 ^4 @
3号抢先优先级

2 V; t; x) X' g  Z' r
! ], \$ W* J3 X
11

2 I9 c  U6 T( ]8 q5 ?, r3 R( ]3 I
4 C$ I# d0 G, G7 L6 f
3号子优先级
4 w3 v; [( R/ k

6 `( ]% H; H" Y. R. P8 ]$ `
无效
6 Z: J, Z0 J; u0 x+ R
% [' U' F% C9 t# b
7.如果在你的系统中使用了TIME2(中断通道28)和EXTI0(中断通道6)两个中断,而TIME2中断必须优先响应,而且当系统在执行EXIT0中断服务时也必须打断(抢先、嵌套),就必须设置TIME2的抢先优先级比EXTI0的抢先优先级要高(数目小)。假定EXTI02号抢先优先级,那么TIME2就必须设置成01号抢先优先级。这些工作需要在AIRCPRIGROUP后进行设置。

- H5 X% r; e6 A% G) b1 e
# t$ r& ^3 s: v' u* p/ F6 _
8.具体优先级的确定和嵌套规则。ARM cortex_m3STM32)规定
9 N) X, g+ S" }3 i. E  w# D# W
a/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。
* F# U, S/ g$ S6 t" P! q
b/ 2n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。

9 l  ~  {+ d* p$ _5 h9 ]! P6 w  Q
c/ 2n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。

$ q2 H( Z- g$ p3 p+ \8 W
具体一点:

! q9 E# D% V; r$ |9 H
0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为234号的中断;…..构成中断嵌套。
9 ~4 f4 k1 U. h6 r
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。
0 G! j. o% m- S: C, T
1 S: Z7 V* e% H3 A1 _+ s+ X* v2 ~" S; p
9.上电RESET后,AIRCPRIGROUP[10:,因此此时系统使用16个抢先优先级,无子优先级。另外由于所有外部中断通道的优先级控制字PRI_n也都是0,所以根据上面的定义可以得出,此时68个外部中断通道的抢先优先级都是0号,没有子优先级的区分。故此时不会发生任何的中断嵌套行为,谁也不能打断当前正在执行的中断服务。当多个中断出现后,则看它们的中断向量地址:地址越低,中断级别越高,STM32优先响应。注意:此时内部中断的抢先优先级也都是0号,由于它们的中断向量地址比外部中断向量地址都低,所以它们的优先级比外部中断高,但如果此时正在执行一个外部中断服务,它们也必须排队等待,只是可以插队,当正在执行的中断完成后,它们可以优先得到执行。
, a3 d# V/ K6 a' w, I0 b) E- ]
7 I1 b* ~- J  J' p

! q* n' c& L0 I2 Y; y4 @
了解以上基本概念还是不够的,还要了解具体中断的控制有那些途径,中断服务程序如何正确的编写。下面的描述主要以TIME2通道为例。

0 i4 C5 u7 j' q8 e
4 T: M# k! a+ m, z( S
二、中断控制
( S! U' u0 u3 ]! g! S! g
1.对于STM32讲,外部中断通道位置2835号优先级)是给外部设备TIME2的,但TIME2本身能够引起中断的中断源或事件有好多个,比如更新事件(上溢/下溢)、输入捕获、输出匹配、DMA申请等。
6 P" f9 N5 i- {' _5 z/ G5 `9 p/ ?+ V
(题外话:就一个通用定时计数器,比8位控制器中TIME要复杂多了。学过AVR的,可能对输入捕获、输出匹配等还有概念,如果你学的标准架构的MCS-51,那么上手32位控制困难就更多了。所以我一直推荐学习8位应该认真从AVR开始,尽管51有很大的市场,价格也相对便宜些,但从发展的眼光,从后续掌握32位的使用,AVR是比较好的选择。)
/ f! d* X8 N9 P+ B# ~1 M

  F! ?/ ]7 q- l% F! n1 W
   所有TIME2的中断事件都是通过一个TIME2的中断通道向STM32内核提出申请的,那么STM32中如何处理和控制TIME2和它众多的、不同的、中断申请呢?
' P0 W0 N1 ]1 a2 |9 D  ^, \0 b
& |# g, j% ]$ P( c
2cortex_m3内核对于每一个外部中断通道都有相应的控制字和控制位,用于单独的和总的控制该中断通道。它们包括有:
$ j! y4 N7 f& m+ I6 b1 r
中断优先级控制字:PRI_n(上面提到的)

/ r4 t& D1 O, e
中断允许设置位:在ISER寄存器中
# E' f% j* B% x( M5 |8 [+ s$ {
中断允许清除位:在ICER寄存器中

! m3 Q% S1 t' c% L1 C( y) c; p
中断悬挂Pending(排队等待)位置位:在ISPR寄存器中(类似于置中断通道标志位)
1 y" K7 n7 Y  s6 t* e( s
中断悬挂Pending(排队等待)位清除:在ICPR寄存器中(用于清除中断通道标志位)
: o' a  q* m- K( K
正在被服务的中断(Active)标志位:在IABR寄存器中,(只读,可以知道当前内核正在处理哪个中断通道)

* {3 U$ ]: Z; A' S
, ~* u  L2 x- R
因此,与TIME2中断通道相关的,在NVIC中有13bits,它们是PRI_288 bits(只用高4);中断通道允许,中断通道清除(相当禁止),中断通道Pending置位(我的理解是中断请求发生了,但当前有其它中断服务在执行,你的中断级别又不能打断别人,所以Pending等待,这个应该由硬件置位的),中断Pending位清除(可以通过软件将本次中断请求且尚处在Pending状态,取消掉),正在被服务的中断(Active)标志位,各1bit
& G/ u) [8 F7 N! c6 i  U( V
/ [/ B1 a. J* p! |
上面的控制字和控制位都是在NVIC中的寄存器组中,可惜的是在STM32中竟然不给出任何的解释和说明。
$ R, M7 q" f% X( H, O$ w, Q* l

3 H( _5 e6 T+ r( S! V
3.作为外围设备TIME2本身也包括更具体的,管理自己不同中断的中断控制器(位),它们主要是各个不同类型中断的允许控制位,和各自相应中断标志位。(这个STM32的手册中有详细的说明了)
" y. C) `4 t& z& H$ M  x
1 M* V8 L* S* |
4.在弄清楚23两点的基础上,我们可以看看TIME2的中断过程,以及如何控制的了。
8 ]  g/ @. J# h# v- x; C6 ^) s7 s
( W4 ]! m) m" J  ]0 _
a/ 初始化过程
4 e4 M, a+ k  m
设置AIRCPRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4bits中占用的位数)

1 H. P4 \$ S7 h
设置TIME2本身的寄存器,允许相应的中断,如允许UIETIME2_DIER的第[0]位)
& v' h" p8 Q3 t0 n
设置TIME2中断通道的抢先优先级和子优先级(PRI_28,在NVIC寄存器组中)
+ ^% {: p4 S0 j8 \. a0 F* p
设置允许TIME2中断通道。在NVIC寄存器组的ISER寄存器中的一位。

% G: A: M2 H+ M3 Z" K
  u& ?* |( V/ l3 L  s% `2 |- P; V; f" ]
b/ 中断响应过程

+ n. E  k* `! C7 a4 m- ]9 |
TIME2UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。
5 w4 R4 s! J4 E; U
此时硬件将TIME2Pending标志置位,相当与中断通道标志置位,表示TIME2有中断申请。

" C+ l2 l; k- S: A. S
如果当前有中断在处理,TIME2的中断级别不高,那么就保持Pending,当然软件可以通过写ICPR寄存器中相应的位把本次中断清除掉。
+ b$ e9 O( o. u) D0 U
当内核有空,开始响应TIME2的中断,进入TIME2的中断服务。此时硬件将IABR寄存器中相应的标志位置位,表示TIME2中断正在被处理。同时硬件清除TIME2Pending标志位。

7 w7 ]" y- C: v9 H: A. q
) V5 V7 J% a# d  Y0 m. ~/ y# E- e; Y
c/ 执行TIME2的中断服务程序

& o8 R0 `/ b0 Z  ]
所有TIME2的中断事件,都是在一个TIME2中断服务程序中完成的,所以进入中断程序后,中断程序需要首先判断是哪个TIME2的具体事件的中断,然后转移到相应的服务代码段去。
; r( I: f# X3 B; f
注意不要忘了把该具体中断事件的中断标志位清除掉,硬件是不会自动清除TIME2寄存器中具体的中断标志位的。
' i: }( C, j9 @, k$ p" n
/ h  g& K' J; l+ \3 u$ j2 |
d/ 中断返回

3 G- h4 `+ ^0 B+ d0 o
执行完中断服务后,中断返回过程,在这个过程中需要:

( S" h3 q( M: w' z% R
硬件将IABR寄存器中相应的标志位清另,表示该中断处理完成

( Z5 x+ D# X6 O2 {% ^0 m
如果TIME2本身还有中断标志位置位,表示TIME2 还有中断在申请,则重新将TIME2Pending标志置为1,等待再次进入TIME2的中断服务。
8 ^1 Z' p2 q. R" O5 [
) A& _' m  Q0 P! O- r# p6 A0 B
注意:以上中断过程在《ARM Cortex-M3权威指南》中有详细描述,并配合时序图说明,可以参考。

3 n; u7 O; F" h* f& B5 g8 J# u
, z( ^& Q" J: f7 U, Q9 w
如果以上明白了,那么可以在ST提供的函数库的帮助下,正确的设置和使用STM32的中断系统了。

$ E4 o4 D2 o$ r# _+ w! W* Q5 N
' E; m7 k4 k* h; x
如果你要了解更深入的东西,或者直接对寄存器操作,还要继续望下看。

; O# V* r! F' Y4 c0 C& d1 d, g' {
1 ^8 |9 I- W9 U2 u! x
三、深入NVIC
, `3 r: C* @8 m* C+ Y
# e0 F! S! Q: q* f
1. 看看Cortex-M3中定义与NVIC相关的寄存器有那些

4 E+ ^+ Z5 W2 w5 \
SysTick     Control and Status Register         Read/write          0xE000E010

& R0 y/ p/ N3 {. o0 S1 B
SysTick     Reload Value Register               Read/write         0xE000E014
1 `6 B* x# o: k% n$ o; w
SysTick     Current Value Register              Read/write clear    0xE000E018
, m2 _& p9 w% _# _1 Z& l
SysTick     Calibration Value Register          Read-only           0xE000E01C

* U) o. S) s& i/ {9 L( [0 w' M! M( m- E! H5 _  Z1 q6 T

& T7 ~0 V, Z, f/ J8 P; c
Irq 0 to 31     Set Enable Register             Read/write          0xE000E100
$ _' ]# S" a8 z9 r# V4 I
. . . . .
. D; Q2 i: P- K) V6 g
Irq 224 to 239  Set Enable Register             Read/write          0xE000E11C

* t( J4 t- ?$ O0 p3 d% u1 G
4 _" ~- y* _2 B6 y; S+ G3 w9 u  M
1 Z1 I" l+ I) }: m; s6 C
Irq 0 to 31     Clear Enable Register           Read/write          0xE000E180

" R2 a. [1 b& P) @
. . . . .
- {6 W$ i  {5 d2 U
Irq 224 to 239 Clear Enable Register           Read/write          0xE000E19C

% P6 E1 A) i7 ?* y6 n" [
7 T0 Q, h. x+ k* E+ v$ N/ n5 Y( j9 U5 H1 k& j6 s3 B$ s% y4 U
Irq 0 to 31     Set Pending Register            Read/write          0xE000E200

: ^+ f* i( u- s1 R2 t, j& Q! W0 M
. . . . .

! A/ A: c0 y, b# k  B
Irq 224 to 239  Set Pending Register            Read/write          0xE000E21C

/ h4 {6 d/ ?- v6 i; |( B$ u$ G5 V! Y. M% i$ h, Z! Y. I- U( O

7 h5 j5 i) b. ?$ r7 g
Irq 0 to 31     Clear Pending Register          Read/write          0xE000E280

2 W4 |1 E! A* O! _
. . . . .
' K' G& D) Q/ t# w: F6 v
Irq 224 to 239  Clear Pending Register          Read/write          0xE000E29C

/ @% u0 q8 B) _" u' i  A2 o
0 v7 R, q8 H9 b
* p& h9 z3 c1 Y8 P
7 V3 {, j6 l4 i( S- [( U" h. A, [
Irq 0 to 31     Active Bit Register             Read-only           0xE000E300

$ e8 W5 R, }- D' f4 ~
. . . . . .
/ \" D) N0 k1 S. Z) c( l
Irq 224 to 239  Active Bit Register             Read-only           0xE000E31C
0 V' G+ {) X+ j: l$ `; W
( t% @" ?  w% G: V7 g, T& t

" s8 O2 a. G0 z- _2 o" a% {* R3 {
Irq 0 to 3      Priority Register               Read/write          0xE000E400
6 i( R) m1 v) e  o! V, H
. . . . .
9 u  I7 r5 ]+ @! u7 {/ P
Irq 224 to 239  Priority Register               Read/write          0xE000E4EC
- H: e3 k' s2 O) D) v* v) e7 T# R6 @! E' Q

0 |& I: u) [6 M* Y) X
3 C8 x! v; _; i& y3 z7 b
CPUID Base Register                             Read-only           0xE000ED00
" x0 Y. ]9 h2 Z) t/ b
Interrupt Control State Register        Read/write or read-only     0xE000ED04
2 I; U. F- L9 f! g  c
Vector Table Offset Register                    Read/write          0xE000ED08

$ F, Y& `% M( B  O% X% |- A
Application Interrupt/Reset Control Register    Read/write          0xE000ED0C

$ a9 x7 \9 g/ D% F" ?) ?
System Control Register                         Read/write          0xE000ED10

* q; D* u. N% H% L. b
Configuration Control Register                  Read/write          0xE000ED14
" h: K% x7 l+ [, L2 G1 V/ g2 D2 S
System Handlers 4-7 Priority Register           Read/write          0xE000ED18

% z+ Y3 X. w9 s) h/ o+ N( U0 F
System Handlers 8-11 Priority Register          Read/write          0xE000ED1C
# [" Y9 s1 ~8 S* l
System Handlers 12-15 Priority Register         Read/write          0xE000ED20

& R) z4 |9 S+ _( `5 W4 v
. . . . .

! p5 q7 x; u" A
1 S5 K. J4 [; I' a8 L
2Stm32中用了那些
6 u4 ]- z+ J0 e+ P9 L5 f

# C- H6 \+ w$ I% G; N* P
下面是从ST公司提供的函数库的头文件得到的,库是v3.1.0

2 b& _# f  W( P$ K# |6 l) f
/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */

9 K' U; b: h5 }/ ]1 P2 A
typedef struct

0 C5 l! P+ C' |* M4 W- c
{

. Q2 R* x+ \8 |3 n! A2 Z) X' [
  __IO uint32_t ISER[8];                 /*!< Interrupt Set Enable Register            */

9 I+ H! e# B. e9 B6 D
       uint32_t RESERVED0[24];
: f' [0 z/ |& U- X: `- Q& p
  __IO uint32_t ICER[8];                 /*!< Interrupt Clear Enable Register          */

* V* |  _' r% a+ b
       uint32_t RSERVED1[24];
( l, F, Q0 N7 v
  __IO uint32_t ISPR[8];                 /*!< Interrupt Set Pending Register           */

) t, C8 C* `' _7 P1 t6 ~7 p
       uint32_t RESERVED2[24];
4 Z8 ]/ v* p# `: B- b
  __IO uint32_t ICPR[8];                 /*!< Interrupt Clear Pending Register         */

9 O7 F$ Y1 ~9 j0 i! c8 b
       uint32_t RESERVED3[24];
  _6 h7 t7 q( X5 c4 T
  __IO uint32_t IABR[8];                 /*!< Interrupt Active bit Register            */
5 D& ?1 H3 c2 Y/ _8 B! N
       uint32_t RESERVED4[56];
& X+ M; e: I4 X3 J2 S
  __IO uint8_t  IP[240];                 /*!< Interrupt Priority Register, 8Bit wide   */
3 C, n$ `. i; @: B) _* _# q$ L/ X
       uint32_t RESERVED5[644];

, w+ S# ]$ e0 X: a/ t: X
  __O  uint32_t STIR;                   /*!< Software trigger Interrupt Register      */
! _6 {$ {; X* L: |* D6 C! m: e
}  NVIC_Type;

: t3 o3 C! m  f' J7 k7 _6 J

- X% Q/ `- a) ]; z. Z
a/  寄存器ISERICERISPRICPRIABRSTM32中都使用的8个(实际3个就够了,后面的将来还要扩充?)。这些32位的寄存器中每一位对应了一个中断通道相应的标志。
! z" v8 N1 ~$ c! _; |2 g
比如地址在0xE000E100的ISER[0]这个32位的寄存器,第0位是中断通道0的允许位,第2位是中断通道1的允许标志……32位是中断通道31的允许位;接下来地址在0xE000E104的ISER[1]则是中断通道32-63的允许位。ICERISPRICPRIABR的结构相同,只是含义不同。
# w0 s- K& G5 T+ C9 h
0 h) J% R' D1 ~- o+ c
注意是对这些寄存器的操作:写1表示置位或清除,写0无任何影响。

2 N' P# a; E4 t" m8 S, }" N. B' z
" H- I/ m5 [( z( q% ]' u
例如:
9 Z# W1 v7 Z6 x, j
对0xE000E100的ISER[0]的第0位写1,表示允许中断通道0中断;

0 Z# b" u: V/ r! r  l$ G1 \# W% t
但对0xE000E100的ISER[0]的第0位写0,则没有任何作用,该位保持不变。
) T" o2 Y5 P0 t8 W' S+ x
如果要禁止中断通道0的中断响应,那么就必须:

5 F( A0 G+ v8 B. l2 D, S; h
对0xE000E180的ICER[0]的第0位写1,表示禁止中断通道0的中断;
: y1 u' z; @( a/ m. c
对0xE000E180的ICER[0]的第0位写0,也是不起任何作用的。
8 N' D, P7 p. V( F

' M+ d; v+ N5 ?! F; K" X+ C2 w9 B
4 o% U9 L8 S! D
b/ IP[240]用于定义240个外部中断通道的优先级,每1个字节对应一个通道。4个通道的IP[]构成一个32位的寄存器。在STM32中最多有68个外部中断通道,每个IP[]1个字节中只使用高4位(见前面介绍)。IP[]的结构如下:
2 Q  O& b" g( ?* E

( k; W) T6 y( f1 j
4 ~) \2 F7 {2 z

% U) b" {/ I8 h0 K1 ?9 Y
" P! P, B$ N# @
31:28

( H$ x2 |$ o  ~! Q5 p

# \4 [0 s- o& W
27:24
- D  X8 E2 |' s9 I) ~
9 r& b5 t8 x* A( c3 `* ]
23:20
. T3 O8 g) q% \+ ], A; n. l' Z

/ s0 M" B  z! p% R! N
19:16

0 v- t. I0 \0 i% m! G/ K

4 R7 C( W* x8 ?2 s2 v
15:12

7 d' x9 `! V, e2 I

0 w9 [6 F* y$ p" h# @0 r
11:8
- L0 P( c; ~0 t

8 x3 H( k6 A) b7 p* B$ `
7:4
7 [  N$ X) B/ H% b

, e  O- d. d7 ~6 [
3:0
- L5 l1 Z# B& E' \9 t( Y( R2 f

1 p# [6 W9 w; x8 l4 X1 L
& I# k9 O7 Y/ H6 V$ J, ^( y' Y
; p; |; n( W- ~# ^
E000E400

# `4 I4 G. n* E

( X  D. `1 c9 D1 `0 \/ k
PIR_3
; y" a; C9 O7 d1 _+ }$ e
$ R) D* F% d* o' ]2 s! s
PIR_2

9 z( o# w0 `% c0 l
& z" t# k2 M/ ?) Y7 R
PIR_1

! `  c: e5 n( }

( B/ T! \' u$ Q) h  O
PIR_0
' C& Q! |  e, ]0 @" X# G3 p

. q- x% @: ~7 K
每8位的高4位有效,灰色位表示无效
3 \+ P5 b% t6 ?$ q. T( b% u
$ \: H( `0 `! M1 @$ m8 P! Z+ @/ I. K
E000E404
2 V' V9 V0 g( R, [! x
* R2 \( }8 K8 K% A/ P
PIR_7
9 x) I# H' k) m3 w$ g
3 U3 p  ?' m' l& y9 n# N
PIR_6

- E2 r7 s8 B' ~& }$ ^: U) t; z8 l

& X7 v( A8 b# W
PIR_5

8 K$ I  G8 h# G" c1 ?* Q. E) D1 ]- S
6 L( `" V0 X1 K/ R/ k$ T" U. p
PIR_4
9 ]$ N( ?; ^3 S. b# S
/ t# }1 W, A5 C8 q( \( @: `: J
……
! f% ]+ Z" v2 J1 X
% z. ^9 i7 D) d/ L
……
5 J, M  j% C3 f

8 h: U7 k. m5 V' I2 Y
……

) d6 |4 t5 T) H/ N: }; D
2 b/ A: B" H9 e. N0 Z6 f1 o3 I8 n- h* V
……
% P" q% Z# i& u7 [3 ~
$ A! N3 ~4 g: g+ S
……

6 |4 _; [  x" O5 h# r
0 {" n0 _' ~' u' y

. k4 E# ]6 F- @0 n$ R: u! e. n
c/ 在ST公司提供的函数库的头文件中另一个数据结构中,还有一个寄存器需要关注 :

; Y1 G. S! F7 i8 W9 Q
3 j1 F: N" w% n! k( N  w! i. V: k+ K
/* memory mapping struct for System Control Block */
) x! N( ^! o* ~# X; [8 J" N) D% V
typedef struct
% _! b  n% s, E0 H4 x
{
% t3 _3 F0 r! _/ Q8 ?& J$ j
__I uint32_t CPUID;     /*!<CPU ID Base Register */

4 [9 U$ V9 y% x# P
__IO uint32_t ICSR;     /*!< Interrupt Control State Register */

) A7 P, f* F  W8 U
__IO uint32_t VTOR;     /*!< Vector Table Offset Register  */
4 Y9 V  y2 \% c" \& S, c) R
__IO uint32_t AIRCR;    /*!< Application Interrupt / Reset Control Register  */

9 n3 c* H1 a! T7 i, }1 _/ ~
__IO uint32_t SCR;      /*!< System Control Register */

$ V. ^, G$ u. a. Z
__IO uint32_t CCR;      /*!< Configuration Control Register */

# G& g- A5 e2 f" I- Y% X1 I# Y4 ?
__IO uint8_t  SHP[12];  /*!< System Handlers Priority Registers (4-7, 8-11, 12-15)*/
: i# Z* h7 @$ s6 @
__IO uint32_t SHCSR;    /*!< System Handler Control and State Register */
* U5 c& c  r4 p
__IO uint32_t CFSR;     /*!< Configurable Fault Status Register */

8 U2 ]2 f) h* I; b
__IO uint32_t HFSR;     /*!< Hard Fault Status Register */

- h9 u$ W- {# G; m0 p$ H
__IO uint32_t DFSR;     /*!< debug Fault Status Register */
3 d$ t) f4 Y8 E& L
__IO uint32_t MMFAR;    /*!< Mem Manage Address Register */

. \! E( K& N$ z& f7 M
__IO uint32_t BFAR;     /*!< Bus Fault Address Register  */
, f$ v0 A' S0 D+ [/ g! }) `
__IO uint32_t AFSR;     /*!< Auxiliary Fault Status Register */

2 f6 x! ~6 Z6 u+ c6 g! u0 _
__I  uint32_t PFR[2];   /*!< Processor Feature Register  */

6 A( R8 i& c$ @- v8 s) q( Q
__I  uint32_t DFR;      /*!< Debug Feature Register */
4 N" G' R) S  v# {: B  J
__I  uint32_t ADR;      /*!< Auxiliary Feature Register */
+ `) Q$ p  z& a/ v. E
__I  uint32_t MMFR[4];  /*!< Memory Model Feature Register */
: Q4 i* w- v5 f4 V
__I  uint32_t ISAR[5];  /*!< ISA Feature Register */
, a; G" e4 p/ t5 Z8 e# m* K. r
} SCB_Type;
( B$ V5 L# B( |! `9 E# D
. h. r6 s1 {3 _

8 P1 ~; b  N! Y) M
它就是地址在0xE000ED0C32位寄存器AIRCRApplication Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4bits,起可能的值如下(来自ST的函数库头文件中的定义)
6 y. ^/ ?: t* t3 {0 T. q" Y

# ]0 a/ o: q* X
#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
% P1 Y$ t7 K: X& r, E
                                                            4 bits for subpriority */
- ~. |7 {# Z2 O- |
#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority

8 Y8 \5 P. ]0 m7 {. c# z4 w/ {& `
                                                            3 bits for subpriority */

' a3 V0 q- x* F; N
#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority

! j/ L+ @  {4 B4 l( `2 G! A
                                                            2 bits for subpriority */

: {4 ^- {5 g$ F3 w  b  V; z. J& [
#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
' h  M" n+ O9 i. |
                                                            1 bits for subpriority */

) p3 B# E+ e: V+ m1 ?% h6 ?
#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority

- [& p. E0 Y; @9 ~& T+ @3 ~7 [2 I( }
                                                            0 bits for subpriority */

+ }  V: |& w6 c, Z' T4 _/ ^6 O/ v2 D" T' N5 Z  S
- c- |( O1 }" F1 h
由于这个寄存器相当重要,所以为了防止误操作(写),因此要改写这个寄存器的内容时,必须同时向这个寄存器的高16位[31:16]写验证字(Register key) 0x05FA。

( p" g; O* A. D# y: O. O' q. }2 Q0 Z* Q" @( e: ~7 n1 |( F4 T& U3 i
3 x# h, ~7 N  A3 }. a) C4 e6 U
例如:SBC->AIRCR |= (0x05FA0000 || 0x300);    // 设置系统中断有16个抢先优先// 级,无子优先级

6 g. T5 y! T! x. _$ V1 W7 x
( P: M2 P" b4 ^' O
1 E, [3 N$ e1 l3 C0 w

4 M: ?# X! U# ^# u
d/ 下面的定义与SYSTICK相关,有时也会用到的。
! T$ S0 J0 q3 k) S7 g9 K9 L
/* memory mapping struct for SysTick */
3 ]6 o6 [6 x% E" Z5 g( o3 ^
typedef struct
6 d$ T5 d( J/ m( i0 `7 u
{

3 p- U9 x/ w, [+ F0 v
  __IO uint32_t CTRL;       /*!< SysTick Control and Status Register */
6 ?- d( \. ?. q0 e
  __IO uint32_t LOAD;       /*!< SysTick Reload Value Register       */
# E. Q$ ?4 r. ^( H4 i" m
  __IO uint32_t VAL;        /*!< SysTick Current Value Register      */
1 a7 ]3 F7 |7 i( u# P; R9 S: z
  __I  uint32_t CALIB;      /*!< SysTick Calibration Register        */

; i4 W; c5 p/ P
} SysTick_Type;

- G1 B. x# {" n+ `; E5 d) v8 {; E

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-30 20:41 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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