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

【经验分享】stm32之NVIC

[复制链接]
STMCU小助手 发布时间:2022-1-18 22:35
STM32的NVIC理解 例程:  /* Configure one bit for preemption priority */% ~3 ~+ A; V: C6 G

  x1 z, A; x' q1 u; o8 z  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);0 ?) [. k# e) a7 |
  
. Q4 ]9 c/ _7 Z  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */  G& R7 X' `0 e2 Z1 E# g; l" d9 ?5 D
  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;
  P! I% c' C5 v  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;* Q8 J8 P9 e1 m" G8 v3 F
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;9 q8 g! }0 a  ^
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;% t) ~3 w! t7 C4 c# `
  NVIC_Init(&NVIC_InitStructure);
% d$ I" K2 P3 C6 q# s  6 Y. M4 Y- r: l; Y& |
  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */  z3 R* T9 t5 G* j) m3 ~1 l# d* ~
  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;3 B( o; l9 X" ^
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;+ m) k7 v& j+ |: n
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
: F& d( W" `4 o. z! f+ o  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
1 `  d5 z/ \) }+ U, B0 i( @  NVIC_Init(&NVIC_InitStructure);  Z' R0 t+ P  A8 U/ y
  
" j. K) ?) w1 }  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */
# A) g3 ~, ^' _" h1 n# ~- c- [  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));

, [$ }, T  P: @: n( S
' w, D: B# e: i$ K
这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。

9 v3 Z/ o- ?: S
        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。
       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。
STM32中指定优先级的寄存器为4位,其定义如下:
第0组:所有4位用于指定响应优先级6 i# `3 H+ {. d  j. u
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级8 J9 H+ y; o; r; I" U5 A
第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级
! R$ _8 I4 Y( C  h, d- @第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
9 ?) B, _* d$ w第4组:所有4位用于指定抢占式优先级
以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。
基础了解了就可以对中断进行操作了。
第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为
NVIC_PriorityGroup_0 => 选择第0组
% P- Q8 j$ p4 {* N! fNVIC_PriorityGroup_1 => 选择第1组3 I" ~& R  j2 A) {! F8 @
NVIC_PriorityGroup_2 => 选择第2组
3 R/ k3 _2 \+ v* @% m% ^NVIC_PriorityGroup_3 => 选择第3组( Q2 M0 S* ]7 H8 H3 l2 g0 P
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;
& ~: O/ v7 L6 Y* L7 G( J
例如: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;

7 R  a: \( Z  n6 w% O
第三步:中断初始化结构体初始化操作如下
         NVIC_Init(&EXTI_NVIC_InitStructure);
0 W8 i. H7 u9 y# x* }
第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。
(1)   下面两个函数等效关闭总中断
void NVIC_SETPRIMASK(void);
1 Q+ O, W! ^8 `1 ovoid NVIC_SETFAULTMASK(void);
(2)   下面两个函数等效开放总中断
void NVIC_RESETPRIMASK(void);
2 C1 d. d# w" Fvoid NVIC_RESETFAULTMASK(void);
(3)   常用操作是先关后开中断
NVIC_SETPRIMASK();     // Disable Interrupts # u$ o/ n% G! f6 K6 I' \4 j
NVIC_RESETPRIMASK(); // Enable Interrupts
两种类型函数要成对使用。

4 a- `9 G7 J, P1 U/ aSTM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下0 I1 I) w/ V7 H, I

# Q, j8 U1 u3 R( @6 W% k#define NVIC_PriorityGroup_0 ((u32)0x700)# `: r: K& a& R6 f5 @- R
#define NVIC_PriorityGroup_1 ((u32)0x600)
1 X( ~  k5 a7 k#define NVIC_PriorityGroup_2 ((u32)0x500)
0 _/ a0 F5 y/ |- ]& x#define NVIC_PriorityGroup_3 ((u32)0x400)
# a3 s  Z, t. x- D4 G" Y2 f#define NVIC_PriorityGroup_4 ((u32)0x300); C/ C/ x; A7 T8 M+ n- J. |
3 F( L  i0 a, m1 g1 p- D+ W+ _
形象化的理解是:
: S( t3 e9 Q$ D9 q3 b) s+ G6 V* _) R( ~; r" z6 J
你是上帝," e8 ~% A# B( x) U" L
造了43个人,这么多人要分社会阶级和社会阶层了;# Q2 _& n! k( T; \+ q$ s2 K2 [
因为“阶级”的词性比较重;"阶层"比较中性,
( `  [& k5 A  M2 Q4 a! m所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;' P  [* [0 i  V

: W3 n, ]3 ?. T0 ~如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。3 d5 Q9 ]0 A5 p5 [2 d1 z
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则
( j2 `; |' ?" @6 M. y' E! yNVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
% F; @7 u4 m: U- RNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15  d7 ^( H2 a: B; h5 N/ g/ o
; ?  h; ~5 a3 I. f! V, d% a" g
另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
. t# g" q7 ^4 R5 j% I还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;
9 x+ h2 V$ t; a( _
. e- v, G! }5 U" I% S  p, b又有1个人SPI1_IRQChannel,设定如下
5 ^& r2 R# N: r+ B# m  WNVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
1 |0 Q- r5 u, b2 a/ \NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15
6 m* o! v: {( \( n3 z
! t9 m- ]! t# l7 uSPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。/ F1 g: \6 A$ c; p( u) a' l0 P

; _, h1 q8 d6 L9 x$ E) s. T) `' ^6 F9 {0 Y8 b
1 }1 t" c2 y$ e% g$ c5 z
如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。. n6 C: A% i9 y: t9 R' t! ?  A- w

3 Q1 F* K4 a4 `每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:
3 d# ?5 N* I* t2 QNVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;. q/ ]" V* g  P' B* j; l
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-79 F7 D0 A  ?) f% `( ^+ Z' Y. C; p) A
还需要指定他的阶层:
. H, t5 x0 w: e8 F0 F& |1 INVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1
% q) k2 p. A4 F4 \5 D% s8 m7 E4 ~8 d4 Q' m1 q; [
另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下3 _8 \! N9 T& W" A( U; u
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
0 ~' \+ l/ V9 a# ]5 B9 t+ o+ INVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-7( t+ @! E3 }% z- J& H6 t% k; i
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
- E" O: P% \% m
9 m; ^. {) p/ H/ W! L- s那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
3 A: {' B- x( P" B- W4 O( Z/ f* W如果他们两个同时想做事,因为前者的阶层高,所以前者优先。
3 V8 ?' G5 d; S# A% _0 z( C& F: j( }' C, t! g5 I' d
还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下( U+ [6 K3 l0 [& s
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
, [' O* j! o; \: H: X! LNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-7
; U# X' x8 t" U; `) lNVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1; n# C5 B4 V1 K; W4 U
0 _9 v. U3 M% i
USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。
; y9 O" o# ]6 a8 m

, M7 ~* d% \2 Q
4 [# L6 d$ n2 d+ J# \3 A" G
收藏 评论0 发布时间:2022-1-18 22:35

举报

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