EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、基本概念
5 X" Y# w8 n" d# @' ]6 [ 1. ARM cortex_m3内核支持 256个中断( 16个内核 +240外部)和可编程 256级中断优先级的设置,与中断控制核中断优先级控制的寄存器( NVIC、 SYStiCK等)属于 cortex_m3内核的部分。 STM32采用了 cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。
1 H' N; h' B3 H, p5 H: N" f9 Y! H 0 |8 p. W' X7 {' l1 {
2.STM32目前支持的中断共为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 \
3.68个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是17个32位的寄存器,它们是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
| $ 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
|
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 |
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位寄存器AIRC(Application Interrupt and Reset Control Register)的第[10:这2个位中。这3个bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。比如你将0x05(上表的编号)写到AIRC的[10:中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。 $ u, b$ O2 c7 g ~& W- b7 k
` R4 N2 n! R7 ~6.AIRC中PRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRC中PRIGROUP,也就规定了当前系统中只能有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% ~
| : 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
|
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 | 2 M, d4 n; l1 {8 k* g$ M/ p/ Q
| 2 j Q6 F1 c6 ~( ]8 A
| ; Z! l+ M# O, u& }. n; O7 H
|
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 }
|
0 B% S: a$ G3 O$ P4 B( b- G | & \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 s5 i H( ` y9 k |
9 Z6 |$ n* D+ |1 \. C |
7.如果在你的系统中使用了TIME2(中断通道28)和EXTI0(中断通道6)两个中断,而TIME2中断必须优先响应,而且当系统在执行EXIT0中断服务时也必须打断(抢先、嵌套),就必须设置TIME2的抢先优先级比EXTI0的抢先优先级要高(数目小)。假定EXTI0位2号抢先优先级,那么TIME2就必须设置成0或1号抢先优先级。这些工作需要在AIRC中PRIGROUP后进行设置。
5 n6 v) G1 H6 I& N3 c- L
& i h! M5 e8 s) V# ^. o8.具体优先级的确定和嵌套规则。ARM cortex_m3(STM32)规定 7 x' n4 M3 `$ j. j4 {
a/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。
u" l: b% V4 \4 ?% K* [1 Db/ 当2(n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。
/ n, q# m+ J$ Q" s2 zc/ 当2(n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。
& V; p! Z+ [& H1 a. ^" J4 U具体一点: $ y8 Y- n: b( ?# R% B
0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为2、3、4号的中断;…..构成中断嵌套。 + e6 u+ Y( I! e2 r- ~ n* s
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。 8 k, e/ X! X8 s$ |
# m. J# {2 d$ H" m9.上电RESET后,AIRC中PRIGROUP[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讲,外部中断通道位置28(35号优先级)是给外部设备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
2.cortex_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中有13个bits,它们是PRI_28,8个 bits(只用高4位);中断通道允许,中断通道清除(相当禁止),中断通道Pending置位(我的理解是中断请求发生了,但当前有其它中断服务在执行,你的中断级别又不能打断别人,所以Pending等待,这个应该由硬件置位的),中断Pending位清除(可以通过软件将本次中断请求且尚处在Pending状态,取消掉),正在被服务的中断(Active)标志位,各1个bit。 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.在弄清楚2、3两点的基础上,我们可以看看TIME2的中断过程,以及如何控制的了。
5 K& x# a# ]& Y1 f. t4 ?" O. H$ A - O% L7 @; U4 t+ O
a/ 初始化过程
( s: W6 ?# g& I% M( W1 }% R设置AIRC中PRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4个bits中占用的位数) $ z: Q. a2 y$ Y
设置TIME2本身的寄存器,允许相应的中断,如允许UIE(TIME2_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 Xb/ 中断响应过程 % ?5 C/ m$ K; n/ {' [7 r* b& W
当TIME2的UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。
, v0 i; m3 H: t' s+ M/ U c. T此时硬件将TIME2的Pending标志置位,相当与中断通道标志置位,表示TIME2有中断申请。 ' A9 y# l) T0 U" d& I, b, j M% d
如果当前有中断在处理,TIME2的中断级别不高,那么就保持Pending,当然软件可以通过写ICPR寄存器中相应的位把本次中断清除掉。 4 [2 T7 \9 } ^
当内核有空,开始响应TIME2的中断,进入TIME2的中断服务。此时硬件将IABR寄存器中相应的标志位置位,表示TIME2中断正在被处理。同时硬件清除TIME2的Pending标志位。
4 [& O& o5 k% a& R' |" b8 w
$ n6 P! M4 ^7 Ec/ 执行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 md/ 中断返回 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 还有中断在申请,则重新将TIME2的Pending标志置为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. x1. 看看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+ fSysTick 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 mIrq 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) ZIrq 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 HIrq 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 sSystem 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 r2.Stm32中用了那些 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/ 寄存器ISER、ICER、ISPR、ICPR、IABR在STM32中都使用的8个(实际3个就够了,后面的将来还要扩充?)。这些32位的寄存器中每一位对应了一个中断通道相应的标志。 + @) O3 _- l/ @4 c
比如地址在0xE000E100的ISER[0]这个32位的寄存器,第0位是中断通道0的允许位,第2位是中断通道1的允许标志……第32位是中断通道31的允许位;接下来地址在0xE000E104的ISER[1]则是中断通道32-63的允许位。ICER、ISPR、ICPR、IABR的结构相同,只是含义不同。
# 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# Eb/ 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 | % M1 ~: m& y" }. n
| 7:4 % B0 ^2 b; k2 |2 R: _7 T1 J/ X. b
4 K/ x/ Y# _$ j* u% v | 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
| , D$ Z- f2 B+ W
| ! 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
|
8 |( k/ o% W* w' ] |
' p+ l; R4 V- ` | PIR_5 4 L8 ^* \5 g' i2 ]: B" Q
" ?& j3 \% ?; n C8 _ | * f% N6 G" K s7 p7 w9 a: I, f
| ; 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 Hc/ 在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
它就是地址在0xE000ED0C的32位寄存器AIRCR(Application Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4位bits,起可能的值如下(来自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 |