EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、基本概念
% K, Z1 ^7 Q* R2 [ 1. ARM cortex_m3内核支持 256个中断( 16个内核 +240外部)和可编程 256级中断优先级的设置,与中断控制核中断优先级控制的寄存器( NVIC、 SYStiCK等)属于 cortex_m3内核的部分。 STM32采用了 cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。 3 s5 S# z, w) B, \1 B2 X' s* X
& G, {+ v5 `# D8 l& O0 z1 J+ j2.STM32目前支持的中断共为84个(16个内核+68个外部),和16级可编程中断优先级的设置(仅使用中断优先级设置8Bit中的高4位,见后面解释)。《参考最新101xx-107xx STM32 Reference manual, RM0008》。
1 R f9 V+ q/ U4 j3 g9 l" |& c
$ j3 h( ?+ b0 l3 Q/ y7 @0 c8 ^以下主要对外部中断进行说明。 2 H! V# Q6 K- o3 _, w$ H; j% F$ e
8 f7 P- l/ @1 x/ _# I; Q
3.68个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。68个通道的优先级寄存器至少有是17个32位的寄存器,它们是NVIC寄存器的一部分。
% _% K" F p$ i5 W 1 o+ q" `5 E7 k5 W# o
4.这4bit的中断优先级控制位还要分成2组看,从高位开始,前面的定义抢先式优先级,后面为子优先级。4bit的组合可以有以下几种形式: 6 Y' n( J+ g. G1 }* z7 J' l$ [
. U) }9 a( \% z2 s) A+ ?" M编 号 ' [; y& C8 [. r+ W; E: C* \' F
| 分配情况
* q- t5 I4 W) g# b. Z 0 ]& G: @ o7 C$ U' c8 N S
|
( ~8 h% H# s4 b ^, c8 u | 7
% R4 [& n$ L9 ?1 n! w- n/ _ # Y* S M- _5 V5 E
|
7 \& b% r h# T, J | 无抢先式优先级,16个子优先级
" A( M! t" E: |% r4 c M - b8 b6 O/ F% a& @1 d0 ^1 g
|
- s# ~! F/ K& u9 H L9 S- c [0 f8 s |
' n% j& N+ Q0 {+ m7 h2 N9 a" _* q | 2个抢先式优先级,8个子优先级
1 r* @& h: v# V J3 d
2 ?& _9 ?* G& r8 p; H) M |
6 t9 C! U7 _, ] | 2:2
% e. q/ _* V: \, S* X K; ^ 8 `, o: W9 o; J+ l D4 Z
| 4个抢先式优先级,4个子优先级
) V5 V9 ]$ g: q' O3 J$ f$ x
" i% H) z; \1 G4 G7 y | 4 3 t) T. D9 q" |# g: Q5 P
8 j7 P7 {7 ~7 c# X8 O
| 3:1
/ C# @: x9 }5 E! M9 ~ 3 L# w3 q8 S9 [% y5 U
| 8个抢先式优先级,2个子优先级 2 j. Y! j% Z; X% _ d
2 G6 y! N% b1 W: a& f
| 3/2/1/0
; j+ m6 _! j8 B: u7 J 5 L8 L7 j) V# Q
| 4:0
/ b8 R1 V+ S4 V+ H6 U# c- Y ]: [
. t6 h7 p7 P3 R9 ?5 T | 16个抢先式优先级,无子优先级
1 b. Y& {) r f4 h5 y! E" q
3 L( ]6 }; N& z8 J W |
! K) ]& T1 |# [8 F$ p! _
5.在一个系统中,通常只使用上面5种分配情况的一种,具体采用哪一种,需要在初始化时写入到一个32位寄存器AIRC(Application Interrupt and Reset Control Register)的第[10:这2个位中。这3个bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。比如你将0x05(上表的编号)写到AIRC的[10:中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。
6 j" H0 Y& {+ x
! u0 L1 W" e5 b4 z0 k4 J6.AIRC中PRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将0x05写入了AIRC中PRIGROUP,也就规定了当前系统中只能有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级,他们分别为: ! O' Q% Q! J! {4 z& _
位[7:
0 M6 `# @9 n2 G, {: @& n) T/ h3 a, K | . b2 v/ [0 F+ {1 p4 w
| 位[5:
) {& N4 h7 ^9 |3 f, e6 \% [ 0 K! r0 l5 f1 X
|
. N4 I/ ?! [( u1 z: A | 位[3:
; L' r4 S. x7 @, H% \1 n 9 U% W7 l3 c- e
| 00 1 g; ] h1 z7 s/ s3 k% X( k* O
/ k# N1 H$ N$ D' d3 E$ H' I
| 0号抢先优先级
5 _( z j& u* q/ U 4 i8 v1 v7 ~- I+ i* X1 K/ I z9 c
|
, ? Y2 q. L. Q | 0号子优先级
0 @* x# }; e9 Z8 Y
( ]+ u& ^* s, k | 无效 9 c8 g" O# X. S5 C2 h: l* }
1 L9 \# E- s& {- H |
( d1 G) b" V8 x0 |; B | 1号抢先优先级 ) N. n1 t- H; V" D$ o( e
9 I8 n1 ~0 V4 [ |
3 O2 ]* n( K# R1 [9 s0 D8 T | 1号子优先级
1 D7 ? T1 ]" |8 t- S5 D3 i
x6 ^$ j: s9 W$ t | 无效 ' W( B' L- Z9 N7 M" O7 c" |' U1 L9 [1 W
' _6 k% y# L; E, O Z: T! }3 K | 4 ^$ \3 s3 \) c* r- H+ ]* m1 W- R
| 2号抢先优先级
5 Y) {8 K7 U, v% w $ F" G/ T5 b4 i# Z. s
| 10 * y" M0 @" L1 l3 _: L) O7 Z
7 \5 A- W$ ^9 Z5 Z
| 2号子优先级
! s0 x% H& j+ _# b* ~ $ T6 \! ~6 E8 K0 f
| 无效 * |/ j3 a3 i- }4 k! L9 J
; z; @/ V8 H# K# e" a0 `& ]9 } | 11
6 T9 r) x9 Q S8 d0 w3 T1 p ' D/ z; C# N/ I C3 ^4 @
| 3号抢先优先级
2 V; t; x) X' g Z' r ! ], \$ W* J3 X
| 11
2 I9 c U6 T( ]8 q5 ?, r3 R( ]3 I 4 C$ I# d0 G, G7 L6 f
|
6 `( ]% H; H" Y. R. P8 ]$ ` | % [' U' F% C9 t# b
|
7.如果在你的系统中使用了TIME2(中断通道28)和EXTI0(中断通道6)两个中断,而TIME2中断必须优先响应,而且当系统在执行EXIT0中断服务时也必须打断(抢先、嵌套),就必须设置TIME2的抢先优先级比EXTI0的抢先优先级要高(数目小)。假定EXTI0位2号抢先优先级,那么TIME2就必须设置成0或1号抢先优先级。这些工作需要在AIRC中PRIGROUP后进行设置。
- H5 X% r; e6 A% G) b1 e # t$ r& ^3 s: v' u* p/ F6 _
8.具体优先级的确定和嵌套规则。ARM cortex_m3(STM32)规定 9 N) X, g+ S" }3 i. E w# D# W
a/ 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。 * F# U, S/ g$ S6 t" P! q
b/ 当2(n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但STM32首先响应子优先级高的中断。
9 l ~ {+ d* p$ _5 h9 ]! P6 w Qc/ 当2(n)个相同抢先优先级和相同子优先级的中断出现,STM32首先响应在该中断通道向量地址低的中断(ROM0008,表52)。
$ q2 H( Z- g$ p3 p+ \8 W具体一点:
! q9 E# D% V; r$ |9 H0号抢先优先级的中断,可以打断任何中断抢先优先级为非0号的中断;1号抢先优先级的中断,可以打断任何中断抢先优先级为2、3、4号的中断;…..构成中断嵌套。 9 ~4 f4 k1 U. h6 r
如果两个中断的抢先优先级相同,谁先出现,就先响应谁,不构成嵌套。如果一起出现(或挂在那里等待),就看它们2个谁的子优先级高了,如果子优先级也相同,就看它们的中断向量位置了。 0 G! j. o% m- S: C, T
1 S: Z7 V* e% H3 A1 _+ s+ X* v2 ~" S; p
9.上电RESET后,AIRC中PRIGROUP[10:,因此此时系统使用16个抢先优先级,无子优先级。另外由于所有外部中断通道的优先级控制字PRI_n也都是0,所以根据上面的定义可以得出,此时68个外部中断通道的抢先优先级都是0号,没有子优先级的区分。故此时不会发生任何的中断嵌套行为,谁也不能打断当前正在执行的中断服务。当多个中断出现后,则看它们的中断向量地址:地址越低,中断级别越高,STM32优先响应。注意:此时内部中断的抢先优先级也都是0号,由于它们的中断向量地址比外部中断向量地址都低,所以它们的优先级比外部中断高,但如果此时正在执行一个外部中断服务,它们也必须排队等待,只是可以插队,当正在执行的中断完成后,它们可以优先得到执行。 , a3 d# V/ K6 a' w, I0 b) E- ]
7 I1 b* ~- J J' p
! q* n' c& L0 I2 Y; y4 @了解以上基本概念还是不够的,还要了解具体中断的控制有那些途径,中断服务程序如何正确的编写。下面的描述主要以TIME2通道为例。
0 i4 C5 u7 j' q8 e 4 T: M# k! a+ m, z( S
二、中断控制 ( S! U' u0 u3 ]! g! S! g
1.对于STM32讲,外部中断通道位置28(35号优先级)是给外部设备TIME2的,但TIME2本身能够引起中断的中断源或事件有好多个,比如更新事件(上溢/下溢)、输入捕获、输出匹配、DMA申请等。 6 P" f9 N5 i- {' _5 z/ G5 `9 p/ ?+ V
(题外话:就一个通用定时计数器,比8位控制器中TIME要复杂多了。学过AVR的,可能对输入捕获、输出匹配等还有概念,如果你学的标准架构的MCS-51,那么上手32位控制困难就更多了。所以我一直推荐学习8位应该认真从AVR开始,尽管51有很大的市场,价格也相对便宜些,但从发展的眼光,从后续掌握32位的使用,AVR是比较好的选择。) / f! d* X8 N9 P+ B# ~1 M
F! ?/ ]7 q- l% F! n1 W 所有TIME2的中断事件都是通过一个TIME2的中断通道向STM32内核提出申请的,那么STM32中如何处理和控制TIME2和它众多的、不同的、中断申请呢? ' P0 W0 N1 ]1 a2 |9 D ^, \0 b
& |# g, j% ]$ P( c
2.cortex_m3内核对于每一个外部中断通道都有相应的控制字和控制位,用于单独的和总的控制该中断通道。它们包括有: $ j! y4 N7 f& m+ I6 b1 r
中断优先级控制字:PRI_n(上面提到的)
/ r4 t& D1 O, e中断允许设置位:在ISER寄存器中 # E' f% j* B% x( M5 |8 [+ s$ {
中断允许清除位:在ICER寄存器中
! m3 Q% S1 t' c% L1 C( y) c; p中断悬挂Pending(排队等待)位置位:在ISPR寄存器中(类似于置中断通道标志位) 1 y" K7 n7 Y s6 t* e( s
中断悬挂Pending(排队等待)位清除:在ICPR寄存器中(用于清除中断通道标志位) : o' a q* m- K( K
正在被服务的中断(Active)标志位:在IABR寄存器中,(只读,可以知道当前内核正在处理哪个中断通道)
* {3 U$ ]: Z; A' S , ~* u L2 x- R
因此,与TIME2中断通道相关的,在NVIC中有13个bits,它们是PRI_28,8个 bits(只用高4位);中断通道允许,中断通道清除(相当禁止),中断通道Pending置位(我的理解是中断请求发生了,但当前有其它中断服务在执行,你的中断级别又不能打断别人,所以Pending等待,这个应该由硬件置位的),中断Pending位清除(可以通过软件将本次中断请求且尚处在Pending状态,取消掉),正在被服务的中断(Active)标志位,各1个bit。 & G/ u) [8 F7 N! c6 i U( V
/ [/ B1 a. J* p! |
上面的控制字和控制位都是在NVIC中的寄存器组中,可惜的是在STM32中竟然不给出任何的解释和说明。 $ R, M7 q" f% X( H, O$ w, Q* l
3 H( _5 e6 T+ r( S! V3.作为外围设备TIME2本身也包括更具体的,管理自己不同中断的中断控制器(位),它们主要是各个不同类型中断的允许控制位,和各自相应中断标志位。(这个STM32的手册中有详细的说明了) " y. C) `4 t& z& H$ M x
1 M* V8 L* S* |
4.在弄清楚2、3两点的基础上,我们可以看看TIME2的中断过程,以及如何控制的了。 8 ] g/ @. J# h# v- x; C6 ^) s7 s
( W4 ]! m) m" J ]0 _
a/ 初始化过程 4 e4 M, a+ k m
设置AIRC中PRIGROUP的值,规定系统中的抢先优先级和子优先级的个数(在4个bits中占用的位数)
1 H. P4 \$ S7 h设置TIME2本身的寄存器,允许相应的中断,如允许UIE(TIME2_DIER的第[0]位) & v' h" p8 Q3 t0 n
设置TIME2中断通道的抢先优先级和子优先级(PRI_28,在NVIC寄存器组中) + ^% {: p4 S0 j8 \. a0 F* p
设置允许TIME2中断通道。在NVIC寄存器组的ISER寄存器中的一位。
% G: A: M2 H+ M3 Z" K u& ?* |( V/ l3 L s% `2 |- P; V; f" ]
b/ 中断响应过程
+ n. E k* `! C7 a4 m- ]9 |当TIME2的UIE条件成立(更新,上溢或下溢),硬件将TIME2本身寄存器中UIE中断标志置位,然后通过TIME2中断通道向内核申请中断。 5 w4 R4 s! J4 E; U
此时硬件将TIME2的Pending标志置位,相当与中断通道标志置位,表示TIME2有中断申请。
" C+ l2 l; k- S: A. S如果当前有中断在处理,TIME2的中断级别不高,那么就保持Pending,当然软件可以通过写ICPR寄存器中相应的位把本次中断清除掉。 + b$ e9 O( o. u) D0 U
当内核有空,开始响应TIME2的中断,进入TIME2的中断服务。此时硬件将IABR寄存器中相应的标志位置位,表示TIME2中断正在被处理。同时硬件清除TIME2的Pending标志位。
7 w7 ]" y- C: v9 H: A. q ) V5 V7 J% a# d Y0 m. ~/ y# E- e; Y
c/ 执行TIME2的中断服务程序
& o8 R0 `/ b0 Z ]所有TIME2的中断事件,都是在一个TIME2中断服务程序中完成的,所以进入中断程序后,中断程序需要首先判断是哪个TIME2的具体事件的中断,然后转移到相应的服务代码段去。 ; r( I: f# X3 B; f
注意不要忘了把该具体中断事件的中断标志位清除掉,硬件是不会自动清除TIME2寄存器中具体的中断标志位的。 ' i: }( C, j9 @, k$ p" n
/ h g& K' J; l+ \3 u$ j2 |
d/ 中断返回
3 G- h4 `+ ^0 B+ d0 o执行完中断服务后,中断返回过程,在这个过程中需要:
( S" h3 q( M: w' z% R硬件将IABR寄存器中相应的标志位清另,表示该中断处理完成
( Z5 x+ D# X6 O2 {% ^0 m如果TIME2本身还有中断标志位置位,表示TIME2 还有中断在申请,则重新将TIME2的Pending标志置为1,等待再次进入TIME2的中断服务。 8 ^1 Z' p2 q. R" O5 [
) A& _' m Q0 P! O- r# p6 A0 B
注意:以上中断过程在《ARM Cortex-M3权威指南》中有详细描述,并配合时序图说明,可以参考。
3 n; u7 O; F" h* f& B5 g8 J# u , z( ^& Q" J: f7 U, Q9 w
如果以上明白了,那么可以在ST提供的函数库的帮助下,正确的设置和使用STM32的中断系统了。
$ E4 o4 D2 o$ r# _+ w! W* Q5 N ' E; m7 k4 k* h; x
如果你要了解更深入的东西,或者直接对寄存器操作,还要继续望下看。
; O# V* r! F' Y4 c0 C& d1 d, g' { 1 ^8 |9 I- W9 U2 u! x
三、深入NVIC , `3 r: C* @8 m* C+ Y
# e0 F! S! Q: q* f
1. 看看Cortex-M3中定义与NVIC相关的寄存器有那些
4 E+ ^+ Z5 W2 w5 \SysTick Control and Status Register Read/write 0xE000E010
& R0 y/ p/ N3 {. o0 S1 BSysTick Reload Value Register Read/write 0xE000E014 1 `6 B* x# o: k% n$ o; w
SysTick Current Value Register Read/write clear 0xE000E018 , m2 _& p9 w% _# _1 Z& l
SysTick Calibration Value Register Read-only 0xE000E01C
* U) o. S) s& i/ {9 L( [0 w' M! M( m- E! H5 _ Z1 q6 T
& T7 ~0 V, Z, f/ J8 P; cIrq 0 to 31 Set Enable Register Read/write 0xE000E100 $ _' ]# S" a8 z9 r# V4 I
. . . . . . D; Q2 i: P- K) V6 g
Irq 224 to 239 Set Enable Register Read/write 0xE000E11C
* t( J4 t- ?$ O0 p3 d% u1 G
4 _" ~- y* _2 B6 y; S+ G3 w9 u M
1 Z1 I" l+ I) }: m; s6 CIrq 0 to 31 Clear Enable Register Read/write 0xE000E180
" R2 a. [1 b& P) @. . . . . - {6 W$ i {5 d2 U
Irq 224 to 239 Clear Enable Register Read/write 0xE000E19C
% P6 E1 A) i7 ?* y6 n" [
7 T0 Q, h. x+ k* E+ v$ N/ n5 Y( j9 U5 H1 k& j6 s3 B$ s% y4 U
Irq 0 to 31 Set Pending Register Read/write 0xE000E200
: ^+ f* i( u- s1 R2 t, j& Q! W0 M. . . . .
! A/ A: c0 y, b# k BIrq 224 to 239 Set Pending Register Read/write 0xE000E21C
/ h4 {6 d/ ?- v6 i; |( B$ u$ G5 V! Y. M% i$ h, Z! Y. I- U( O
7 h5 j5 i) b. ?$ r7 gIrq 0 to 31 Clear Pending Register Read/write 0xE000E280
2 W4 |1 E! A* O! _. . . . . ' K' G& D) Q/ t# w: F6 v
Irq 224 to 239 Clear Pending Register Read/write 0xE000E29C
/ @% u0 q8 B) _" u' i A2 o
0 v7 R, q8 H9 b
* p& h9 z3 c1 Y8 P
7 V3 {, j6 l4 i( S- [( U" h. A, [
Irq 0 to 31 Active Bit Register Read-only 0xE000E300
$ e8 W5 R, }- D' f4 ~. . . . . . / \" D) N0 k1 S. Z) c( l
Irq 224 to 239 Active Bit Register Read-only 0xE000E31C 0 V' G+ {) X+ j: l$ `; W
( t% @" ? w% G: V7 g, T& t
" s8 O2 a. G0 z- _2 o" a% {* R3 {Irq 0 to 3 Priority Register Read/write 0xE000E400 6 i( R) m1 v) e o! V, H
. . . . . 9 u I7 r5 ]+ @! u7 {/ P
Irq 224 to 239 Priority Register Read/write 0xE000E4EC - H: e3 k' s2 O) D) v* v) e7 T# R6 @! E' Q
0 |& I: u) [6 M* Y) X
3 C8 x! v; _; i& y3 z7 bCPUID Base Register Read-only 0xE000ED00 " x0 Y. ]9 h2 Z) t/ b
Interrupt Control State Register Read/write or read-only 0xE000ED04 2 I; U. F- L9 f! g c
Vector Table Offset Register Read/write 0xE000ED08
$ F, Y& `% M( B O% X% |- AApplication Interrupt/Reset Control Register Read/write 0xE000ED0C
$ a9 x7 \9 g/ D% F" ?) ?System Control Register Read/write 0xE000ED10
* q; D* u. N% H% L. bConfiguration Control Register Read/write 0xE000ED14 " h: K% x7 l+ [, L2 G1 V/ g2 D2 S
System Handlers 4-7 Priority Register Read/write 0xE000ED18
% z+ Y3 X. w9 s) h/ o+ N( U0 FSystem Handlers 8-11 Priority Register Read/write 0xE000ED1C # [" Y9 s1 ~8 S* l
System Handlers 12-15 Priority Register Read/write 0xE000ED20
& R) z4 |9 S+ _( `5 W4 v. . . . .
! p5 q7 x; u" A 1 S5 K. J4 [; I' a8 L
2.Stm32中用了那些 6 u4 ]- z+ J0 e+ P9 L5 f
# C- H6 \+ w$ I% G; N* P下面是从ST公司提供的函数库的头文件得到的,库是v3.1.0
2 b& _# f W( P$ K# |6 l) f/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
9 K' U; b: h5 }/ ]1 P2 Atypedef struct
0 C5 l! P+ C' |* M4 W- c{
. Q2 R* x+ \8 |3 n! A2 Z) X' [ __IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */
9 I+ H! e# B. e9 B6 D uint32_t RESERVED0[24]; : f' [0 z/ |& U- X: `- Q& p
__IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */
* V* | _' r% a+ b uint32_t RSERVED1[24]; ( l, F, Q0 N7 v
__IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */
) t, C8 C* `' _7 P1 t6 ~7 p uint32_t RESERVED2[24]; 4 Z8 ]/ v* p# `: B- b
__IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */
9 O7 F$ Y1 ~9 j0 i! c8 b uint32_t RESERVED3[24]; _6 h7 t7 q( X5 c4 T
__IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */ 5 D& ?1 H3 c2 Y/ _8 B! N
uint32_t RESERVED4[56]; & X+ M; e: I4 X3 J2 S
__IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */ 3 C, n$ `. i; @: B) _* _# q$ L/ X
uint32_t RESERVED5[644];
, w+ S# ]$ e0 X: a/ t: X __O uint32_t STIR; /*!< Software trigger Interrupt Register */ ! _6 {$ {; X* L: |* D6 C! m: e
} NVIC_Type;
: t3 o3 C! m f' J7 k7 _6 J
- X% Q/ `- a) ]; z. Za/ 寄存器ISER、ICER、ISPR、ICPR、IABR在STM32中都使用的8个(实际3个就够了,后面的将来还要扩充?)。这些32位的寄存器中每一位对应了一个中断通道相应的标志。 ! z" v8 N1 ~$ c! _; |2 g
比如地址在0xE000E100的ISER[0]这个32位的寄存器,第0位是中断通道0的允许位,第2位是中断通道1的允许标志……第32位是中断通道31的允许位;接下来地址在0xE000E104的ISER[1]则是中断通道32-63的允许位。ICER、ISPR、ICPR、IABR的结构相同,只是含义不同。 # w0 s- K& G5 T+ C9 h
0 h) J% R' D1 ~- o+ c
注意是对这些寄存器的操作:写1表示置位或清除,写0无任何影响。
2 N' P# a; E4 t" m8 S, }" N. B' z
" H- I/ m5 [( z( q% ]' u
例如: 9 Z# W1 v7 Z6 x, j
对0xE000E100的ISER[0]的第0位写1,表示允许中断通道0中断;
0 Z# b" u: V/ r! r l$ G1 \# W% t但对0xE000E100的ISER[0]的第0位写0,则没有任何作用,该位保持不变。 ) T" o2 Y5 P0 t8 W' S+ x
如果要禁止中断通道0的中断响应,那么就必须:
5 F( A0 G+ v8 B. l2 D, S; h对0xE000E180的ICER[0]的第0位写1,表示禁止中断通道0的中断; : y1 u' z; @( a/ m. c
对0xE000E180的ICER[0]的第0位写0,也是不起任何作用的。 8 N' D, P7 p. V( F
' M+ d; v+ N5 ?! F; K" X+ C2 w9 B
4 o% U9 L8 S! Db/ IP[240]用于定义240个外部中断通道的优先级,每1个字节对应一个通道。4个通道的IP[]构成一个32位的寄存器。在STM32中最多有68个外部中断通道,每个IP[]的1个字节中只使用高4位(见前面介绍)。IP[]的结构如下: 2 Q O& b" g( ?* E
( k; W) T6 y( f1 j 4 ~) \2 F7 {2 z
% U) b" {/ I8 h0 K1 ?9 Y
" P! P, B$ N# @ | 31:28
( H$ x2 |$ o ~! Q5 p
# \4 [0 s- o& W | 27:24 - D X8 E2 |' s9 I) ~
9 r& b5 t8 x* A( c3 `* ]
| 23:20 . T3 O8 g) q% \+ ], A; n. l' Z
/ s0 M" B z! p% R! N | 19:16
0 v- t. I0 \0 i% m! G/ K
4 R7 C( W* x8 ?2 s2 v |
0 w9 [6 F* y$ p" h# @0 r |
8 x3 H( k6 A) b7 p* B$ ` |
, e O- d. d7 ~6 [ | 3:0 - L5 l1 Z# B& E' \9 t( Y( R2 f
1 p# [6 W9 w; x8 l4 X1 L | & I# k9 O7 Y/ H6 V$ J, ^( y' Y
; p; |; n( W- ~# ^
|
( X D. `1 c9 D1 `0 \/ k | PIR_3 ; y" a; C9 O7 d1 _+ }$ e
$ R) D* F% d* o' ]2 s! s
| & z" t# k2 M/ ?) Y7 R
|
( B/ T! \' u$ Q) h O | PIR_0 ' C& Q! | e, ]0 @" X# G3 p
. q- x% @: ~7 K | 每8位的高4位有效,灰色位表示无效 3 \+ P5 b% t6 ?$ q. T( b% u
$ \: H( `0 `! M1 @$ m8 P! Z+ @/ I. K
| E000E404 2 V' V9 V0 g( R, [! x
* R2 \( }8 K8 K% A/ P
| PIR_7 9 x) I# H' k) m3 w$ g
3 U3 p ?' m' l& y9 n# N
| PIR_6
- E2 r7 s8 B' ~& }$ ^: U) t; z8 l
& X7 v( A8 b# W | PIR_5
8 K$ I G8 h# G" c1 ?* Q. E) D1 ]- S 6 L( `" V0 X1 K/ R/ k$ T" U. p
| PIR_4 9 ]$ N( ?; ^3 S. b# S
/ t# }1 W, A5 C8 q( \( @: `: J
| % z. ^9 i7 D) d/ L
|
8 h: U7 k. m5 V' I2 Y | ……
) d6 |4 t5 T) H/ N: }; D 2 b/ A: B" H9 e. N0 Z6 f1 o3 I8 n- h* V
| $ A! N3 ~4 g: g+ S
| 0 {" n0 _' ~' u' y
|
. k4 E# ]6 F- @0 n$ R: u! e. n
c/ 在ST公司提供的函数库的头文件中另一个数据结构中,还有一个寄存器需要关注 :
; Y1 G. S! F7 i8 W9 Q
3 j1 F: N" w% n! k( N w! i. V: k+ K
/* memory mapping struct for System Control Block */ ) x! N( ^! o* ~# X; [8 J" N) D% V
typedef struct % _! b n% s, E0 H4 x
{ % t3 _3 F0 r! _/ Q8 ?& J$ j
__I uint32_t CPUID; /*!<CPU ID Base Register */
4 [9 U$ V9 y% x# P__IO uint32_t ICSR; /*!< Interrupt Control State Register */
) A7 P, f* F W8 U__IO uint32_t VTOR; /*!< Vector Table Offset Register */ 4 Y9 V y2 \% c" \& S, c) R
__IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */
9 n3 c* H1 a! T7 i, }1 _/ ~__IO uint32_t SCR; /*!< System Control Register */
$ V. ^, G$ u. a. Z__IO uint32_t CCR; /*!< Configuration Control Register */
# G& g- A5 e2 f" I- Y% X1 I# Y4 ?__IO uint8_t SHP[12]; /*!< System Handlers Priority Registers (4-7, 8-11, 12-15)*/ : i# Z* h7 @$ s6 @
__IO uint32_t SHCSR; /*!< System Handler Control and State Register */ * U5 c& c r4 p
__IO uint32_t CFSR; /*!< Configurable Fault Status Register */
8 U2 ]2 f) h* I; b__IO uint32_t HFSR; /*!< Hard Fault Status Register */
- h9 u$ W- {# G; m0 p$ H__IO uint32_t DFSR; /*!< debug Fault Status Register */ 3 d$ t) f4 Y8 E& L
__IO uint32_t MMFAR; /*!< Mem Manage Address Register */
. \! E( K& N$ z& f7 M__IO uint32_t BFAR; /*!< Bus Fault Address Register */ , f$ v0 A' S0 D+ [/ g! }) `
__IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */
2 f6 x! ~6 Z6 u+ c6 g! u0 ___I uint32_t PFR[2]; /*!< Processor Feature Register */
6 A( R8 i& c$ @- v8 s) q( Q__I uint32_t DFR; /*!< Debug Feature Register */ 4 N" G' R) S v# {: B J
__I uint32_t ADR; /*!< Auxiliary Feature Register */ + `) Q$ p z& a/ v. E
__I uint32_t MMFR[4]; /*!< Memory Model Feature Register */ : Q4 i* w- v5 f4 V
__I uint32_t ISAR[5]; /*!< ISA Feature Register */ , a; G" e4 p/ t5 Z8 e# m* K. r
} SCB_Type; ( B$ V5 L# B( |! `9 E# D
. h. r6 s1 {3 _
8 P1 ~; b N! Y) M它就是地址在0xE000ED0C的32位寄存器AIRCR(Application Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定义位值,它规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4位bits,起可能的值如下(来自ST的函数库头文件中的定义) 6 y. ^/ ?: t* t3 {0 T. q" Y
# ]0 a/ o: q* X#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority % P1 Y$ t7 K: X& r, E
4 bits for subpriority */ - ~. |7 {# Z2 O- |
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
8 Y8 \5 P. ]0 m7 {. c# z4 w/ {& ` 3 bits for subpriority */
' a3 V0 q- x* F; N#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
! j/ L+ @ {4 B4 l( `2 G! A 2 bits for subpriority */
: {4 ^- {5 g$ F3 w b V; z. J& [#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority ' h M" n+ O9 i. |
1 bits for subpriority */
) p3 B# E+ e: V+ m1 ?% h6 ?#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
- [& p. E0 Y; @9 ~& T+ @3 ~7 [2 I( } 0 bits for subpriority */
+ } V: |& w6 c, Z' T4 _/ ^6 O/ v2 D" T' N5 Z S
- c- |( O1 }" F1 h
由于这个寄存器相当重要,所以为了防止误操作(写),因此要改写这个寄存器的内容时,必须同时向这个寄存器的高16位[31:16]写验证字(Register key) 0x05FA。
( p" g; O* A. D# y: O. O' q. }2 Q0 Z* Q" @( e: ~7 n1 |( F4 T& U3 i
3 x# h, ~7 N A3 }. a) C4 e6 U
例如:SBC->AIRCR |= (0x05FA0000 || 0x300); // 设置系统中断有16个抢先优先// 级,无子优先级
6 g. T5 y! T! x. _$ V1 W7 x
( P: M2 P" b4 ^' O
1 E, [3 N$ e1 l3 C0 w
4 M: ?# X! U# ^# ud/ 下面的定义与SYSTICK相关,有时也会用到的。 ! T$ S0 J0 q3 k) S7 g9 K9 L
/* memory mapping struct for SysTick */ 3 ]6 o6 [6 x% E" Z5 g( o3 ^
typedef struct 6 d$ T5 d( J/ m( i0 `7 u
{
3 p- U9 x/ w, [+ F0 v __IO uint32_t CTRL; /*!< SysTick Control and Status Register */ 6 ?- d( \. ?. q0 e
__IO uint32_t LOAD; /*!< SysTick Reload Value Register */ # E. Q$ ?4 r. ^( H4 i" m
__IO uint32_t VAL; /*!< SysTick Current Value Register */ 1 a7 ]3 F7 |7 i( u# P; R9 S: z
__I uint32_t CALIB; /*!< SysTick Calibration Register */
; i4 W; c5 p/ P} SysTick_Type;
- G1 B. x# {" n+ `; E5 d) v8 {; E |