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

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

[复制链接]
STMCU小助手 发布时间:2022-1-13 20:42
例程:  /* Configure one bit for preemption priority */; E9 l0 G: @. |4 c1 V, V, K
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);; U3 I, V% P  I  z* }9 m# h
  
5 B8 r! f0 X# Y% n% |7 }2 I  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */
5 d* x- ]. y: j+ j  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;
% m) M& J' x% m. e& |, i; j2 b- R  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
0 e& i1 e. o7 }5 v7 W  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;, b. `5 r$ U% T8 v4 O2 j* D: }
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;9 \5 P. K5 `6 K& a( ?: ]
  NVIC_Init(&NVIC_InitStructure);
8 w: ^* q$ V. U# [; D, e- ?5 y0 @$ N  c$ [  8 t) v6 g9 X" |2 t. [
  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */
( \- K( F& j% \6 N& F  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;
4 a% b/ f7 o5 ~0 O$ D) j  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;. s3 V% w  h  Q6 e. k7 z
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;* ?4 r, Y9 d; H1 B4 g  n$ N- I
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
# @7 ]- c" j1 e, O- O  NVIC_Init(&NVIC_InitStructure);" h4 A5 i# [; Y% h
  ) d9 U0 A6 H' g: b2 B9 H
  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */: T3 Y6 u% E4 C! M. l5 J
  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));2 l0 d+ b+ n# }: Q& y
6 k( m2 R5 i3 [3 Y% v
这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。

. }8 I: s7 W. a- m8 G# W
        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。
       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。
STM32中指定优先级的寄存器为4位,其定义如下:
第0组:所有4位用于指定响应优先级
0 V! P9 s$ A$ @8 R- g$ {; K第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级' j1 R' `$ L1 _+ R/ X
第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级  h! i! p+ @8 g, \, g8 m
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级# J7 h5 F5 d$ R8 o% x0 b# E8 t6 D
第4组:所有4位用于指定抢占式优先级
以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。
基础了解了就可以对中断进行操作了。
第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为
NVIC_PriorityGroup_0 => 选择第0组
3 F/ l& `1 v9 |NVIC_PriorityGroup_1 => 选择第1组
& B2 v5 k% i% sNVIC_PriorityGroup_2 => 选择第2组
* Y0 z2 H- ]; \* mNVIC_PriorityGroup_3 => 选择第3组
8 r! ~; V; a( {* d$ A' ~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+ x1 E% c" ~/ n- i( ]$ @
例如: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;
8 v8 l2 I/ l6 l# W4 y# x
第三步:中断初始化结构体初始化操作如下
         NVIC_Init(&EXTI_NVIC_InitStructure);

$ X! c; \1 h. w9 x+ T0 j; w
第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。
(1)   下面两个函数等效关闭总中断
void NVIC_SETPRIMASK(void); & ?- O  ?6 n6 a
void NVIC_SETFAULTMASK(void);
(2)   下面两个函数等效开放总中断
void NVIC_RESETPRIMASK(void);
  K) s3 u! e# [% ?# k* _/ Qvoid NVIC_RESETFAULTMASK(void);
(3)   常用操作是先关后开中断
NVIC_SETPRIMASK();     // Disable Interrupts
. Z5 r5 G! W+ F( o3 TNVIC_RESETPRIMASK(); // Enable Interrupts
两种类型函数要成对使用。
& o8 m4 [) B  s. x( n1 N, r
STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下
: _, u: d, u3 L' p; T9 }
3 H( C' a( f6 x8 e#define NVIC_PriorityGroup_0 ((u32)0x700)
4 v; M0 F: f+ |: [, o#define NVIC_PriorityGroup_1 ((u32)0x600)
# P+ }6 q  y4 v1 i  e#define NVIC_PriorityGroup_2 ((u32)0x500)& ~) R0 V' B. ^8 n' ]
#define NVIC_PriorityGroup_3 ((u32)0x400)( [; w( I0 H# o6 ]3 N; Q9 h
#define NVIC_PriorityGroup_4 ((u32)0x300)
9 y6 y: T0 b9 Y" ?/ C3 u
. ~! K. G& c  t形象化的理解是:+ H( E8 N2 t) L1 ~, d6 l
9 P5 |  D% l7 u1 _: u9 j3 k3 y
你是上帝,
5 y' f& k3 u/ d( A; h0 t# E8 ~, M) a: F造了43个人,这么多人要分社会阶级和社会阶层了;
; |5 v: x, l5 p* r& [. U! E因为“阶级”的词性比较重;"阶层"比较中性,+ [+ U3 P8 S" f/ I& J! ^3 R
所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;7 `5 {4 ]9 c8 {& I

) |' I" `" V( g% m4 F: g. }" M' v9 d如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
" g9 g0 e* i' P# s1 x4 X每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则! N: G: ]( N) P& t/ e
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;8 @& u: j2 q. T! ~+ q
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-150 f, ]8 G4 o/ A9 E0 \  {8 m! Z* b
) T) K. b% _0 [5 ~. B
另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
, N5 _% C- o5 Q还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;
( I7 n9 x5 x% a# a3 L5 F- x2 \: a3 l0 K6 e, ~) y, s
又有1个人SPI1_IRQChannel,设定如下
; B$ V2 P4 a0 [  RNVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;; y0 z$ {3 J& }; y8 v
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15
) p# J- ?) D4 P$ t' h8 I4 h) }! }* d9 ^: Q  v4 j7 @
SPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。
) d- m) `, f3 c3 I0 ]1 U
' Z: x+ V- X- E: X1 _) |9 e+ a; }
; |1 P4 Y9 w% A0 I5 I( h1 |/ V
如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。
  i; `% o' t6 J( w) @6 X, y5 I8 m9 p2 S& ]( r
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:
1 {. ~* C  \; m1 w9 F3 t" o- z' y) {: pNVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
$ \8 b* u3 f2 e  F2 R. d2 ^# ANVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-7
( b/ \. s" T8 [4 q" H" D$ n还需要指定他的阶层:
8 [' T8 H4 p9 ^# ?. K, R2 SNVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1
$ }6 V7 p& f- h/ e/ i" d% B
1 C* ?! o& O& C2 S! A! ?另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下
6 m% J- c2 |) k) pNVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;* \' C- j" u; g' b+ u" E6 m
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-71 I! J( U5 d5 \% e# B5 @5 |
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别13 S6 p, r9 ?( ^' @
8 f3 a5 i. i9 K+ ]! i7 p
那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)  O0 A7 w- ?8 Y0 P9 u3 x
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。
& H6 c1 b4 H+ O! ~# s# c- N
2 g1 |0 M6 A+ P3 R& K' q1 ~: _还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下; N+ G1 c; Y0 D$ ^, q: g
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;: h+ U. r, n  D
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-7
# H. N# s. B7 Y' x- `3 i0 U: iNVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1& ]1 {) B( y" r6 J; I) w2 y( f

: q; o9 Z; w  p; |USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。
# }* R9 [7 u: N* F5 \" ?" Q9 P% r
" g& O) T1 Q3 ?以下的类推。
/ c* a" s9 l3 B7 S1 Z$ V& _
4 z1 N6 h/ c, F, p% i7 ^  l

! k; B5 p( L/ J) V" `+ V0 H3 i; w6 s% I/ Q( Z. T3 a; @8 Y. X4 W
收藏 评论0 发布时间:2022-1-13 20:42

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版