EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、基本概念
, v1 U9 M. h0 P, [ 1. ARM cortex_m3内核支持 256个中断( 16个内核 +240外部)和可编程 256级中断优先级的设置,与中断控制核中断优先级控制的寄存器( NVIC、 SYStiCK等)属于 cortex_m3内核的部分。 STM32采用了 cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。
$ I7 f U4 g9 j2 Z! m
$ _% e. N3 J2 h% w& Y# j2.STM32目前支持的中断共为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
3.68个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是17个32位的寄存器,它们是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 _+ `+ |
| # 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
|
5 ~8 x" I9 k/ @; o4 U. `: D | 无抢先式优先级,16个子优先级 ( t* X" k8 O. M8 s
( R S" L6 N% _5 f |
( T- s$ x6 [; w$ l/ s* i |
; 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
|
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位寄存器AIRC(Application Interrupt and Reset Control Register)的第[10:这2个位中。这3个bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。比如你将0x05(上表的编号)写到AIRC的[10:中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。 * ~0 d5 P- Y+ K& {! P8 }
( t9 U" Q0 L8 n- C1 [" f( [* Q6.AIRC中PRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRC中PRIGROUP,也就规定了当前系统中只能有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
| b# J* k& l' Z2 M* X0 ~6 J5 ^" t7 G
| # Q0 @ T2 o, [3 m
| 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
| # 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 | 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 | ! 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 ^- ` |
2 P v1 p8 z& l! a8 t$ s. A$ P | ! 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的抢先优先级要高(数目小)。假定EXTI0位2号抢先优先级,那么TIME2就必须设置成0或1号抢先优先级。这些工作需要在AIRC中PRIGROUP后进行设置。
) ^% B! U! r* `- `" [5 ` 2 V0 G& D: ?* k0 o! `, C) ]
8.具体优先级的确定和嵌套规则。ARM cortex_m3(STM32)规定
# r& g7 n: Y6 ~' O: Ta/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。 9 ~, Q3 u4 W. @6 m0 P; C# \
b/ 当2(n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。
/ R. W: ~) J( p/ E5 z( L$ @& Cc/ 当2(n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。
6 c* r) v, K( K1 B) w8 z6 k具体一点:
9 ~7 W$ S5 N% N8 j a4 ^( \' Q; c0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为2、3、4号的中断;…..构成中断嵌套。 $ l6 j7 A/ M7 }3 {' Q
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。 n* [5 E; x. Q! C: Q
9 a$ H4 G( i9 z* p/ N9 y6 c- z9.上电RESET后,AIRC中PRIGROUP[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讲,外部中断通道位置28(35号优先级)是给外部设备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# ?) [2.cortex_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中有13个bits,它们是PRI_28,8个 bits(只用高4位);中断通道允许,中断通道清除(相当禁止),中断通道Pending置位(我的理解是中断请求发生了,但当前有其它中断服务在执行,你的中断级别又不能打断别人,所以Pending等待,这个应该由硬件置位的),中断Pending位清除(可以通过软件将本次中断请求且尚处在Pending状态,取消掉),正在被服务的中断(Active)标志位,各1个bit。
! 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 a3.作为外围设备TIME2本身也包括更具体的,管理自己不同中断的中断控制器(位),它们主要是各个不同类型中断的允许控制位,和各自相应中断标志位。(这个STM32的手册中有详细的说明了) / n @0 h. x( `' y/ Y
) f' g% n! K" T5 }, c! V* f4.在弄清楚2、3两点的基础上,我们可以看看TIME2的中断过程,以及如何控制的了。 ; e4 `' R" ~, v9 _' `
! h. i' u- }9 C( `7 T1 f1 b: ^a/ 初始化过程
^$ A' S! _6 q2 y: r设置AIRC中PRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4个bits中占用的位数) $ W: }6 S6 p) | g
设置TIME2本身的寄存器,允许相应的中断,如允许UIE(TIME2_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当TIME2的UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。 1 _8 W& n; ]( ~
此时硬件将TIME2的Pending标志置位,相当与中断通道标志置位,表示TIME2有中断申请。 0 f8 {- r; ]* k3 D5 I
如果当前有中断在处理,TIME2的中断级别不高,那么就保持Pending,当然软件可以通过写ICPR寄存器中相应的位把本次中断清除掉。
Y1 l6 r3 h$ s当内核有空,开始响应TIME2的中断,进入TIME2的中断服务。此时硬件将IABR寄存器中相应的标志位置位,表示TIME2中断正在被处理。同时硬件清除TIME2的Pending标志位。
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 还有中断在申请,则重新将TIME2的Pending标志置为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 xSysTick Control and Status Register Read/write 0xE000E010
! u- _* K& O6 G/ {! sSysTick Reload Value Register Read/write 0xE000E014
) C& p( c! }( a3 RSysTick Current Value Register Read/write clear 0xE000E018
* [5 f% g9 `# a Y1 Y* SSysTick 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: JIrq 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: FIrq 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* dIrq 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 UIrq 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) [- IIrq 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 UIrq 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/ vIrq 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 FVector Table Offset Register Read/write 0xE000ED08
7 N0 g2 X1 Z8 G+ ^2 {2 E$ {; dApplication 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( vSystem 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 RSystem 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
2.Stm32中用了那些 ! 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 wa/ 寄存器ISER、ICER、ISPR、ICPR、IABR在STM32中都使用的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的允许位。ICER、ISPR、ICPR、IABR的结构相同,只是含义不同。 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
| % i$ `: x( [; V( I6 }& R
| 27:24
& r9 {, _' J) X+ l1 B
1 g% I9 ^6 d! w/ f3 x8 n% R | o W0 l! R1 W* }& x
| 19:16 . i9 S* z$ W0 ^% B- q3 H( o, G
9 `# k) f) c. r; U; y
| , 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 E; Y7 F0 C2 q/ f# w* K |
$ 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% | | 3 l) T( K* I7 t. ]$ l& p: g1 @
|
% 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
|
: h. @ Z8 x* _7 X2 Y( X; B4 T |
3 s( z1 z& R) M; ]) J |
5 V( W9 L3 e3 x3 W& R- e |
. x7 j5 }+ d# O/ j! o0 `+ Y | ……
% ]% z: U# o+ D! J/ I. x
& {8 k2 C! C/ _5 S! Y) H1 `0 z | - 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# jtypedef 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它就是地址在0xE000ED0C的32位寄存器AIRCR(Application Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4位bits,起可能的值如下(来自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
|