你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 NVIC配置详解

[复制链接]
STMCU小助手 发布时间:2022-1-13 20:42
例程:  /* Configure one bit for preemption priority */+ Y2 W) z6 i& T( L
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
0 i1 y& ]6 v0 A/ R9 |( I7 a+ P  5 |1 k1 [+ s0 E  d1 `# K
  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */' K1 i/ ]% Y& y5 i: q. j+ n0 a9 D. }
  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;
1 U* {3 C5 b( m$ N- |2 D5 [& R3 |  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
  ?5 X2 {( |4 a  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;# n. r3 t# S3 o% K+ @# K6 B
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;: i# a* X9 Z5 S1 ?5 d  v4 w/ S" v
  NVIC_Init(&NVIC_InitStructure);
& X2 H; t; D- X' s$ c; J0 X  
; @2 I) t/ b( x0 ?" f! H  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */
$ T% F# m' j" C: a  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;
3 B3 N# q7 D# R: a" I  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;: x0 x( ~* g& }2 r( _! C
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;* g/ y  y- t% f# y- d5 Y
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;' Z: e2 c; B& `  k
  NVIC_Init(&NVIC_InitStructure);) y6 D7 w& D. i
  
2 L( h6 ?* k  F: Y+ [5 g+ R  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */
9 j, Z! c- g, D& ?  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));: y. [5 A! s& J1 u  d
3 G% ~8 u7 h/ s; i" l
这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。
! M, W! L! ]; D9 F/ x
        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。
       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。
STM32中指定优先级的寄存器为4位,其定义如下:
第0组:所有4位用于指定响应优先级9 ]! D# V( S& r- Q) |( z% }
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
4 i+ D5 ?0 t+ p' E7 Z  a6 d第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级3 f$ _' o/ ]# h3 n7 J* a# j
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
+ @0 R. b' u4 |/ X0 ?第4组:所有4位用于指定抢占式优先级
以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。
基础了解了就可以对中断进行操作了。
第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为
NVIC_PriorityGroup_0 => 选择第0组
+ h: O1 z' n, ZNVIC_PriorityGroup_1 => 选择第1组' F9 Z% f  i& ^2 W8 `2 i
NVIC_PriorityGroup_2 => 选择第2组
: \0 Z3 {5 X" X1 d+ p/ UNVIC_PriorityGroup_3 => 选择第3组7 y6 n8 r" A- @( E: Z+ ~/ w2 P8 g
NVIC_PriorityGroup_4 => 选择第4组
例如:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0)配置为0组。
第二步:中断初始化结构体配置,结构体类型定义如下:
typedef struct
{
  uint8_t NVIC_IRQChannel;                 
  uint8_t NVIC_IRQChannelPreemptionPriority;  //抢断优先级
  uint8_t NVIC_IRQChannelSubPriority;  //响应优先级      
  FunctionalState NVIC_IRQChannelCmd;      
} NVIC_InitTypeDef;

' s' j# ^9 B2 d" u$ p4 @
例如:STM32外部中断0配置如下
    EXTI_NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
         EXTI_NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级别(0~1)
         EXTI_NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;  //响应优先级别(0~7)
         EXTI_NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
9 @+ c/ W6 u' z7 B
第三步:中断初始化结构体初始化操作如下
         NVIC_Init(&EXTI_NVIC_InitStructure);

9 C$ _' _& l; n1 g9 _: Y. t
第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。
(1)   下面两个函数等效关闭总中断
void NVIC_SETPRIMASK(void); * n( M9 I( S) Z! u, m' i
void NVIC_SETFAULTMASK(void);
(2)   下面两个函数等效开放总中断
void NVIC_RESETPRIMASK(void);
/ _9 O5 F  `3 |: I, rvoid NVIC_RESETFAULTMASK(void);
(3)   常用操作是先关后开中断
NVIC_SETPRIMASK();     // Disable Interrupts 1 @' i  F7 f* b
NVIC_RESETPRIMASK(); // Enable Interrupts
两种类型函数要成对使用。
7 {* y% O6 z) t
STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下
" Q& C/ t" [) ^, Q% v! V; H8 @  ~" @9 z9 C- f
#define NVIC_PriorityGroup_0 ((u32)0x700)5 t$ a5 J+ y6 F7 C& B) ^& Z
#define NVIC_PriorityGroup_1 ((u32)0x600)6 u4 l' U% G7 W0 w
#define NVIC_PriorityGroup_2 ((u32)0x500)
6 a2 C8 z4 _  Z( S#define NVIC_PriorityGroup_3 ((u32)0x400)
* n3 P$ L4 J% N. E( _#define NVIC_PriorityGroup_4 ((u32)0x300)2 q; X1 k! Y- X
: ?( H% x' q3 H. `+ Q3 @7 ?6 Y
形象化的理解是:
! I8 |' \6 k0 H0 b, N! f
! c2 _8 a+ n# q& ]% C. l你是上帝,! \4 w, A& Q+ t" P* {, t0 B
造了43个人,这么多人要分社会阶级和社会阶层了;( I0 y; a1 c5 [9 `, X8 v2 f: w; X8 {2 O
因为“阶级”的词性比较重;"阶层"比较中性,5 \# ]; k! V& u- j& \- w* k
所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;6 u/ L5 y; h) w; c7 W3 o

$ s& h; n/ P3 m7 Z- g如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。( ?5 M: Q$ o5 \4 o: I& ~
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则
* i' R# o- s7 ], l  B- ^NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
$ f! g% n0 a% Q5 hNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15
2 {$ n  O8 j- r8 s! p  F- \3 {- w; ~* L3 g& V
另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)+ e3 r+ t; P# q4 j4 R$ q# c
还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;& E+ g. Y1 e6 _' C- h8 y# L+ u! [8 w" ~8 `
  ~4 C/ \0 i3 U  p7 B
又有1个人SPI1_IRQChannel,设定如下
1 Q/ t3 s: i0 X1 p7 O! L1 oNVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
9 n* Q- n5 b; jNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15
0 i2 Q0 w2 t% m3 b2 r; i- @" u2 z, G+ b( @4 r
SPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。" P$ z/ E+ x1 [

! ^# u+ W; @) I
5 q8 [6 n& p4 \/ S! V. K/ H5 O/ K( T0 |* I
如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。7 E$ l: O# J" j2 p+ q1 {& X8 S. m) W
4 b5 G5 d8 J3 ]. g  q
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:+ R( w( l/ u& C
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
9 k# F) Z/ v. S: dNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-7" y: r8 f, b, `' |. K4 M4 B$ y2 l
还需要指定他的阶层:
$ V' m* i2 _' z9 J4 N, U! @NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1
3 J9 C; }! q" x) ~3 [6 g+ r0 \! U7 i& z8 h8 }+ ?: J+ K8 e
另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下' n* R. T+ E- w9 c0 ~
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;( t2 g& @, L1 c
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-7
2 ^: z, ~$ s1 v/ ]3 `% K% {$ ANVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
9 d* e% l' v* _" c+ Z
0 O, S( K/ `, I+ p& }2 \那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)7 y7 V) ~. W; K! c& I0 L
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。
0 ^( S5 B; T4 C$ u4 ]
4 m7 w8 X# ^" T/ H$ A2 W0 D还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下
; x! D! d2 i0 X' v4 M% s' w7 H8 LNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
! _" G1 h. F! [6 t  rNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-7. ~5 H/ D. p9 q1 c+ Y- \9 v
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
) i/ f- y9 Z  b- t' U# l; a2 i! h2 _
+ x3 K3 K9 I: x4 H3 ^3 IUSART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。
0 c" X, h; [' t; o7 B: O" \& p# `8 Z$ O4 X4 Q. W( o
以下的类推。$ s5 ]6 U! q4 d# D- y  e
' ]2 A+ }6 [% H$ X$ Q& C

0 q& X- K( W7 k! }. ~1 u
+ ?* Z+ s4 t  Q: u  Z% b5 L& |/ p
收藏 评论0 发布时间:2022-1-13 20:42

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版