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

【经验分享】stm32之NVIC

[复制链接]
STMCU小助手 发布时间:2022-1-18 22:35
STM32的NVIC理解 例程:  /* Configure one bit for preemption priority */3 Y8 Q! Q6 i8 H+ ~3 Y
2 Z, H7 m* E$ x+ n# R" ?. r
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);5 e- V7 `9 D1 I) G
  
! \% o+ p; i1 Y, i4 U5 D6 |  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */4 T1 d3 ~, f6 D- C
  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;2 t0 z7 L1 {0 H, [  q
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
) L. M- o( C0 \- A2 i" f; K  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;$ W; n' A$ N( c. c* P$ f7 [
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
0 p# c7 @$ Q, Z/ @& B  NVIC_Init(&NVIC_InitStructure);
9 z& S8 a) d% M- c" R8 z  U) h* F4 v  & \$ K7 H: \. Y' E0 u" p( t
  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */6 n0 V% y8 t; T7 L8 z
  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;
& ]8 X6 O$ T* X+ e  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;. i. r, g5 j* Q, c+ s
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
, c6 S& K# Z8 w& w" R5 E  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;& M+ \9 F9 ?/ [" J/ |
  NVIC_Init(&NVIC_InitStructure);
" L, o) j7 v$ O  ( ^& G- v3 `" k6 S  q+ Q# V
  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */3 D* r& ~) o* _- a6 J* b% u
  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));

3 v1 E0 e/ H7 w8 Z9 D' e- R7 @& I8 \4 n
这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。
% e" S7 O" s. \. \4 N+ }
        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。
       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。
STM32中指定优先级的寄存器为4位,其定义如下:
第0组:所有4位用于指定响应优先级' K2 \- d5 r4 ]8 A/ q9 \
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
8 }* q2 x% |6 h) `第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级2 \! l& T8 H/ N  f8 a4 B# f
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级  j4 |2 o/ q' W4 v7 ]$ c) N
第4组:所有4位用于指定抢占式优先级
以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。
基础了解了就可以对中断进行操作了。
第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为
NVIC_PriorityGroup_0 => 选择第0组) n4 d( l6 m0 L( T1 n; b: P, f) j5 `
NVIC_PriorityGroup_1 => 选择第1组0 B! r5 D2 h4 ?$ S8 t+ ]; Y; v
NVIC_PriorityGroup_2 => 选择第2组' f2 f' {& @( O; P1 `! j0 ^
NVIC_PriorityGroup_3 => 选择第3组
9 D5 m& m; |; A7 g' l4 r: GNVIC_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;
( x6 v  |$ |1 P5 A& f- Y. N
例如: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;
/ R  W5 w" }1 `! M# b- }
第三步:中断初始化结构体初始化操作如下
         NVIC_Init(&EXTI_NVIC_InitStructure);
2 `5 y! H- c& R5 V" Y7 ~
第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。
(1)   下面两个函数等效关闭总中断
void NVIC_SETPRIMASK(void);
% f& P# j  l7 ]void NVIC_SETFAULTMASK(void);
(2)   下面两个函数等效开放总中断
void NVIC_RESETPRIMASK(void);
: G; K+ V, {6 _3 v% Kvoid NVIC_RESETFAULTMASK(void);
(3)   常用操作是先关后开中断
NVIC_SETPRIMASK();     // Disable Interrupts
; Q  g: d2 i" ^8 i( Q% cNVIC_RESETPRIMASK(); // Enable Interrupts
两种类型函数要成对使用。
) m" W5 g, O) E; ^; G; l7 M
STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下
- ]& V' v) z7 M9 n: ~
+ {, ^9 m& r  G" h# j#define NVIC_PriorityGroup_0 ((u32)0x700)
1 o1 j- O1 @0 f8 M7 z% p#define NVIC_PriorityGroup_1 ((u32)0x600)
  D4 v) J; s3 q#define NVIC_PriorityGroup_2 ((u32)0x500); _: {1 ?9 w# V' R  x
#define NVIC_PriorityGroup_3 ((u32)0x400)
  W) {* |7 M+ o9 E#define NVIC_PriorityGroup_4 ((u32)0x300): A$ Y0 ]- D- A& |, O) r
& X% P" P9 j: e2 \
形象化的理解是:1 M9 R' L) t: y

! Q: Z/ M  T/ ?0 C' `* O你是上帝,
3 p* Q3 `6 ?% E% ?- f' r- y, \造了43个人,这么多人要分社会阶级和社会阶层了;
9 e7 |6 B1 R0 d6 B$ E' l因为“阶级”的词性比较重;"阶层"比较中性,  ]+ M5 G  b+ m; U: B) b6 V+ ?8 A; l
所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;
  g4 }; h1 I, U& t$ U$ U- c7 y; B2 I4 R- Z
如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
$ R: k9 f: ]$ p) R7 ^每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则8 X4 N" n+ M1 X' W& j
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
2 o% H: {4 K% R$ m+ |2 XNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15& \  {9 R; T( y2 e

! m$ M5 d/ q* Q$ Y- c另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
3 X0 O( h7 y0 l% s. z( X还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;
. d0 j1 S9 p- S! t( D& `
1 p, a, G! E' q. v: {+ X  n又有1个人SPI1_IRQChannel,设定如下
; y8 E6 ?6 y: o. u: e: d% fNVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;  W2 q7 Y5 |! e2 B
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15
0 p" W, F+ M" w. X3 ?
7 H- b5 r/ V, \! D  ?, A7 TSPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。
$ }. ~. j" h0 T" F4 k2 E* _" \6 C$ {5 l# D. S3 \- H% i' O
! U& f: ~* d1 Q4 U) s

/ g# X0 F1 b$ ?+ B7 M4 v' k( P2 r7 U如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。* M+ u/ U8 r! u6 F2 Y7 j
! i: S; @, _: _& R* A
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:6 @+ r6 e* [6 d: n0 ^0 C/ `- A
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;0 _9 w9 u# m" I) F$ a* r" K2 E$ c
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-7
8 P2 q, B& c0 |- \, a还需要指定他的阶层:; X$ K4 {  D1 H6 A; m, Z3 }
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1$ Y' s. I/ V* U) U1 ^

3 z" c, L9 K& ^+ B0 p/ f4 P0 t: V; V另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下! b, D! p# W% \5 t" @: S
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
# u* d) D9 y& N6 }' b6 f3 Z7 pNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-78 H0 `* R: j! ]' H& L* ^
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
: r7 j7 M& t  a* P, T0 Y
; x6 }* \8 e; F2 F3 k/ n9 j* P7 G那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)% M8 m+ ^" e( e
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。3 c( U1 d: e1 y, S, Z
, p* k6 O3 Z4 T/ G
还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下
. `% m, [6 O% r, C7 G# y6 XNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;+ _1 |" O& b. @* \! |
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-72 h8 c# T+ q( m( G1 n* x" x
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1- X; c$ V6 z7 f* r$ [& b; w8 s; {
) A4 t  o  k" Z
USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。
0 @; X  }% s: t8 d
+ p" \9 i0 l( [9 F( S
0 _2 C( I1 e4 r1 k( Q' g
收藏 评论0 发布时间:2022-1-18 22:35

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版