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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
一、基本概念
, v1 U9 M. h0 P, [
1ARM cortex_m3内核支持256个中断(16个内核+240外部)和可编程256级中断优先级的设置,与中断控制核中断优先级控制的寄存器(NVICSYStiCK等)属于cortex_m3内核的部分。STM32采用了cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。

$ I7 f  U4 g9 j2 Z! m

$ _% e. N3 J2 h% w& Y# j
2STM32目前支持的中断共为84个(16个内核+68个外部),和16级可编程中断优先级的设置(仅使用中断优先级设置8Bit中的高4位,见后面解释)。《参考最新101xx-107xx STM32 Reference manual, RM0008》。

( \8 |2 T! C9 X& n8 i( v
/ J5 c+ ^' f4 h% k3 J" V+ H
以下主要对外部中断进行说明。
; k# M% M& L  u6 V
% W# d5 I, G) i# q5 [5 s  q' I2 p* D
368个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是1732位的寄存器,它们是NVIC寄存器的一部分。
2 w: f5 _. q4 H# k6 M9 O
: s. v+ T& B/ m, s- }- z
4.这4bit的中断优先级控制位还要分成2组看,从高位开始,前面的定义抢先式优先级,后面为子优先级。4bit的组合可以有以下几种形式:
, D2 }, {1 ?( D# o4 N, k
% ~! `7 l. w; F+ |8 k
+ H- g1 U) M7 _+ `+ |
分配情况
# P2 F3 D) j: Z+ p
# P) \+ g' z! h( y3 @# b
  c' s6 F# W# E* Y# p. L/ X  S/ v

# \4 d0 F( d& a3 B) ], d
7
0 e1 q% _' E4 _4 Y, L! Z
& ~# U$ g2 i& e
0:4
9 o$ B6 j! M/ [4 X

5 ~8 x" I9 k/ @; o4 U. `: D
无抢先式优先级,16个子优先级
( t* X" k8 O. M8 s

( R  S" L6 N% _5 f
6
0 ^* p" x9 g! p2 A5 F

( T- s$ x6 [; w$ l/ s* i
1:3

  x+ V/ @- o* [) S* E

; w' M- }7 U8 v/ N8 A: ^5 S
2个抢先式优先级,8个子优先级

$ L5 o% p& K) O+ d! v
) V# _' p5 G1 q2 E9 d% a( L
5
  F. C* ^% ]+ \

4 }: t: y& u/ X: R4 A8 b
2:2
, E# d/ c8 f6 H0 k; A' y

% A( ~# {/ H" ]1 L
4个抢先式优先级,4个子优先级
7 d7 c; A- e, Y
8 C. H* V* R$ V$ b# F! C) J. T" G
4

2 {* X9 Y$ P8 k+ |0 A* k
' `' k  W0 u! M( I) `# u. r
3:1
' K; l7 n, S) I2 f7 D8 z

5 a4 R9 S6 A9 l. o1 R/ |$ }
8个抢先式优先级,2个子优先级

9 ?# W& ^- \) K0 |, ?7 j
2 k" ^" Z; f2 S# v$ s
3/2/1/0

7 t* w; k: j" r% g0 Q- j* }

$ k- j6 p9 b7 a8 ]; z9 Z
4:0
0 S" M$ a% K" d9 K  w- m: E1 ?
  o. L$ @$ w7 t* |$ L# T' B9 E
16个抢先式优先级,无子优先级

7 d+ P! l% h, ?  d9 a) b* G

+ E8 I3 t+ a3 H) ]+ S2 k  P6 Y
" f, K( p6 n6 D, j7 ~1 |6 W5 _" x
5.在一个系统中,通常只使用上面5种分配情况的一种,具体采用哪一种,需要在初始化时写入到一个32位寄存器AIRCApplication Interrupt and Reset Control Register)的第[10:这2个位中。这3bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。比如你将0x05(上表的编号)写到AIRC[10:中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。
* ~0 d5 P- Y+ K& {! P8 }

( t9 U" Q0 L8 n- C1 [" f( [* Q
6AIRCPRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRCPRIGROUP,也就规定了当前系统中只能有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级,他们分别为:
5 t/ H, [/ Z$ g0 A3 m
[7
4 K3 ?1 p- e/ R2 W' ?' a3 l
1 O$ N& E8 I3 R$ A+ B! @8 Q! Z& r

+ y% H: v) ?6 O% @; n+ ^1 r* [
[5

/ C3 C! u8 X  T; w* V) O
8 T, \* J5 @5 g3 _2 y

) f6 R7 z8 y; R5 |* Q) N
  b# J* k& l' Z2 M* X0 ~6 J5 ^" t7 G
[3
2 a+ C. [: L3 F
# Q0 @  T2 o, [3 m
00
4 R0 }6 V. E% \# z
0 E5 ^1 k: m6 L1 H5 h
0号抢先优先级
3 k# _0 S+ M9 q. O* O* m. v) b+ s
$ D5 [2 H- p, v' `" D$ Q' `
00

: D7 ?; |+ e+ q& r! h9 O

+ g& f+ R# M! r" F, e
0号子优先级

9 M! Y! g6 |, y4 H, R' w  s' O; r

1 l* P5 T! K( L  F9 C* T
无效

" M& ]/ |1 v- u: @7 w5 n% g
' z9 U, y2 Z2 o5 x4 p$ G
01
. T7 K6 M9 ?( E" z
# V' j/ B3 @. V' G9 f) w1 f2 h
1号抢先优先级
% |/ l9 y8 X$ v1 n9 z1 f7 B

2 t0 q2 f1 b" ^+ b4 F
01
9 E- I" u. S; Y6 L
3 a( l5 p: D$ m  B5 I( D9 k- }7 k
1号子优先级

; w4 Q* A: d8 N5 y7 n/ K# Z7 g
  X. q* w  V3 h% z* {: r* I0 V+ K
无效

. q. ^: Q% }3 c+ O& B( `0 ]; n$ B$ g. C

4 t! @* d; x4 T, ^3 y' H- y6 y$ W- R
10
9 c) o8 i( c/ }2 ]$ Z
! k) a5 u/ o8 s
2号抢先优先级
) O% b% b5 m1 U' F) \7 p; M

0 `- F/ ]4 G& [- G7 ~8 {3 [7 w
10

: M. E/ `: v& L! o: ~( \

- Q3 M2 ?6 d9 `& T
2号子优先级

' T* a' E' t0 `4 T" _

( b4 Q% A% p2 ^- `
无效

" a4 x2 ?! p( y, ?

2 P  v1 p8 z& l! a8 t$ s. A$ P
11

* n" g# M/ C7 ]! x3 @
! p# i5 n# p& |
3号抢先优先级

+ b* W+ f) ~1 g$ h8 w
* E& v9 I. f" G0 T
11

/ U& t- q( M$ \* g  z" e
) r5 i. Y/ M' q) w2 b
3号子优先级
# g4 ?( J$ l$ Q" i7 Z* _/ V2 q

% H& j( P6 E8 `% `
无效

" p) O4 c# F1 ~% r* c: J0 @' S

, S3 S3 u% W( q6 b
7.如果在你的系统中使用了TIME2(中断通道28)和EXTI0(中断通道6)两个中断,而TIME2中断必须优先响应,而且当系统在执行EXIT0中断服务时也必须打断(抢先、嵌套),就必须设置TIME2的抢先优先级比EXTI0的抢先优先级要高(数目小)。假定EXTI02号抢先优先级,那么TIME2就必须设置成01号抢先优先级。这些工作需要在AIRCPRIGROUP后进行设置。

) ^% B! U! r* `- `" [5 `
2 V0 G& D: ?* k0 o! `, C) ]
8.具体优先级的确定和嵌套规则。ARM cortex_m3STM32)规定

# r& g7 n: Y6 ~' O: T
a/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。
9 ~, Q3 u4 W. @6 m0 P; C# \
b/ 2n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。

/ R. W: ~) J( p/ E5 z( L$ @& C
c/ 2n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。

6 c* r) v, K( K1 B) w8 z6 k
具体一点:

9 ~7 W$ S5 N% N8 j  a4 ^( \' Q; c
0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为234号的中断;…..构成中断嵌套。
$ l6 j7 A/ M7 }3 {' Q
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。
  n* [5 E; x. Q! C: Q

9 a$ H4 G( i9 z* p/ N9 y6 c- z
9.上电RESET后,AIRCPRIGROUP[10:,因此此时系统使用16个抢先优先级,无子优先级。另外由于所有外部中断通道的优先级控制字PRI_n也都是0,所以根据上面的定义可以得出,此时68个外部中断通道的抢先优先级都是0号,没有子优先级的区分。故此时不会发生任何的中断嵌套行为,谁也不能打断当前正在执行的中断服务。当多个中断出现后,则看它们的中断向量地址:地址越低,中断级别越高,STM32优先响应。注意:此时内部中断的抢先优先级也都是0号,由于它们的中断向量地址比外部中断向量地址都低,所以它们的优先级比外部中断高,但如果此时正在执行一个外部中断服务,它们也必须排队等待,只是可以插队,当正在执行的中断完成后,它们可以优先得到执行。
. z$ Q& ]9 p3 k# M

: _  x, q0 o7 y7 J8 @2 w9 m# w
/ W# _  E- @" f1 {! U9 `* s
了解以上基本概念还是不够的,还要了解具体中断的控制有那些途径,中断服务程序如何正确的编写。下面的描述主要以TIME2通道为例。

: e- r$ U/ l, d; ~+ k/ G
- ^" }$ H+ B! @$ e( Y, [
二、中断控制

5 J% M5 j, K/ E% ]
1.对于STM32讲,外部中断通道位置2835号优先级)是给外部设备TIME2的,但TIME2本身能够引起中断的中断源或事件有好多个,比如更新事件(上溢/下溢)、输入捕获、输出匹配、DMA申请等。
- u5 z( v6 D/ ?* t/ a
(题外话:就一个通用定时计数器,比8位控制器中TIME要复杂多了。学过AVR的,可能对输入捕获、输出匹配等还有概念,如果你学的标准架构的MCS-51,那么上手32位控制困难就更多了。所以我一直推荐学习8位应该认真从AVR开始,尽管51有很大的市场,价格也相对便宜些,但从发展的眼光,从后续掌握32位的使用,AVR是比较好的选择。)
' ^. A& r9 I% G: ]# Z
; L4 ]8 _8 Y+ E- X* f) n4 @
   所有TIME2的中断事件都是通过一个TIME2的中断通道向STM32内核提出申请的,那么STM32中如何处理和控制TIME2和它众多的、不同的、中断申请呢?
9 \3 c. x# l" V- n# r# j

# C! t; c% m/ @8 z: W% ^9 p# ?) [
2cortex_m3内核对于每一个外部中断通道都有相应的控制字和控制位,用于单独的和总的控制该中断通道。它们包括有:

3 ]$ ~# \2 L* P: g6 W  m0 r
中断优先级控制字:PRI_n(上面提到的)
, `& c3 p" r' h: r7 Y
中断允许设置位:在ISER寄存器中

7 E# b  u# E4 h9 w: Q/ }( w
中断允许清除位:在ICER寄存器中

: l; L0 G; Y& c! @  z' ~* l4 A- T  |
中断悬挂Pending(排队等待)位置位:在ISPR寄存器中(类似于置中断通道标志位)
7 K2 }6 H! i+ x+ u; Y) l" i$ O
中断悬挂Pending(排队等待)位清除:在ICPR寄存器中(用于清除中断通道标志位)
* L- l( `9 V$ d) `3 [, m. B
正在被服务的中断(Active)标志位:在IABR寄存器中,(只读,可以知道当前内核正在处理哪个中断通道)
8 C/ E) e6 k+ ?1 r( m/ V& }( t

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

! t: }& z5 G+ b* F
, }& ^0 w* A4 ]7 f* ~
上面的控制字和控制位都是在NVIC中的寄存器组中,可惜的是在STM32中竟然不给出任何的解释和说明。

8 h; e) l7 h& P" U

  u" s! x0 g1 w. w0 a
3.作为外围设备TIME2本身也包括更具体的,管理自己不同中断的中断控制器(位),它们主要是各个不同类型中断的允许控制位,和各自相应中断标志位。(这个STM32的手册中有详细的说明了)
/ n  @0 h. x( `' y/ Y

) f' g% n! K" T5 }, c! V* f
4.在弄清楚23两点的基础上,我们可以看看TIME2的中断过程,以及如何控制的了。
; e4 `' R" ~, v9 _' `

! h. i' u- }9 C( `7 T1 f1 b: ^
a/ 初始化过程

  ^$ A' S! _6 q2 y: r
设置AIRCPRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4bits中占用的位数)
$ W: }6 S6 p) |  g
设置TIME2本身的寄存器,允许相应的中断,如允许UIETIME2_DIER的第[0]位)
3 r: e' }5 Y0 ]! C, K/ f/ {& U8 m& l, B
设置TIME2中断通道的抢先优先级和子优先级(PRI_28,在NVIC寄存器组中)

: b( g: \* m  l7 q
设置允许TIME2中断通道。在NVIC寄存器组的ISER寄存器中的一位。
4 ?6 F! d1 |8 Y* s  d  a" {
8 t8 ~' }9 r+ r
b/ 中断响应过程

; n5 M: {% L: [$ @2 P9 O, j) m+ v
TIME2UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。
1 _8 W& n; ]( ~
此时硬件将TIME2Pending标志置位,相当与中断通道标志置位,表示TIME2有中断申请。
0 f8 {- r; ]* k3 D5 I
如果当前有中断在处理,TIME2的中断级别不高,那么就保持Pending,当然软件可以通过写ICPR寄存器中相应的位把本次中断清除掉。

  Y1 l6 r3 h$ s
当内核有空,开始响应TIME2的中断,进入TIME2的中断服务。此时硬件将IABR寄存器中相应的标志位置位,表示TIME2中断正在被处理。同时硬件清除TIME2Pending标志位。

1 [1 O+ L. m7 g( L; S% V  b

+ b, L5 f/ p+ K1 w# P3 `+ `' `
c/ 执行TIME2的中断服务程序
4 F: {5 L7 I; p' s+ g
所有TIME2的中断事件,都是在一个TIME2中断服务程序中完成的,所以进入中断程序后,中断程序需要首先判断是哪个TIME2的具体事件的中断,然后转移到相应的服务代码段去。

; ^) ]$ ?, x4 B* M/ Y
注意不要忘了把该具体中断事件的中断标志位清除掉,硬件是不会自动清除TIME2寄存器中具体的中断标志位的。

9 c: t. W: [! x- t
+ x; `# k8 J+ ~/ z
d/ 中断返回

' c: @" I8 b% X- T" E% n- c1 g) U
执行完中断服务后,中断返回过程,在这个过程中需要:

% q( ~+ ]4 O2 U7 R: X
硬件将IABR寄存器中相应的标志位清另,表示该中断处理完成
6 H7 n: ]1 w' a/ e/ B6 x, q; U
如果TIME2本身还有中断标志位置位,表示TIME2 还有中断在申请,则重新将TIME2Pending标志置为1,等待再次进入TIME2的中断服务。

, O' K) K8 B% I3 K) O) V
. q7 P6 L- z% Y9 Q2 h* J" D
注意:以上中断过程在《ARM Cortex-M3权威指南》中有详细描述,并配合时序图说明,可以参考。
  X7 q- X7 g" u& g
: o. v- v5 I8 R# l* j- g# N
如果以上明白了,那么可以在ST提供的函数库的帮助下,正确的设置和使用STM32的中断系统了。

/ o2 [2 ^' A' R9 p6 H% d$ q
3 ~( r9 W: _- U" g2 u: t
如果你要了解更深入的东西,或者直接对寄存器操作,还要继续望下看。

+ {3 r+ L4 }6 i' B+ ^8 c9 ~
( j5 z+ U" k3 q
三、深入NVIC

5 C) @1 M$ e0 k9 K! n
4 |$ y: ~9 W* d4 h3 g
1. 看看Cortex-M3中定义与NVIC相关的寄存器有那些

% o/ U5 }! O2 v. Z6 \+ x6 x
SysTick     Control and Status Register         Read/write          0xE000E010

! u- _* K& O6 G/ {! s
SysTick     Reload Value Register               Read/write         0xE000E014

) C& p( c! }( a3 R
SysTick     Current Value Register              Read/write clear    0xE000E018

* [5 f% g9 `# a  Y1 Y* S
SysTick     Calibration Value Register          Read-only           0xE000E01C

2 Y  ~5 r+ k% ^3 c. w+ U* O" ]* ]0 l6 w2 B

9 G- d( T' N+ l: I/ P: J
Irq 0 to 31     Set Enable Register             Read/write          0xE000E100

& `( V! y7 [; G3 Z
. . . . .
6 x( K2 `6 [: x! G* U
Irq 224 to 239  Set Enable Register             Read/write          0xE000E11C

+ j& H0 R* J* T2 |: g$ [% f) v& F% C, E  h( K8 J

; L3 ~3 y" _7 R8 n6 i( O/ ?. r: F
Irq 0 to 31     Clear Enable Register           Read/write          0xE000E180
5 v' r7 M5 ~5 g' O3 |. a
. . . . .

9 e; Z( }7 u9 i. n% R* d
Irq 224 to 239 Clear Enable Register           Read/write          0xE000E19C

- T( n+ ], }) A+ S- M
0 R3 g2 J" Z  x/ ?& ]1 q+ t2 E' [# C# U
Irq 0 to 31     Set Pending Register            Read/write          0xE000E200
) ~' q2 j% h/ d7 h/ ?
. . . . .

7 {0 f3 w6 g7 U
Irq 224 to 239  Set Pending Register            Read/write          0xE000E21C
. y) o8 u7 Y: h2 i9 {, s
( [. Q* _% i% N- u/ e  b& s

2 e8 U& A* M3 H) [- I
Irq 0 to 31     Clear Pending Register          Read/write          0xE000E280

5 ]( h/ b# Z$ f% h# N
. . . . .
7 S. u0 |0 R6 F) |7 W7 c. }
Irq 224 to 239  Clear Pending Register          Read/write          0xE000E29C
9 g% A( h+ n$ z& K

8 K( A5 E% T( G0 n
: _! Y  o& H5 F: b
& f  O" P2 A: q3 o5 T- G7 d
, S% @# Y& M' m( Y2 U
Irq 0 to 31     Active Bit Register             Read-only           0xE000E300

3 R' P1 ?* j8 j/ F$ e* N5 R& N
. . . . . .

) l7 p5 R/ `' X1 x. R) x1 f  x/ v
Irq 224 to 239  Active Bit Register             Read-only           0xE000E31C
! o" N6 A8 K6 C3 K. d  N
' c7 z# K" j1 ]+ s3 x8 w& ?
. M) I( K2 e! S7 r! ~# z
Irq 0 to 3      Priority Register               Read/write          0xE000E400

% W/ {, {# b. z- O* j9 S' C
. . . . .
* }5 u5 y1 ^: L' V6 n6 ]
Irq 224 to 239  Priority Register               Read/write          0xE000E4EC

& g3 c1 d, w3 P7 s: ?( U
" N0 L- j5 W, ]( C. m* _' K8 ^  T4 U. O6 N  V3 L
CPUID Base Register                             Read-only           0xE000ED00
' G; O- a8 c( c- B
Interrupt Control State Register        Read/write or read-only     0xE000ED04

3 R7 T& }3 W3 J* C0 Y7 F
Vector Table Offset Register                    Read/write          0xE000ED08

7 N0 g2 X1 Z8 G+ ^2 {2 E$ {; d
Application Interrupt/Reset Control Register    Read/write          0xE000ED0C
2 l" r6 E7 ^# ^. H/ f- W9 r5 z$ c! s2 M
System Control Register                         Read/write          0xE000ED10
) F1 X6 X9 K1 t
Configuration Control Register                  Read/write          0xE000ED14

. U  N- _8 Z7 J( v
System Handlers 4-7 Priority Register           Read/write          0xE000ED18
' v, |5 a* s0 s# z' a  W
System Handlers 8-11 Priority Register          Read/write          0xE000ED1C

- V6 ^5 ^5 [& T1 R
System Handlers 12-15 Priority Register         Read/write          0xE000ED20
: V/ m0 c8 y( F4 s
. . . . .

+ X. G. N0 F9 P
( t' X( \1 J8 T9 ?: V0 R" Q+ {& x
2Stm32中用了那些
! C. l! j4 k, A, Y6 p! D

' j, D' e( m9 x( g1 F; O: U5 ]
下面是从ST公司提供的函数库的头文件得到的,库是v3.1.0
1 u  X$ H! I% d0 X4 u7 M
/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */

  _) q; k! e- A' G( [
typedef struct
* {$ T# @4 l9 k/ \6 W2 \/ U
{

5 R) o$ J. d- z
  __IO uint32_t ISER[8];                 /*!< Interrupt Set Enable Register            */

7 U7 {  [4 |. {
       uint32_t RESERVED0[24];
- E/ S( {5 e/ D. p( U4 x1 E4 t
  __IO uint32_t ICER[8];                 /*!< Interrupt Clear Enable Register          */

, R7 d5 R: r3 g! M" K) e
       uint32_t RSERVED1[24];
! a7 ]0 W& ?  _3 Z+ h9 N  ?
  __IO uint32_t ISPR[8];                 /*!< Interrupt Set Pending Register           */

( U( J  L; m9 ]' I
       uint32_t RESERVED2[24];

! j1 F) b( K% X" j" M8 m; e
  __IO uint32_t ICPR[8];                 /*!< Interrupt Clear Pending Register         */

: T6 \1 v) b% P0 n( a+ ~; B, u7 Z) c
       uint32_t RESERVED3[24];
& B. L/ G2 c( N6 I  @4 O
  __IO uint32_t IABR[8];                 /*!< Interrupt Active bit Register            */
$ ]) v& t" ?6 L0 E# M6 o) C
       uint32_t RESERVED4[56];

. e2 m; D( w$ n3 @4 c4 _, I
  __IO uint8_t  IP[240];                 /*!< Interrupt Priority Register, 8Bit wide   */
/ `- o3 T2 I) p
       uint32_t RESERVED5[644];

9 r2 O" \/ u# ~- p  X! M, U5 c4 c: J
  __O  uint32_t STIR;                   /*!< Software trigger Interrupt Register      */
5 ~0 M  `3 d& e* q. p5 L3 H
}  NVIC_Type;
) v. m7 c0 {& h4 G$ a, W! g5 u; v. C

! W& d+ i9 K5 _, P( M- x! ?. `7 w
a/  寄存器ISERICERISPRICPRIABRSTM32中都使用的8个(实际3个就够了,后面的将来还要扩充?)。这些32位的寄存器中每一位对应了一个中断通道相应的标志。

3 d5 w, x% n. Y$ c- |
比如地址在0xE000E100的ISER[0]这个32位的寄存器,第0位是中断通道0的允许位,第2位是中断通道1的允许标志……32位是中断通道31的允许位;接下来地址在0xE000E104的ISER[1]则是中断通道32-63的允许位。ICERISPRICPRIABR的结构相同,只是含义不同。
0 n  a/ B5 c) P# |) m
$ ]! }$ I8 q: j7 u
注意是对这些寄存器的操作:写1表示置位或清除,写0无任何影响。

7 C* o) T% `. H) p& w4 q" N2 G! t; i9 l
1 W) h7 N( Y& \9 i6 E* F
例如:
; F( V. U0 Y! i, W( Q  Y- L
对0xE000E100的ISER[0]的第0位写1,表示允许中断通道0中断;
/ ?4 _3 o: A7 B0 P2 J" s' K
但对0xE000E100的ISER[0]的第0位写0,则没有任何作用,该位保持不变。
% \5 p: ~4 [/ a* V( h. J
如果要禁止中断通道0的中断响应,那么就必须:
$ e) H; G* N4 L, d9 o' l
对0xE000E180的ICER[0]的第0位写1,表示禁止中断通道0的中断;

, s9 N% U: \% g
对0xE000E180的ICER[0]的第0位写0,也是不起任何作用的。
) `% {: A! x6 S7 Y9 V
* H3 g4 @5 }, Y  ]
2 ~( M8 B/ t7 `  p9 w8 S
b/ IP[240]用于定义240个外部中断通道的优先级,每1个字节对应一个通道。4个通道的IP[]构成一个32位的寄存器。在STM32中最多有68个外部中断通道,每个IP[]1个字节中只使用高4位(见前面介绍)。IP[]的结构如下:

$ @# x+ k. C8 I- N9 A& d0 i# n! e

( _4 k0 V6 O$ c+ q  o2 q0 |

. X/ y% c8 X& q0 }& w1 Y

' A+ C, h+ }. h! ?$ }) K- c, W$ q5 s+ p" f
31:28

3 [3 y; |; k2 f" @
% i$ `: x( [; V( I6 }& R
27:24

& r9 {, _' J) X+ l1 B

1 g% I9 ^6 d! w/ f3 x8 n% R
23:20
: D5 T" Z5 p$ Q8 }
  o  W0 l! R1 W* }& x
19:16
. i9 S* z$ W0 ^% B- q3 H( o, G
9 `# k) f) c. r; U; y
15:12

5 ^6 k% G! Q2 b5 i
, d. y% v) F- Q: j1 X0 P
11:8
2 l! C& N2 R# t5 @8 u* s

& o7 G& l3 J- E' l# P4 \
7:4

: K2 [! O$ M8 P4 \

7 E; Y7 F0 C2 q/ f# w* K
3:0
' P$ c8 C+ C' e! ^. q

$ y$ N3 v) U+ h# N

" d/ w7 f1 D7 d5 v- h0 v5 e
8 F; F* E' u  w8 y
E000E400

3 z3 z8 V9 n' s6 R1 l
2 M, b" ?/ |/ t. x, s2 L* v
PIR_3
% Y1 s% n) }: r- C, X% I

+ A& u( h4 p3 `  W$ H% |
PIR_2
. v0 t' P3 ]  b
3 l) T( K* I7 t. ]$ l& p: g1 @
PIR_1

. O8 x; d5 A- K5 n

% m3 @. A4 x0 i3 j
PIR_0

+ b. O& U5 b* M  ^. [

( l* c- ?3 ?% a% S0 u& I* F, g
每8位的高4位有效,灰色位表示无效
  z; |, Z' a. P$ c

$ ?" O$ }5 P4 l
E000E404

8 M& Y% q$ e% i! {

" r+ \. h' F, ~" M0 s: \
PIR_7
7 X2 B' ^; H" e: _& l7 Z9 o
4 ~. a! G$ C8 A8 T1 T
PIR_6
& l* [% F+ y, r7 `+ ?8 s4 H) R

. J( K& k1 ^7 i$ l3 @
PIR_5
" B* }4 [0 I. @' i) L
" Q/ ^$ Z0 I* E* [  d
PIR_4

" ]5 g- }4 b% [- `

: h. @  Z8 x* _7 X2 Y( X; B4 T
……

2 |9 L: E& k3 p7 J

3 s( z1 z& R) M; ]) J
……
/ e  `1 R. A, ]- E

5 V( W9 L3 e3 x3 W& R- e
……
6 _* j: X3 `: Y: \3 t

. x7 j5 }+ d# O/ j! o0 `+ Y
……

% ]% z: U# o+ D! J/ I. x

& {8 k2 C! C/ _5 S! Y) H1 `0 z
……

/ x; ?2 e3 ~* G8 y
- E: A$ n+ b# n  v4 w9 Q8 C
( k3 a& p7 Q3 e8 H: V  i! J
3 Q' _6 h+ d+ M8 E2 q& x4 R. q
c/ 在ST公司提供的函数库的头文件中另一个数据结构中,还有一个寄存器需要关注 :

: M2 U; i4 D0 y- \( X
3 [$ w( |1 W) R0 d' j
  V- J9 i, Z5 J8 z& E( Y
/* memory mapping struct for System Control Block */

% E7 V: F3 y7 J( P# i0 T# j
typedef struct

8 k/ w8 y8 u' v/ q* Z
{
: l8 m' n$ o' G$ I" ]2 F' D7 f
__I uint32_t CPUID;     /*!<CPU ID Base Register */
' P/ e  H3 T+ }) C! ^0 i* J' M, d
__IO uint32_t ICSR;     /*!< Interrupt Control State Register */

8 |+ Z* A+ O1 b& e( ~: @
__IO uint32_t VTOR;     /*!< Vector Table Offset Register  */
; D  p# h8 K: |& U' ?, w" r
__IO uint32_t AIRCR;    /*!< Application Interrupt / Reset Control Register  */
3 p4 }5 b3 `* @: i/ X
__IO uint32_t SCR;      /*!< System Control Register */
- H% C- s% A1 S9 j+ m
__IO uint32_t CCR;      /*!< Configuration Control Register */
8 t3 n9 R  h# c+ c$ |
__IO uint8_t  SHP[12];  /*!< System Handlers Priority Registers (4-7, 8-11, 12-15)*/

- E6 ?+ c6 V: A: B5 T- o- u
__IO uint32_t SHCSR;    /*!< System Handler Control and State Register */
* i( P9 K3 l' r
__IO uint32_t CFSR;     /*!< Configurable Fault Status Register */
2 F& {) ?+ J, o2 ^; `
__IO uint32_t HFSR;     /*!< Hard Fault Status Register */
) S* S, Q5 D, d) b
__IO uint32_t DFSR;     /*!< debug Fault Status Register */

; P8 j/ U- s& y
__IO uint32_t MMFAR;    /*!< Mem Manage Address Register */
& R7 q9 ~- t+ M! V
__IO uint32_t BFAR;     /*!< Bus Fault Address Register  */
( P: C4 T* e9 n) A4 A8 `
__IO uint32_t AFSR;     /*!< Auxiliary Fault Status Register */

* G% V! |7 P1 e
__I  uint32_t PFR[2];   /*!< Processor Feature Register  */
9 }1 W  c8 B; C
__I  uint32_t DFR;      /*!< Debug Feature Register */
$ g8 s& G. A9 p& o0 R: d7 a
__I  uint32_t ADR;      /*!< Auxiliary Feature Register */

8 X2 y4 }7 f( y/ P& }
__I  uint32_t MMFR[4];  /*!< Memory Model Feature Register */

9 m  P5 k1 a, d
__I  uint32_t ISAR[5];  /*!< ISA Feature Register */
6 Y6 c/ z; N3 t: K) T  p# m
} SCB_Type;
) N7 V2 x6 A0 ]+ ^; G* G5 Y  d: V2 q
3 R) W3 n1 J& j1 Q2 O& m

1 M4 B2 x$ K+ g4 m$ Z7 Q
它就是地址在0xE000ED0C32位寄存器AIRCRApplication Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4bits,起可能的值如下(来自ST的函数库头文件中的定义)

, I, P' D" u- Z3 K" j1 t

6 C' N1 o/ q3 e' G& _; B
#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority

/ O; ]0 g8 h4 _1 r8 Z* u# J
                                                            4 bits for subpriority */
4 i9 m0 o  n4 e
#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority

- K  `5 j7 g% J8 u. M) J2 r
                                                            3 bits for subpriority */

0 k# b6 H$ b/ E( Q/ V; G
#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority

( T+ S& @3 L+ W# Y% |$ L2 J
                                                            2 bits for subpriority */
+ z2 G) s5 q$ ^: m  h
#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority

- l% b" v4 Z2 W
                                                            1 bits for subpriority */
& J% d3 m* U" ]8 K) m$ y
#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority

( O+ I- N7 b% X( _! N& ~/ C  P
                                                            0 bits for subpriority */
0 }/ [/ c! ^  u
  g; A! T( m. o0 L0 W& J6 ?, [

  m: T, J7 r8 W5 X
由于这个寄存器相当重要,所以为了防止误操作(写),因此要改写这个寄存器的内容时,必须同时向这个寄存器的高16位[31:16]写验证字(Register key) 0x05FA。

8 |4 k) r4 d- W* L  H) @: p* |" O  J* f$ ]! ]4 n2 ]6 z
6 L' n1 ^! R+ `
例如:SBC->AIRCR |= (0x05FA0000 || 0x300);    // 设置系统中断有16个抢先优先// 级,无子优先级
) ]3 ~% ^+ e0 e- k

& M9 S! Y: n" |4 J: U) C" w' e% J& K. p% _  ]8 t( x' e
8 U3 z! P, V8 V; c/ K
d/ 下面的定义与SYSTICK相关,有时也会用到的。
- y7 {) U7 E4 ]- c
/* memory mapping struct for SysTick */
: z! h) E6 y- l) _- Z
typedef struct

7 {. I% p0 u) z+ j
{
  J, H8 I6 N! `
  __IO uint32_t CTRL;       /*!< SysTick Control and Status Register */

7 ~8 e7 U. U) q4 I7 H4 n0 S2 C% ]! r
  __IO uint32_t LOAD;       /*!< SysTick Reload Value Register       */

5 k6 T1 G4 m9 m
  __IO uint32_t VAL;        /*!< SysTick Current Value Register      */
3 F+ \% p4 }. f/ r" U8 T9 c
  __I  uint32_t CALIB;      /*!< SysTick Calibration Register        */

$ e# V7 ?9 w1 I- ?7 Z: z
} SysTick_Type;
5 n, g  T! @/ k$ N" G5 S

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-8-24 01:41 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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