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

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

[复制链接]
STMCU小助手 发布时间:2022-1-13 20:42
例程:  /* Configure one bit for preemption priority */, J! \0 h9 X' {, B3 R: O3 Q5 s
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);7 G* w7 n8 t  N' M* K% F
  $ _* r$ y/ G- u4 J
  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */
% ^5 M, @2 ~$ T/ U  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;
: d" I& G8 r3 Y, X  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
; Y' M2 b  V' ?+ M2 v. k& ?  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
& F$ r2 ?; F; C) r! g' \2 A) x  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- ?4 ]3 j& ?( I5 y  NVIC_Init(&NVIC_InitStructure);1 ^* X3 ?5 I! l$ R
  * s* X( s# w; G
  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */# q% w/ z% `$ D1 B7 {" @: m$ k
  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;8 R$ i9 H0 a- f8 ?, V
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
" r6 S  t! P6 I9 S* {0 b  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;. R. ?4 U1 R% G4 g3 U! t
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
4 V/ b) A5 h: V  T" F  NVIC_Init(&NVIC_InitStructure);
; u2 x/ _- ?! I8 W5 s  
, ?( G3 m' O' b3 K  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */
$ y6 {5 H* n: Z, ^  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));0 _: [9 e9 f# ^

! ~7 \& C) h: k* E  K
这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。

. b0 K, O2 K9 e: P4 S4 {9 U
        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。
       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。
STM32中指定优先级的寄存器为4位,其定义如下:
第0组:所有4位用于指定响应优先级! p1 W( a0 B! W  u3 C  \1 T9 T, `: `- q
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
/ R, ~4 M1 E. i$ N2 a第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级7 V0 R  v* k. x
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级' |% X0 z7 w2 L) M( B* f
第4组:所有4位用于指定抢占式优先级
以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。
基础了解了就可以对中断进行操作了。
第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为
NVIC_PriorityGroup_0 => 选择第0组- e2 w) X! q: |% y
NVIC_PriorityGroup_1 => 选择第1组2 V+ H. ~: b/ K0 |5 U# e
NVIC_PriorityGroup_2 => 选择第2组
0 x3 {0 W, `$ K1 H$ p1 P8 Z8 CNVIC_PriorityGroup_3 => 选择第3组/ U9 {1 i& R5 v2 ^
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;

' X- h, {/ i; X9 j9 r7 ^2 k5 P+ E& O
例如: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;
/ B- s1 U6 H0 k* [: l
第三步:中断初始化结构体初始化操作如下
         NVIC_Init(&EXTI_NVIC_InitStructure);
' [, K! Z8 e* z! }6 m5 g
第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。
(1)   下面两个函数等效关闭总中断
void NVIC_SETPRIMASK(void); 2 f, u: s# F1 l
void NVIC_SETFAULTMASK(void);
(2)   下面两个函数等效开放总中断
void NVIC_RESETPRIMASK(void);
9 m* u! L, u; e# z4 i; ~1 @void NVIC_RESETFAULTMASK(void);
(3)   常用操作是先关后开中断
NVIC_SETPRIMASK();     // Disable Interrupts
/ i0 U7 a3 r9 t" A) h( q+ T! E8 kNVIC_RESETPRIMASK(); // Enable Interrupts
两种类型函数要成对使用。
, u+ t. S/ d5 M
STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下9 A2 w; s. D$ r+ _, P
: R; m  b2 Z% J; b  m
#define NVIC_PriorityGroup_0 ((u32)0x700)
, m, `4 h6 w" Q# X  p9 V4 `#define NVIC_PriorityGroup_1 ((u32)0x600)
% c' Y# a9 u: u2 f#define NVIC_PriorityGroup_2 ((u32)0x500)& E$ t# \7 A/ s1 `2 \9 y) @1 H
#define NVIC_PriorityGroup_3 ((u32)0x400)5 W4 p" A( a8 @. Z
#define NVIC_PriorityGroup_4 ((u32)0x300)
7 x) ]. U- {) ]
# @6 j& ~8 T. s2 K形象化的理解是:7 j# u+ {  f: e& G# |

' t7 b; V: A5 z( B1 H4 g. t4 i. h% t你是上帝,
1 Z3 S6 L  [, v# U  m造了43个人,这么多人要分社会阶级和社会阶层了;
5 P0 D8 C, b( M6 k* q( ^. l因为“阶级”的词性比较重;"阶层"比较中性,
2 @3 p/ L+ ]% J) D所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;' N* }4 s' q* i! v8 c9 R7 T

5 c3 ?8 k) {6 o! x" p# _+ Z4 _如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
+ u" @/ F- k- [: n每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则+ G. |- Y9 d) `3 R
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;7 `7 Y. U7 P8 S8 a) s
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15- q$ t+ V. v: T! u) c3 N' v' c
- V4 \( n& t8 B4 M
另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
% O; c: f/ ?0 ?* h7 g$ n+ }还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;- f3 B+ U. r* B" @

4 ]; D8 f% B/ j5 u! _又有1个人SPI1_IRQChannel,设定如下/ T0 [# ]8 H" T
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;6 ?- Z: V; O2 s* V' F
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15
& y# ^0 n7 Y( B! _& d1 W' n) U
3 ?. m- F: _' w" Q& gSPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。. Y, p# a" F7 R) u
4 ^. [, b( {& L) d) G2 \
& e- P$ z: }& z$ F  B4 k
. Z& f! {( {2 D0 ?! Z/ ?, o: L  i
如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。6 z- K' J1 ^* P2 v
. e5 C( r! e' E9 z. t
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:* V5 M$ d$ d2 h
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
* F2 Y6 K/ J$ v6 Q% R5 N, ENVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-7
' y# Q6 m2 I* h, B. F. A还需要指定他的阶层:8 a# ]- m1 Q9 e( C# D5 X! B3 d
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1
7 E* I: f& y0 \8 Q, \* M$ R: M) j% Q* f: ?9 D0 x
另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下
/ n5 G8 ?! c9 x# GNVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
/ T9 _' M/ c+ S, J- |* |NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-7
- o* l9 G, h% P! F  u- y  jNVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
/ v( V" t7 J1 d% A$ R
; L, _9 \- H: K那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系): c4 d* S9 z& y5 y/ @
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。
" M3 b* Y* \" M2 m4 R7 l( _% X; @* v1 i- I$ C6 x
还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下; |' _6 j* H8 }& u  g
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;/ R' h' i4 m: K) J
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-76 n' ^2 Y: H$ B9 a2 }
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
' c& s( j' j! Z  F( h2 E3 P9 l2 {2 e+ y
USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。: `& B2 n/ [' T3 f5 g
& _3 `: ~  r9 A8 o& {( m9 q
以下的类推。' ]1 W% Q4 S0 g7 ?- E! G
2 E/ i3 a) y# i8 Y" b  @; X
- a3 l$ a8 x: U1 i/ Z
. k3 C- W4 v% o6 f; G4 o1 V
收藏 评论0 发布时间:2022-1-13 20:42

举报

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