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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
一、基本概念
5 X" Y# w8 n" d# @' ]6 [
1ARM cortex_m3内核支持256个中断(16个内核+240外部)和可编程256级中断优先级的设置,与中断控制核中断优先级控制的寄存器(NVICSYStiCK等)属于cortex_m3内核的部分。STM32采用了cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。

1 H' N; h' B3 H, p5 H: N" f9 Y! H
0 |8 p. W' X7 {' l1 {
2STM32目前支持的中断共为84个(16个内核+68个外部),和16级可编程中断优先级的设置(仅使用中断优先级设置8Bit中的高4位,见后面解释)。《参考最新101xx-107xx STM32 Reference manual, RM0008》。

8 c5 {2 `6 O1 w6 s* D
& v) r1 z; u0 v  P: G
以下主要对外部中断进行说明。

1 Q9 U' X2 e/ j8 A# G  B- I6 S
5 [( u6 w  s* n+ O! S5 \
368个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是1732位的寄存器,它们是NVIC寄存器的一部分。

3 w# M2 E0 J" ?8 B( P
% C6 x% g5 ]5 d( y
4.这4bit的中断优先级控制位还要分成2组看,从高位开始,前面的定义抢先式优先级,后面为子优先级。4bit的组合可以有以下几种形式:
& k0 v4 p, T' G7 l! n/ z" j) F
* ?5 S- F, N1 N2 F2 o& {: x
5 y% `1 T. s- O% j
分配情况

6 ~' R* l: g3 y; D
$ f- o0 _: _( l/ E; {; i

0 ^& }: }* E( }( k" q2 g( ^

) M. z) P: K4 K; i! W
7
( t# P3 C( A0 ?# e! D% H
( r& w6 V$ ?' L6 I$ z* }, s. d4 I, D: {
0:4

1 K4 ^. m8 V3 }$ L* Z
4 |7 u/ I. r0 J3 u+ m, f9 L5 Z
无抢先式优先级,16个子优先级

( Q4 j4 u0 |9 b
# e" i0 m, V+ @$ Z( |' Z) n
6

# N3 z8 K6 g$ E5 ~1 v+ z
  i4 J$ Q& o( D2 }- e2 s
1:3
, k) o) c9 Y+ e, l

5 f8 v5 ^6 Y( T% t! j; q
2个抢先式优先级,8个子优先级
! g! k. P  e+ H/ u

" M/ r7 S7 q% _
5
1 U8 d( [9 p' Z+ B8 _. t/ |6 U

& [" l7 i% S1 [
2:2
8 p/ H. G- J* l! M# N; ~

$ G/ ?3 S8 P" K, h
4个抢先式优先级,4个子优先级
8 X5 x4 l+ l! M" S) q

) Y% X( f/ {; q8 s( D( Q$ K
4

: E, [; p( g1 ?9 K

6 P2 G# t# j$ y0 i6 Z# f3 E2 W
3:1

+ m/ X6 M6 u* H  A8 y$ }
8 @8 {% s) ~3 v0 z5 r/ ^: D  n9 R# Z. z
8个抢先式优先级,2个子优先级

3 g  c; R) \* p, i- E8 A3 z0 a

0 z; Z% F( W. X. X
3/2/1/0

- G- G2 |& O2 Q( v; h

- L' b9 x# O$ r0 Z( X1 r
4:0

) R, R' e# H6 Z/ l3 H& V1 ^" Z
7 F4 d6 }! d$ {$ O; Q1 I
16个抢先式优先级,无子优先级
; A. n, N: N7 H0 w9 _; ?# L% C

+ D- k' C6 C2 W! u; Z8 k$ Q

% e8 e$ n$ \  Y1 G) Y5 {
5.在一个系统中,通常只使用上面5种分配情况的一种,具体采用哪一种,需要在初始化时写入到一个32位寄存器AIRCApplication Interrupt and Reset Control Register)的第[10:这2个位中。这3bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。比如你将0x05(上表的编号)写到AIRC[10:中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。
$ u, b$ O2 c7 g  ~& W- b7 k

  `  R4 N2 n! R7 ~
6AIRCPRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRCPRIGROUP,也就规定了当前系统中只能有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级,他们分别为:
1 A+ t: r& v* o! m
[7
0 H, i6 i9 z3 V. s# F$ o! F
* x' {* |6 z/ _, b. Y) |' C% Z
/ v( A; ~/ _# w6 W
[5
7 ^7 ~' @' W1 @  q  t8 ?! Z% }* `
6 t% }1 ?# M' ^/ d8 y5 m% ~

) q; f2 Z, N  m
: S- O( J7 o( m% S/ Q
[3
; C. s. M) i4 E# M& k6 C, s
1 C1 D: B' ?. b
00

8 A" k) O( k# [: y' G" ?
9 `& U& \% n, f5 R/ D
0号抢先优先级

2 L& S; V* m. j2 M' ^. {

, K) A5 O; Q5 L: a
00

9 E8 C; j/ A9 {4 f) B# f' q& U
8 l5 [9 f$ {2 o( r/ y" m& k
0号子优先级
: O2 k* j9 A  \! O% X
* e' R. u' h. n; E8 q5 q! R7 k
无效

3 q3 `. T) @( K$ C

8 K/ T# E6 ?& u$ S3 v! z
01

& z- C# t4 K! k. K/ N- Q8 k" s6 N

' k, p8 w+ w4 m8 n/ {# ?
1号抢先优先级

9 u2 t' n8 r. J" C8 F5 Q: I

" ^+ N/ s0 E, b  }. a) w' U8 g
01

3 u% T1 a; Q' O9 T- R
2 M, d4 n; l1 {8 k* g$ M/ p/ Q
1号子优先级

7 Y( k  l9 |- j& d
2 j  Q6 F1 c6 ~( ]8 A
无效

0 D& k6 i. }* N0 J! U
; Z! l+ M# O, u& }. n; O7 H
10

* Z2 z0 x" r9 l* i" L

7 Y# A2 [1 V( e: u
2号抢先优先级

  @/ v' r- s& t3 k6 F& c
# Q3 p" g. y( f. C2 E) J/ g' A' `/ n4 }
10

* E0 |7 x* c% |, Q- O

0 B% S: a$ G3 O$ P4 B( b- G
2号子优先级
( n8 S- ~. F% V
& \4 \3 E" q1 E' j2 |2 D
无效
7 N8 Y/ p: n0 D- {+ I4 r( p

3 N/ G( \9 Z; q! ?' `6 d
11
. ]7 J& @) E3 Z( }# w/ O+ T! g. H6 H
9 D* d# |9 a6 t  P
3号抢先优先级

4 T1 O) D' {$ F) p
9 M) C3 Y# U: ~: H* j0 W  a( {
11

% E" n4 d( b6 _" t( k" g+ a5 _
: q" F3 @2 K  b5 B
3号子优先级

0 _2 D4 z( j, b

3 s5 i  H( `  y9 k
无效

% I( X9 `4 ]0 p3 A% h

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

5 n6 v) G1 H6 I& N3 c- L

& i  h! M5 e8 s) V# ^. o
8.具体优先级的确定和嵌套规则。ARM cortex_m3STM32)规定
7 x' n4 M3 `$ j. j4 {
a/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。

  u" l: b% V4 \4 ?% K* [1 D
b/ 2n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。

/ n, q# m+ J$ Q" s2 z
c/ 2n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。

& V; p! Z+ [& H1 a. ^" J4 U
具体一点:
$ y8 Y- n: b( ?# R% B
0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为234号的中断;…..构成中断嵌套。
+ e6 u+ Y( I! e2 r- ~  n* s
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。
8 k, e/ X! X8 s$ |

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

' W' h; `4 n$ D2 A2 Y0 f) l
  B% T* C& a* o, l

% ^  x; Z1 D$ D1 g2 u. B
了解以上基本概念还是不够的,还要了解具体中断的控制有那些途径,中断服务程序如何正确的编写。下面的描述主要以TIME2通道为例。

2 h- h: m5 g9 q" l
6 r$ x6 Y6 a5 i
二、中断控制
$ q/ `0 e0 i8 A$ t: X7 E
1.对于STM32讲,外部中断通道位置2835号优先级)是给外部设备TIME2的,但TIME2本身能够引起中断的中断源或事件有好多个,比如更新事件(上溢/下溢)、输入捕获、输出匹配、DMA申请等。

  }# P' Z) l. g* V8 r0 I
(题外话:就一个通用定时计数器,比8位控制器中TIME要复杂多了。学过AVR的,可能对输入捕获、输出匹配等还有概念,如果你学的标准架构的MCS-51,那么上手32位控制困难就更多了。所以我一直推荐学习8位应该认真从AVR开始,尽管51有很大的市场,价格也相对便宜些,但从发展的眼光,从后续掌握32位的使用,AVR是比较好的选择。)
- S0 ^, }0 l& w% m
) A4 t4 n% `$ r1 ?1 g2 \. z
   所有TIME2的中断事件都是通过一个TIME2的中断通道向STM32内核提出申请的,那么STM32中如何处理和控制TIME2和它众多的、不同的、中断申请呢?
- f0 U) V& F+ I$ w0 g: x
! n$ @3 M2 ?1 R( q4 D) H% m( t! j
2cortex_m3内核对于每一个外部中断通道都有相应的控制字和控制位,用于单独的和总的控制该中断通道。它们包括有:

% p% v$ {- @2 B+ }" F
中断优先级控制字:PRI_n(上面提到的)
5 g$ p* K/ d6 X8 o1 ]* k6 d. c
中断允许设置位:在ISER寄存器中
8 [2 |) D  n- R  v5 |" S$ J
中断允许清除位:在ICER寄存器中
/ s: P. {  b8 n4 P2 x" o# s4 [
中断悬挂Pending(排队等待)位置位:在ISPR寄存器中(类似于置中断通道标志位)

: ?' B, H# ]- I% k4 x2 ^8 E
中断悬挂Pending(排队等待)位清除:在ICPR寄存器中(用于清除中断通道标志位)

) n1 H- `/ P) T/ q$ u
正在被服务的中断(Active)标志位:在IABR寄存器中,(只读,可以知道当前内核正在处理哪个中断通道)
) N, a0 }. M) X5 `4 T6 `+ R. f

" V0 `- {2 }7 R* l
因此,与TIME2中断通道相关的,在NVIC中有13bits,它们是PRI_288 bits(只用高4);中断通道允许,中断通道清除(相当禁止),中断通道Pending置位(我的理解是中断请求发生了,但当前有其它中断服务在执行,你的中断级别又不能打断别人,所以Pending等待,这个应该由硬件置位的),中断Pending位清除(可以通过软件将本次中断请求且尚处在Pending状态,取消掉),正在被服务的中断(Active)标志位,各1bit
2 x& W& \1 ]+ I; q
, I! A- u2 L$ Z' _3 h) t
上面的控制字和控制位都是在NVIC中的寄存器组中,可惜的是在STM32中竟然不给出任何的解释和说明。
) t5 u" i# d- s. V& V: {" B
3 q2 ~1 E6 o) J9 M1 m
3.作为外围设备TIME2本身也包括更具体的,管理自己不同中断的中断控制器(位),它们主要是各个不同类型中断的允许控制位,和各自相应中断标志位。(这个STM32的手册中有详细的说明了)

2 \$ `# S, q% `2 D) E5 b6 D1 w
+ ?5 v" |9 g* }
4.在弄清楚23两点的基础上,我们可以看看TIME2的中断过程,以及如何控制的了。

5 K& x# a# ]& Y1 f. t4 ?" O. H$ A
- O% L7 @; U4 t+ O
a/ 初始化过程

( s: W6 ?# g& I% M( W1 }% R
设置AIRCPRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4bits中占用的位数)
$ z: Q. a2 y$ Y
设置TIME2本身的寄存器,允许相应的中断,如允许UIETIME2_DIER的第[0]位)

( O$ \- m3 K4 r5 ?
设置TIME2中断通道的抢先优先级和子优先级(PRI_28,在NVIC寄存器组中)

! l6 A  p2 r8 D  p0 ^- v% F
设置允许TIME2中断通道。在NVIC寄存器组的ISER寄存器中的一位。
5 F6 j3 P  M  S# ~

: H, P+ z+ d; s# o" M8 X
b/ 中断响应过程
% ?5 C/ m$ K; n/ {' [7 r* b& W
TIME2UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。

, v0 i; m3 H: t' s+ M/ U  c. T
此时硬件将TIME2Pending标志置位,相当与中断通道标志置位,表示TIME2有中断申请。
' A9 y# l) T0 U" d& I, b, j  M% d
如果当前有中断在处理,TIME2的中断级别不高,那么就保持Pending,当然软件可以通过写ICPR寄存器中相应的位把本次中断清除掉。
4 [2 T7 \9 }  ^
当内核有空,开始响应TIME2的中断,进入TIME2的中断服务。此时硬件将IABR寄存器中相应的标志位置位,表示TIME2中断正在被处理。同时硬件清除TIME2Pending标志位。

4 [& O& o5 k% a& R' |" b8 w

$ n6 P! M4 ^7 E
c/ 执行TIME2的中断服务程序

4 t* m8 I8 u( t8 y& T1 m
所有TIME2的中断事件,都是在一个TIME2中断服务程序中完成的,所以进入中断程序后,中断程序需要首先判断是哪个TIME2的具体事件的中断,然后转移到相应的服务代码段去。

( Y. p) Y0 V; M/ l. p3 g- [3 k
注意不要忘了把该具体中断事件的中断标志位清除掉,硬件是不会自动清除TIME2寄存器中具体的中断标志位的。

  T8 V  L* h7 i* F, j

4 y% B: I& I  m
d/ 中断返回
5 Z1 _& r3 Z/ h* \! o5 u- `2 w9 ^
执行完中断服务后,中断返回过程,在这个过程中需要:

: b: S$ L" V4 b2 [
硬件将IABR寄存器中相应的标志位清另,表示该中断处理完成
9 W) i; b1 T6 t% Z- v; |& _) T
如果TIME2本身还有中断标志位置位,表示TIME2 还有中断在申请,则重新将TIME2Pending标志置为1,等待再次进入TIME2的中断服务。
  E: G( b& `2 ~

. a. o  B6 _' v+ Q8 b, A5 q& J1 v% ?
注意:以上中断过程在《ARM Cortex-M3权威指南》中有详细描述,并配合时序图说明,可以参考。

5 x- y) H7 i, L5 a, j6 C& N

6 `% Y) u8 j9 I% N
如果以上明白了,那么可以在ST提供的函数库的帮助下,正确的设置和使用STM32的中断系统了。
2 }4 W5 L. x% q2 b; a

8 Q% S/ C- K9 C2 ]! Z/ r- A. D
如果你要了解更深入的东西,或者直接对寄存器操作,还要继续望下看。

% m& d/ n; ~9 X7 J$ c
  Q3 d( f* X; M8 |
三、深入NVIC
( u7 ~. q8 x, s, a/ Q

. V8 i  E7 o2 z. x
1. 看看Cortex-M3中定义与NVIC相关的寄存器有那些

9 I" R; H2 \9 d" k: S( [
SysTick     Control and Status Register         Read/write          0xE000E010
* Y: O. k1 a- t+ P$ T6 h1 \2 _
SysTick     Reload Value Register               Read/write         0xE000E014

, D2 [" w$ r- q2 n% A1 y+ f
SysTick     Current Value Register              Read/write clear    0xE000E018
& B" `6 W2 z! R7 J- }$ m8 t" s
SysTick     Calibration Value Register          Read-only           0xE000E01C

7 }/ T8 ~# c  `" ]. W- y; R5 ?
, Y5 C' k& [7 ]5 N
5 C( R$ {2 W# @4 m
Irq 0 to 31     Set Enable Register             Read/write          0xE000E100

: S0 ?! X/ T2 E3 e1 S+ }
. . . . .

( |% o" A: r/ |" v2 [" p( h  \3 o) }
Irq 224 to 239  Set Enable Register             Read/write          0xE000E11C
* l# N0 Y4 M  X
2 R! `7 }6 D! `$ K# J5 C: W3 J
" ]$ p! m% N% d
Irq 0 to 31     Clear Enable Register           Read/write          0xE000E180

/ E; E( }! C- Q- H( X( c- e
. . . . .
4 M4 Q" ?3 P$ F+ `7 A' M
Irq 224 to 239 Clear Enable Register           Read/write          0xE000E19C
. J/ `% z( L7 u$ \& A4 m: d
, \7 Z5 H% f7 x; `
2 h' e- m( ^2 {3 N1 x! [
Irq 0 to 31     Set Pending Register            Read/write          0xE000E200
) x5 a2 K+ t3 M$ Z* Q
. . . . .
: b+ Q2 h, B! E/ c6 l
Irq 224 to 239  Set Pending Register            Read/write          0xE000E21C

* a  `" q* q6 i$ Q! L# O% o+ i! {4 l2 n7 v9 N
: L7 f5 T2 @" d3 ~% G* S2 t3 s
Irq 0 to 31     Clear Pending Register          Read/write          0xE000E280
. C$ q9 m, l0 Q) M9 e. s( y
. . . . .

- U5 b  i: y% f. C" D# H: `
Irq 224 to 239  Clear Pending Register          Read/write          0xE000E29C
: [% c4 r) L  c3 }

7 j4 R" o2 u# l( n, o: C# K4 V" J, v; j
5 A5 V8 F7 G( m! S

6 R1 p, U1 S7 K7 t9 F) Z
Irq 0 to 31     Active Bit Register             Read-only           0xE000E300

; k% h  h1 I7 `2 N9 N  V6 L' Y
. . . . . .
! x' s: m' w% k! U8 I" U
Irq 224 to 239  Active Bit Register             Read-only           0xE000E31C
9 p4 a7 H7 H% e

# l9 [: k2 ~9 d' j) {% _$ j' W0 `. D4 Q+ ^/ N6 S1 I
Irq 0 to 3      Priority Register               Read/write          0xE000E400

, r# i5 v% L$ m( S1 P3 l' \
. . . . .

2 N1 U- [- H- c  `5 H
Irq 224 to 239  Priority Register               Read/write          0xE000E4EC

8 C1 m) f6 H. |1 l- u4 T0 i- B5 c3 _7 |. W1 |. A; B* G( }
; q9 _+ `! P4 a% j  V
CPUID Base Register                             Read-only           0xE000ED00

2 G0 V4 E7 N9 o& M2 {
Interrupt Control State Register        Read/write or read-only     0xE000ED04
; n; j" U# i, t0 p0 p
Vector Table Offset Register                    Read/write          0xE000ED08
7 `# ~; {- I$ ?5 Z
Application Interrupt/Reset Control Register    Read/write          0xE000ED0C
; L7 V. X$ U6 e  T) t, Q
System Control Register                         Read/write          0xE000ED10
, Q8 Y/ a+ \4 _. h
Configuration Control Register                  Read/write          0xE000ED14
0 W* N" ^8 F1 B  S- y2 J6 E
System Handlers 4-7 Priority Register           Read/write          0xE000ED18

2 n1 ?% e( F0 Y8 ~
System Handlers 8-11 Priority Register          Read/write          0xE000ED1C

$ }# J2 g( n: [% g' d0 F" ~9 s
System Handlers 12-15 Priority Register         Read/write          0xE000ED20
( F; C* M& s* h8 ^1 h! D4 y: I. Z
. . . . .

5 ]; A; a1 X" L+ @  _( o6 {' o

3 |5 {7 `* Y6 M4 r
2Stm32中用了那些
9 j$ i. l$ C& D8 C/ S& M

' P( \. ~+ Q4 @- w  W8 v5 I' _
下面是从ST公司提供的函数库的头文件得到的,库是v3.1.0
5 |7 Z, w! k! y4 C& M3 [+ W
/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
/ X( z) X1 K! T8 u/ l& m; c& R
typedef struct
/ v) l2 t- s( P5 E
{

  M8 g, o0 k/ n2 T- D
  __IO uint32_t ISER[8];                 /*!< Interrupt Set Enable Register            */
8 [5 L8 B5 p6 g$ b( g; O
       uint32_t RESERVED0[24];

9 [: d7 p& L: N. S$ b
  __IO uint32_t ICER[8];                 /*!< Interrupt Clear Enable Register          */
. G* U0 ^7 y( s1 p% e- D
       uint32_t RSERVED1[24];

( m0 M5 `. x( p6 W2 W8 F# W
  __IO uint32_t ISPR[8];                 /*!< Interrupt Set Pending Register           */
. _* z% F$ {; W3 @! r
       uint32_t RESERVED2[24];

( T7 @8 J6 |6 w/ c" n
  __IO uint32_t ICPR[8];                 /*!< Interrupt Clear Pending Register         */

8 B9 _$ ^$ [: V2 ]6 J( u6 p
       uint32_t RESERVED3[24];
* e; D% @* W$ L! N0 Y5 D) @" L  ?
  __IO uint32_t IABR[8];                 /*!< Interrupt Active bit Register            */
- k; q- ~  p" c6 d( Y" b8 N+ B
       uint32_t RESERVED4[56];
- m: O$ _3 K% }) m" H& j9 ~
  __IO uint8_t  IP[240];                 /*!< Interrupt Priority Register, 8Bit wide   */

, G3 X( Y. c; ~% B& y( H
       uint32_t RESERVED5[644];

: c. ^% O) h, O9 q2 }/ `
  __O  uint32_t STIR;                   /*!< Software trigger Interrupt Register      */

3 S. J: V. F' w! F$ J; M) _
}  NVIC_Type;
8 S9 W$ ]) K& t6 ~: L6 c6 z; R
" S- `. _; x, w8 L1 ^* n  |
a/  寄存器ISERICERISPRICPRIABRSTM32中都使用的8个(实际3个就够了,后面的将来还要扩充?)。这些32位的寄存器中每一位对应了一个中断通道相应的标志。
+ @) O3 _- l/ @4 c
比如地址在0xE000E100的ISER[0]这个32位的寄存器,第0位是中断通道0的允许位,第2位是中断通道1的允许标志……32位是中断通道31的允许位;接下来地址在0xE000E104的ISER[1]则是中断通道32-63的允许位。ICERISPRICPRIABR的结构相同,只是含义不同。

# n! t) n1 a! `( p: G' U

: n5 u# }6 p& |) n/ A9 S
注意是对这些寄存器的操作:写1表示置位或清除,写0无任何影响。
9 A  t& _* p# p: ]! T3 ]* @3 {# Q

# f0 i7 J* a# k3 e9 u* z
4 n5 L& T6 b, E' s" N( q0 x. X
例如:
0 D% [+ ]. t/ N  n
对0xE000E100的ISER[0]的第0位写1,表示允许中断通道0中断;
/ D) \, ~0 s3 b* S! P: ?
但对0xE000E100的ISER[0]的第0位写0,则没有任何作用,该位保持不变。

  x) q- r4 z) G; D3 w  l6 Y. Y
如果要禁止中断通道0的中断响应,那么就必须:
8 {; F% o% M2 a: `4 j: r
对0xE000E180的ICER[0]的第0位写1,表示禁止中断通道0的中断;
" P8 V  L$ ^2 o2 T3 ?  |
对0xE000E180的ICER[0]的第0位写0,也是不起任何作用的。
: @/ k4 b) E* C

, S( k- @5 t! m. J6 F
1 A! }& N. C4 k* N% L# E
b/ IP[240]用于定义240个外部中断通道的优先级,每1个字节对应一个通道。4个通道的IP[]构成一个32位的寄存器。在STM32中最多有68个外部中断通道,每个IP[]1个字节中只使用高4位(见前面介绍)。IP[]的结构如下:
2 H1 h9 Y+ u& e3 q. ^# |

$ o1 I& z4 f3 T2 a$ g

1 j: A" z% u# I; V; W

, h. u! G( z, F: F
5 N$ o7 L  D6 e) y9 F( {/ N
31:28
2 @" O- `0 b: P; @0 \& J

: b, ]( y" }1 M9 J( G
27:24
% n& ^( u, ^( G# O* F) A

% L- O5 h0 q% K( t3 y$ Z2 w
23:20
( Y$ a6 C3 _. q" n. o8 c; O- @
: E2 g  E, [$ \. {3 M
19:16

8 [) n9 R, Y! P" S0 ~" W

* E# o' W; ?3 Q
15:12

! B! ^) T' q) k+ y: ]9 b

; F/ [8 w$ [) Q4 r7 K% L$ V* G
11:8
: L& O  z% _$ S
% M1 ~: m& y" }. n
7:4
% B0 ^2 b; k2 |2 R: _7 T1 J/ X. b

4 K/ x/ Y# _$ j* u% v
3:0
( t& P' c# z" m* ]! c
5 z4 G3 ~1 G& I" k6 h. A3 h8 [
5 U! T9 G9 v" c! w5 M, P

5 U9 H4 I9 w- f) L1 H7 t
E000E400

8 Z4 b* R% `* m* t
' o$ T1 x. P& R0 @/ t
PIR_3

; y' l  u* Y) C% @! `( x4 B

, x2 e" x  j$ ^# g5 Z
PIR_2
5 G9 s* |- Q2 }8 Y& D9 y+ Y
/ `' x6 Q, E! _" i/ W. m8 T% W( k1 ~( c
PIR_1
5 v. [" ]4 Y2 n: I
, D$ Z- f2 B+ W
PIR_0

2 s5 r% y. S' i
! h: t8 u. [( f- }0 g
每8位的高4位有效,灰色位表示无效
& E9 u, ]& A$ U, g6 z; }

0 D' k& Z: m9 E8 ^
E000E404
' m% t& ~2 e! O) z5 C5 k" {* w
9 s3 V9 O3 Z+ D  I% Q( a* {2 U
PIR_7
1 K  W! Y$ Z: T6 g

8 |( k/ o% W* w' ]
PIR_6
0 W, j0 I, [% e* \

' p+ l; R4 V- `
PIR_5
4 L8 ^* \5 g' i2 ]: B" Q

" ?& j3 \% ?; n  C8 _
PIR_4

1 {, Z+ ]1 E5 z
* f% N6 G" K  s7 p7 w9 a: I, f
……

: V, U+ m& b; R- t
; e( x9 b+ K' w5 q( P
……
# i5 V3 \8 }+ T& _# {0 Y$ J0 d

* ?% D/ g, E0 b# S+ s5 o, ?) l3 g
……

# R  {9 B: H( P# ^' I* O* j* y6 b

* w$ M+ B5 h7 e" N
……

0 B* Y3 y6 f1 x3 K0 q5 ~4 f
0 K' }" f7 T4 E& W. J1 W- l6 y5 z
……

' s& j! }! O$ D. [- M1 s, v3 }0 p

( u; v; N, B- b. \& m( |

% p1 f" @! Q3 z: c
1 w& V- P7 p6 H
c/ 在ST公司提供的函数库的头文件中另一个数据结构中,还有一个寄存器需要关注 :
7 |3 Q: b) H4 @: N0 Z* X
6 }9 ^' q$ d$ t- g, [

. R& v; x/ Y  r: m6 k1 n( u
/* memory mapping struct for System Control Block */
8 U2 p! F, ]) ^: r2 `! c( x
typedef struct

8 t+ X5 t6 e, ]+ Y$ r* c. o/ O
{

2 n# f, j% u7 D5 B
__I uint32_t CPUID;     /*!<CPU ID Base Register */

" O$ }  m, A3 H9 v
__IO uint32_t ICSR;     /*!< Interrupt Control State Register */
+ g/ {, \& z! w* i
__IO uint32_t VTOR;     /*!< Vector Table Offset Register  */
( f; c1 l  B9 U& B
__IO uint32_t AIRCR;    /*!< Application Interrupt / Reset Control Register  */
) A- |! m- I! a0 ^' U6 q9 ]
__IO uint32_t SCR;      /*!< System Control Register */
7 ^8 F2 T3 m; q0 K3 Z0 \  g" i
__IO uint32_t CCR;      /*!< Configuration Control Register */

! L4 p" d# n' J9 I) |
__IO uint8_t  SHP[12];  /*!< System Handlers Priority Registers (4-7, 8-11, 12-15)*/
4 x( r: J3 o/ R$ A
__IO uint32_t SHCSR;    /*!< System Handler Control and State Register */
6 Z7 _! i+ L6 G/ Y& r5 L( u  Y
__IO uint32_t CFSR;     /*!< Configurable Fault Status Register */

3 Y5 O' T  k3 t, z
__IO uint32_t HFSR;     /*!< Hard Fault Status Register */
- b6 q6 n) B1 x; }% e
__IO uint32_t DFSR;     /*!< debug Fault Status Register */

/ x  ]- Z- P7 Y3 V* m3 n! _1 r
__IO uint32_t MMFAR;    /*!< Mem Manage Address Register */

6 S) o/ j, Y  u% }
__IO uint32_t BFAR;     /*!< Bus Fault Address Register  */

5 A* c0 _( E( A* k: e9 L
__IO uint32_t AFSR;     /*!< Auxiliary Fault Status Register */

" H) \$ Z7 f; O& L
__I  uint32_t PFR[2];   /*!< Processor Feature Register  */
+ g5 |* i' `. \( f! B6 c" Y
__I  uint32_t DFR;      /*!< Debug Feature Register */
3 A5 `; {4 D+ M3 d! {
__I  uint32_t ADR;      /*!< Auxiliary Feature Register */

1 i- l; D8 S: ?. T+ D' _
__I  uint32_t MMFR[4];  /*!< Memory Model Feature Register */

6 d: Y, x1 j) g9 k$ x3 o  n9 U
__I  uint32_t ISAR[5];  /*!< ISA Feature Register */
' `/ |; d9 I7 `
} SCB_Type;
3 G. T+ \% u& I/ n+ K
" w/ s$ o; ?6 Q+ E9 `/ }2 C
* h% k: u* Q' W. i: Z# d$ U9 s
它就是地址在0xE000ED0C32位寄存器AIRCRApplication Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4bits,起可能的值如下(来自ST的函数库头文件中的定义)

- d( u/ R) B6 n: s! H2 ^$ ?. d
- t* d; a5 l" b3 y/ D3 I  H! ~6 q
#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
, W# T5 w5 \% z& P" ~% p5 V4 q
                                                            4 bits for subpriority */

6 d) m" {$ R/ f0 O' Z* z
#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority

$ r8 @% K& K8 Q  L2 V0 H5 l
                                                            3 bits for subpriority */
3 A: X) v- l. J% h$ n" M
#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
) l& G4 ]& u  M  }
                                                            2 bits for subpriority */

1 B+ \, n% A% i) O* \1 }, K% n
#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
5 R& r) v# X1 m
                                                            1 bits for subpriority */
$ j* v+ N) I6 x) E  v
#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority

, Q$ f1 l- e0 r# U" x7 Q
                                                            0 bits for subpriority */
* S0 v( Q3 g; H, ]. V! g' b

8 n. _5 R7 o6 S9 b: \
6 {7 J: Z  k' V. a% @( i2 x
由于这个寄存器相当重要,所以为了防止误操作(写),因此要改写这个寄存器的内容时,必须同时向这个寄存器的高16位[31:16]写验证字(Register key) 0x05FA。
* j1 o! @, g# D+ ]6 W) j

7 D/ f4 ]3 k- m$ v
+ e" x9 i4 l! I' r6 Z6 l
例如:SBC->AIRCR |= (0x05FA0000 || 0x300);    // 设置系统中断有16个抢先优先// 级,无子优先级
. f6 O( y, r  I; |
6 O; @" c% Q2 W; w
! u: q" ]/ }# e3 ]9 |. p% n" n
) j/ q7 t) z; G+ B8 l' M
d/ 下面的定义与SYSTICK相关,有时也会用到的。
8 k0 [  F1 g) S1 W: l7 P
/* memory mapping struct for SysTick */
# g: i: B: C1 K1 ], u+ Q! W- s9 m, o( a
typedef struct

$ r2 \  j& ~0 s* x! ~& P) L# P
{
' q/ ^; P7 ^9 D" t/ [2 S( D
  __IO uint32_t CTRL;       /*!< SysTick Control and Status Register */
8 Z' R: }' M( c! q9 Z0 N/ W' O. q
  __IO uint32_t LOAD;       /*!< SysTick Reload Value Register       */

, X* A1 {2 \" Y3 L% M$ j
  __IO uint32_t VAL;        /*!< SysTick Current Value Register      */
5 w0 N  H% W8 L4 `) H
  __I  uint32_t CALIB;      /*!< SysTick Calibration Register        */
4 P! I( ]" d0 a5 G/ G2 d0 p
} SysTick_Type;

- S6 }/ n- \8 K

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-8 14:20 , Processed in 0.187500 second(s), 23 queries , Gzip On.

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

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

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