EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、基本概念! ?6 [0 i0 X6 G9 m
1. ARM cortex_m3内核支持 256个中断( 16个内核 +240外部)和可编程 256级中断优先级的设置,与中断控制核中断优先级控制的寄存器( NVIC、 SYStiCK等)属于 cortex_m3内核的部分。 STM32采用了 cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。 # V- H4 E d W( z: h
) K9 l5 u# C, Y3 }( G
2.STM32目前支持的中断共为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 q3.68个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是17个32位的寄存器,它们是NVIC寄存器的一部分。
7 g; {# I5 e/ I
# C& p% \# I; t5 [3 w0 r4.这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
| # `0 a2 A/ y% ~8 I# u
|
" 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* ^
|
+ 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 |
. 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) A5.在一个系统中,通常只使用上面5种分配情况的一种,具体采用哪一种,需要在初始化时写入到一个32位寄存器AIRC(Application Interrupt and Reset Control Register)的第[10:这2个位中。这3个bit位有专门的称呼: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 g6.AIRC中PRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRC中PRIGROUP,也就规定了当前系统中只能有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级,他们分别为:
2 G i- M% l' p) V H0 S% [3 ]位[7:
' j! b. H6 F! y" N9 A5 p | + n5 e$ J0 n1 X% P0 t) B
| 位[5:
) R1 s0 m- c' ^1 @- w 2 P, U% H7 V, ]
|
) 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 | 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 |
9 \7 o" A) ]6 |+ E8 v+ | |
4 C2 l; ^: }! D/ ^ | 2号抢先优先级
% `! f* w% m5 E% s+ @: ? 4 U4 r- \+ z3 P# F1 \
|
: O4 l; ]' r; j: P- ?0 c | 2号子优先级 # C6 k% I0 v) O& a. L3 X
/ m* A) D: a" b# n | ) 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 |
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
| * h6 R0 x$ j9 ~& g8 K% F- M; w3 d8 k
|
7.如果在你的系统中使用了TIME2(中断通道28)和EXTI0(中断通道6)两个中断,而TIME2中断必须优先响应,而且当系统在执行EXIT0中断服务时也必须打断(抢先、嵌套),就必须设置TIME2的抢先优先级比EXTI0的抢先优先级要高(数目小)。假定EXTI0位2号抢先优先级,那么TIME2就必须设置成0或1号抢先优先级。这些工作需要在AIRC中PRIGROUP后进行设置。
2 s) V. T& k2 }5 }/ f$ Q/ Z, p. H
- r. E o3 }: s1 q$ Y8.具体优先级的确定和嵌套规则。ARM cortex_m3(STM32)规定
v q N+ k, i' I: \; ^3 @a/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。
0 P( i# U" f! B+ V% Vb/ 当2(n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。 + @/ k9 e8 g' o7 |' w" ^
c/ 当2(n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。 3 n* E z5 f6 ^$ w2 A
具体一点:
( u+ Q6 {/ u C0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为2、3、4号的中断;…..构成中断嵌套。 " \; x8 R5 D& o* T% _
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。
" p: A5 M7 T# A3 N3 |" [- {: G
& {$ }! w/ S( U! l3 H$ P9.上电RESET后,AIRC中PRIGROUP[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讲,外部中断通道位置28(35号优先级)是给外部设备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# ~
2.cortex_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中有13个bits,它们是PRI_28,8个 bits(只用高4位);中断通道允许,中断通道清除(相当禁止),中断通道Pending置位(我的理解是中断请求发生了,但当前有其它中断服务在执行,你的中断级别又不能打断别人,所以Pending等待,这个应该由硬件置位的),中断Pending位清除(可以通过软件将本次中断请求且尚处在Pending状态,取消掉),正在被服务的中断(Active)标志位,各1个bit。
( |+ 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, E4.在弄清楚2、3两点的基础上,我们可以看看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
设置AIRC中PRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4个bits中占用的位数) : | m% |7 u- _' K; B% P8 r
设置TIME2本身的寄存器,允许相应的中断,如允许UIE(TIME2_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- }
当TIME2的UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。 9 V) X" k/ E( f U* V$ V
此时硬件将TIME2的Pending标志置位,相当与中断通道标志置位,表示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中断正在被处理。同时硬件清除TIME2的Pending标志位。 ! ^6 ^( `! M i+ I" M! }" `6 A
. p* Z" }$ z7 ~% }/ cc/ 执行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 还有中断在申请,则重新将TIME2的Pending标志置为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 jSysTick 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 OIrq 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 yIrq 0 to 31 Set Pending Register Read/write 0xE000E200
2 U1 h; G J' o, G5 s. . . . .
/ T; ^* S2 O* T! _( O# K" D ~- rIrq 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 lIrq 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) LIrq 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, RIrq 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 `2.Stm32中用了那些 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/ 寄存器ISER、ICER、ISPR、ICPR、IABR在STM32中都使用的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的允许位。ICER、ISPR、ICPR、IABR的结构相同,只是含义不同。
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 | 2 {" p) e9 D& _
|
* {+ O- R! t) n% e8 A8 h4 W9 b; H |
4 v% w; l" Z j- ]/ ] | ; 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 | * 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 | 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" Qc/ 在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 dtypedef 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它就是地址在0xE000ED0C的32位寄存器AIRCR(Application Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4位bits,起可能的值如下(来自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 |