
Cortex M3内核支持256个中断,其中包含: 16个内核中断 240个外部中断- x. S2 D5 F- u: H3 h 并且具有256级可编程中断设置 4 Z7 m) c5 H2 c% ^& J* @ STM32F1并没有使用Cortex M3的全部0 K$ F/ [$ C3 O: F8 T- W STM32有84个中断,其中包括: 16个内核中断 68个外部中断(可屏蔽中断) STM32F103系列只有60个可屏蔽中断 * l) P3 M! L" d1 I $ b1 T* |) d8 } V* D 中断优先级分组% @. X% y" P7 d' r: y 首先,对STM32中断进行分组(在系统初始化时就分好组),组0~4.同时,对每个中断设置一个抢占优先级和一个响应优先级值 6 V+ s* q, d8 P: o+ P8 Z& y, w 分组配置是在寄存器SCB->AIRCR中进行配置+ D& t r( N, a! ?, g G7 J) j ![]() * M$ \" |( ]+ [# h 在SCB的AIRCR寄存器的8到10位可以对中断进行分组4 [8 u1 D0 j: Z0 X 假设被分到组2,意味着每个中断可以设置2位抢占优先级,2位响应优先级! T2 D# B# i2 ]" Q 对于每个中断,他有一个IP寄存器,4到7位,相当于一共4个位可以用来设置抢占和响应 STM32F103具有16级可编程的中断优先级,为什么是16级呢?# K: F& F( s0 e' z( J ( f+ L# s- g% D0 U% G* a 因为4个位可以用来设置抢占和响应2 V! n7 _, |# I0 g 2的4次方就是16 抢占优先级与响应优先级的区别3 E5 a2 x# b3 N. A 抢占优先级是指,两个中断,抢占优先级谁高,谁就可以抢占另外一个正在执行的中断,可以打断9 @( @: @/ h* u5 y. A( ~: t+ J 5 A) ^+ t6 S' A9 l' T) y5 ]8 t: ` 例如A中断的抢占优先级为0(优先级高),B中断的抢占优先级为3(低优先级),B正在发生,正在执行B中断的中断服务函数,如果A发生了,那么A是可以打断B的,执行完了再回去B2 ]' d( i* T% ^! R5 A $ y$ a2 R" i6 ]; \& s/ ` 抢占优先级相同的中断,高响应优先级的中断不可以打断低响应优先级的中断 抢占优先级相同的中断,当两个中断同时发生时,哪个的优先级高,哪个就先执行 2 a. M7 o b* M' D G8 i 中断优先级分组函数0 t) t! w- W6 X/ a; n5 w" e misc.c" H0 v& m O1 X8 T. ~( L$ x ![]() 5 a8 o$ c. D' I9 Z. y7 x) j: u ![]() 8 c2 d g2 v) _, v; o 中断优先级设置寄存器2 }# e) V. ~+ [/ g core_cm3.h ![]() 可以看到,有240个IP寄存器,即Interrupt Priority Register! J& X* g; ~3 D8 f! {4 f' { 7 |3 u& M3 T7 P H2 ] 240个8位寄存器,每个中断使用一个寄存器来确定优先级 STM32F10x系列一共60个可屏蔽中断,使用IP[59]~IP[0]" g9 f$ ], L) {9 c) v3 W \1 x; s; A 2 i& }3 j7 C* C8 o ![]() 3 L9 ~! i, J5 Y NVIC初始化 G5 p: j7 ]$ Y5 V misc.c ![]() ! c! ? S9 B& c& L$ K9 W; S misc.h, S, B( h" Q( r0 M ![]() . W1 {7 ?/ S: m% H4 B- @, _& s6 } ![]() ; u- A1 w- T+ y G ![]() 中断使能寄存器ISER寄存器+ ~' {, ?. A$ w1 V/ ?; \: `; X3 ? ISER[8]用于使能中断,共有8个32位寄存器 32位的寄存器,每个位控制一个中断的使能" s8 y5 F( p; b! e4 V STM32F10x只有60个可屏蔽中断,因此只能收了第1个和第2个寄存器,即ISER[0]和ISER[1]. m# ?# O8 _4 ?0 O6 o# J ISER[0]的bit 0~31分别对应中断0~315 y9 x) j* u: v9 p& z9 j+ C 5 ]) G! p5 ^, w: { ISER[1]的bit 0~27分别对应中断32~590 v. K6 d% h9 H' p7 ~* [1 H6 N 中断失能寄存器ICER寄存器 ICER[8]" T9 @. X! l3 f5 x$ q; } 其余上同7 n1 W! l# @ K. _4 m% c% u 中断挂起控制寄存器ISPR ISPR[8]4 g. H7 j" F4 u1 Y8 ]2 H 2 D) B7 m# u0 N! N C ![]() : z V9 e- x$ u7 a! v, J+ s4 X$ c 中断解挂控制寄存器ICPR- A3 E6 V& `5 x! o. Z8 ~ ICPR[8]: c. @( I; ~ P# h( H: N) [% M: R @ ![]() 中断激活标志位寄存器组IABR5 K2 v1 G& z6 I1 i+ e IABR[8]4 @# i9 C1 M' q2 D0 l! {9 O C 只读,通过读取该寄存器可以知道当前执行的中断是哪一个,如果对应的位为1,则说明该中断正在执行 9 F0 e/ a& Q0 Z- L; \ ![]() 中断配置步骤总结 1. 首先设置中断优先级分组,确定系统的分组级别,知道有几位抢占优先级和几位响应优先级可以设置(这里只需要设置一次)3 W" L" ^$ j% G G/ h 8 W: S3 {8 v& f T$ a0 @ }" v 2. 针对每个中断,调NVIC_init函数,给定想要的抢占优先级和响应优先级,对中断进行设置6 U, ^7 \/ ?. r8 U3 L$ z, u4 S * Z# J( _( o1 `9 P7 w3 b7 d 3. 如果需要挂起或解挂,查看中断当前的激活状态,调用相关函数即可 0 _4 X$ _1 O1 H0 @1 o 举例:) z* A3 ?' Y( O* Z! u main.c ![]() exit.c ![]() ———————————————— 版权声明:CodeForCoffee3 b+ h6 [6 |1 C8 u0 U |