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

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

[复制链接]
STMCU小助手 发布时间:2022-1-13 20:42
例程:  /* Configure one bit for preemption priority */+ U9 _; f0 p5 U
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
! Z$ @" O. `" j/ T  
+ y' y1 x7 H" m( ]  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */
, ]2 [+ k) D3 U  |; t2 j0 w. E- s% A  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;
' f5 U1 @0 h+ q) B  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
# P4 Y, U: V* Z) d9 m% g$ w. j4 T  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;$ V1 C1 r7 j( E4 X" j5 F+ J
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  I2 a2 G$ H4 A. M: r3 y  NVIC_Init(&NVIC_InitStructure);
0 o& @3 ]% `4 y: y, K8 H: E$ c  
& q- A5 C8 T! P5 I2 d  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */" P) g* n* V, F! Q/ W) W" g7 b  s- c; G
  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;% {" C- B7 v# [" E! G8 k0 `7 F! N- W
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
$ v3 y- x3 `& O2 w4 ~* R; N# P0 A  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;& s- F* {; G7 t
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;) Z- c( b8 D5 d' ^& `& K; Z
  NVIC_Init(&NVIC_InitStructure);4 Q. U& `: l' \, H) S  \' F
  ' ]+ A& M2 ~5 U. I
  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */
$ i: k, R7 U1 N$ ~  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));5 x, S0 M/ ~) ^5 ?4 w3 h$ [
# B) |! e  x/ L- i3 Z) Y# T, h
这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。

" o. N4 {9 d$ v( ]3 k! ]
        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。
       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。
STM32中指定优先级的寄存器为4位,其定义如下:
第0组:所有4位用于指定响应优先级8 g+ r0 k7 i8 w1 I- O8 a
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
9 H1 T) S4 K0 [; n# a; \第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级' d3 i4 `' u6 O7 r- Y1 \
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
& D$ B4 c1 c0 c- ^第4组:所有4位用于指定抢占式优先级
以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。
基础了解了就可以对中断进行操作了。
第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为
NVIC_PriorityGroup_0 => 选择第0组
2 e- C# _3 e6 _! \NVIC_PriorityGroup_1 => 选择第1组. H( }( k  r7 Y9 q3 ?
NVIC_PriorityGroup_2 => 选择第2组' i$ }9 F3 e" K; s0 e+ o( |* n
NVIC_PriorityGroup_3 => 选择第3组7 I( |: Y0 ^/ F+ o
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;

& D, X5 A' Q+ \/ b
例如: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;

" L2 u2 G8 i) ]1 ]. u  Q. p
第三步:中断初始化结构体初始化操作如下
         NVIC_Init(&EXTI_NVIC_InitStructure);

: j) d% x& q9 b
第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。
(1)   下面两个函数等效关闭总中断
void NVIC_SETPRIMASK(void);
9 r1 }/ r( C+ X% s* Y7 Xvoid NVIC_SETFAULTMASK(void);
(2)   下面两个函数等效开放总中断
void NVIC_RESETPRIMASK(void); / _, r  K% T0 [6 C* x0 U+ l9 U' q% x
void NVIC_RESETFAULTMASK(void);
(3)   常用操作是先关后开中断
NVIC_SETPRIMASK();     // Disable Interrupts
9 |- k6 U2 r8 @. m# wNVIC_RESETPRIMASK(); // Enable Interrupts
两种类型函数要成对使用。

# a- e, u$ \8 a% W; j" Q. e+ U: ]STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下
6 K1 {: }4 c, {5 I1 i" S
  }: ^  a  a8 M$ e% S$ S4 `#define NVIC_PriorityGroup_0 ((u32)0x700)5 Y4 W5 k- f8 N! A
#define NVIC_PriorityGroup_1 ((u32)0x600)% _0 u- z' i& e1 f2 C  k
#define NVIC_PriorityGroup_2 ((u32)0x500)
5 W+ {, J9 N- g( }#define NVIC_PriorityGroup_3 ((u32)0x400)3 r0 S3 F2 z" w2 q
#define NVIC_PriorityGroup_4 ((u32)0x300)
- ]- [+ v+ @$ r% n0 ?
5 H. {+ D2 G6 D! {( |3 V8 S; t形象化的理解是:
) G# D& s: o* X# j& O
! K% V# s- B3 p- W( n7 k) J' }你是上帝,
3 r* Q% p  H8 e% r& n造了43个人,这么多人要分社会阶级和社会阶层了;
% R' T/ [* h- o6 q+ W  G因为“阶级”的词性比较重;"阶层"比较中性,9 p$ v4 g2 p. R: v9 r( @% \' O
所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;
# O% b8 [8 A( D: q: s# r# I1 R, W& \: h8 H
如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
' W8 Y- Z/ ?% l1 {每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则
, Q# Z- }( H  D( o/ k5 V8 G& vNVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;. Q# T# ]% K5 K
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15
1 U/ [2 O4 f! b. x3 `  Z) s: ^
# |: Y7 H5 P; l; m另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)6 F4 i5 V. r2 r! S9 s4 W
还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;
4 K/ U. L& w5 j9 |" U* U1 V: [! e( m5 p  E8 O6 R! Y/ P
又有1个人SPI1_IRQChannel,设定如下
( i- f( i# S' g! N' JNVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;  b* S0 o4 ?4 W) @& ]! g5 v+ W. m4 m
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15
  J2 K* [. t0 F& {0 t  e
" K. j9 p" r, |" Q5 u; l( [" OSPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。- |0 z5 h' }: j( I9 W! G& y
+ i$ D2 G, N  ^7 K
! e; d+ \  c. ?/ ?5 X, ^
3 \$ W" f/ o0 }" w
如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。
4 T$ z: T* j/ P+ w' H  C) M, s
3 \) c. w( t, I2 ^每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:% r- y2 ]) X6 y3 |
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;: x1 a& R2 U; i' P/ M& B( N
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-7
$ ^& m- w" P2 U8 x( V9 r; w  w, d2 V6 d还需要指定他的阶层:: P( j4 U" {# [! i5 L
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1
! o8 |! A  ?" I' E/ R0 j( w. v
另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下
! g3 }0 d; s) r: C" g2 P+ H0 XNVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;  |, ]9 d- Q8 T5 ^, O2 A( I& F
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-76 {; n9 Y# |( F  j7 W2 M# Q
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
/ h0 y& e5 N6 m4 g7 p% l) \0 I$ d+ T% o* F7 ~9 ~! D
那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)3 ^0 \$ t" L: x. l- V! ~' y+ ~. p
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。4 I+ C  k/ K/ q* {3 |. T& P0 |- d+ [$ j

6 ~4 F1 n$ y) B" P5 a: t! [3 B还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下( c7 [' U$ G7 T
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;2 b2 o- w; ?& L- j! }  H+ _
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-7
! k& X: q& ?! t: a& ENVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
& m% O7 D% ^' R! S) M
! U0 b/ ?& D/ l- B" Q, [. BUSART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。
! T7 d3 ~# }, n* |& R7 c# t3 u8 W1 {: T7 N  N
以下的类推。( R1 ?0 K2 B! G/ r! v) n

, g+ h$ Q7 U6 v  ?, R8 f. ?
% A% g" o3 i( O! |3 y1 a& x# A1 I3 l& e' S
赞 收藏 评论0 发布时间:2022-1-13 20:42

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版