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

【经验分享】stm32之NVIC

[复制链接]
STMCU小助手 发布时间:2022-1-18 22:35
STM32的NVIC理解 例程:  /* Configure one bit for preemption priority */$ i2 m( q9 G2 {7 K7 E$ y

/ H- b$ B2 {1 L2 u  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);5 b. p2 p# |8 t% \
  / O( R, m$ P4 V* H6 g, ?! a
  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */
' X* V) f8 _3 D7 y$ P( ]# C  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;( N# j2 t& _9 Z& Q
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;) y* B8 c- k1 m+ k# c
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;+ i; J; \7 Q/ f% x$ k: k' F3 ]' I
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
! C8 v8 t: f9 U: d* [' d- X' U  NVIC_Init(&NVIC_InitStructure);  Y# y* Q# B) X# ^0 O; Y
  1 e( @6 a4 t( v+ i8 |3 O" F
  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */, e8 l/ {. [7 ]% c
  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;0 R4 P; _" d! g7 u! I
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
0 a- V# K7 D6 F4 X$ `  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;3 D$ U9 ^8 @- |0 |
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ R- j, Q2 F* e; }) a# }, l  NVIC_Init(&NVIC_InitStructure);0 T7 J6 w0 [. h3 [9 W* K
  
3 p1 X; i) Y7 O- y" ^6 d; {, f  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */1 C5 s, y, \) ~' G- Z# m2 }
  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));

2 H" E& y0 Q0 c4 l; e/ H! n- j( C4 q- r7 M: F2 U) \3 `
这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。
. \1 B  f7 U3 g8 p, M: a  G- O/ f! K
        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。
       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。
STM32中指定优先级的寄存器为4位,其定义如下:
第0组:所有4位用于指定响应优先级
5 c. a4 Y: {; ]5 |% K4 D第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
9 |, y5 [5 J8 ]' e' {* x6 E  T第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级
) N3 {$ z4 t0 ?- Y1 G第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
- u% Y" ]$ Q5 `! ?第4组:所有4位用于指定抢占式优先级
以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。
基础了解了就可以对中断进行操作了。
第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为
NVIC_PriorityGroup_0 => 选择第0组- `8 s2 C& L0 S: w" ~' q
NVIC_PriorityGroup_1 => 选择第1组
! h) F- Q) C* ^; R* M# jNVIC_PriorityGroup_2 => 选择第2组
7 c9 [5 u/ r1 A6 INVIC_PriorityGroup_3 => 选择第3组6 q1 n4 u* @) V9 R" 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;

3 s' d8 x* ?$ \7 a7 O' P- d
例如: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;

# o1 i: ~/ E8 O3 R# Z; @4 H- l# h  i
第三步:中断初始化结构体初始化操作如下
         NVIC_Init(&EXTI_NVIC_InitStructure);
/ R% J# x% f, D5 _' V7 R8 E7 }
第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。
(1)   下面两个函数等效关闭总中断
void NVIC_SETPRIMASK(void); 7 ?3 a( k4 j$ q( o5 D: v
void NVIC_SETFAULTMASK(void);
(2)   下面两个函数等效开放总中断
void NVIC_RESETPRIMASK(void); - O- [- U) v/ O8 a
void NVIC_RESETFAULTMASK(void);
(3)   常用操作是先关后开中断
NVIC_SETPRIMASK();     // Disable Interrupts
' C, {, w0 q( V# m' Z. L) Y+ cNVIC_RESETPRIMASK(); // Enable Interrupts
两种类型函数要成对使用。
  @2 Q9 v* m  w/ D$ I' Y
STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下
  T+ b5 q. h; Y, h! S( _; i+ f  I" Z
$ _- d4 ^' A  T8 c! @+ M  n#define NVIC_PriorityGroup_0 ((u32)0x700)
$ `8 T( W; p9 x6 @#define NVIC_PriorityGroup_1 ((u32)0x600)# L1 j6 j% o( U8 b  B
#define NVIC_PriorityGroup_2 ((u32)0x500)
, i5 ]6 ?, L2 f1 M! {/ U9 I0 A#define NVIC_PriorityGroup_3 ((u32)0x400), L" ^" S9 P0 ]4 ?! c8 \5 W
#define NVIC_PriorityGroup_4 ((u32)0x300)
6 C. \- B4 @. q7 U/ h( a+ E8 o) H: H: F2 R, F& a: i' J
形象化的理解是:
" n9 A4 h8 r# E0 H/ w4 u. D, T* ^" v( [* @2 j4 a
你是上帝,
& P5 a+ d0 D, Q# y造了43个人,这么多人要分社会阶级和社会阶层了;& C7 F! Z: j2 P: C
因为“阶级”的词性比较重;"阶层"比较中性,4 T' G0 R% ^2 y5 C4 U4 _0 c
所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;
& K2 m" \- ]3 `; J
5 ], @) K" C, r+ u如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。( d; O. p! S, z; D6 L, A3 B
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则
6 X' R( ~( b% S6 u2 x, ~NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
* K  p" V! D8 v8 [NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15
" |, c/ t1 h5 \; G1 o
+ ~2 W3 C  R4 R  G& Z+ n( N% |- U另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系). j  p* s% N4 S5 D# B
还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;- X# K' i$ A, C# A8 F

; ]& L5 _5 `0 n又有1个人SPI1_IRQChannel,设定如下1 P" A7 b; }. w4 R+ O
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
8 _: i, @2 p8 [( e% A1 C0 Q8 BNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15
( H, |: v8 ?5 l" n# s
, U5 D7 A% @9 @, T8 w" ?) L/ [SPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。
* g7 V/ z$ L- `  J$ t6 @& V
* X- K% f- r/ ^
* V/ c# f+ A1 Y) o1 ~9 E1 H' J0 y- N3 c% Z% B# X) W( S
如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。% F8 M$ B% K' T/ v

- G5 u/ O2 U/ b) z6 Q每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:' {) S: u. u2 [9 |1 v
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;( B1 |0 e4 O% V; ]6 U+ b( @
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-76 g! z/ ~7 D- q: V. q
还需要指定他的阶层:  \9 \  x' ~, G& f
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1. Y- w9 S3 Y8 F( I; Z
- Q5 z' M8 G. e( s
另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下' @2 L4 l1 ^( \
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
0 j  F) r* u6 n4 w! \6 dNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-7
5 e6 }; B# F# b% i  G0 y" DNVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别10 I% s& v. X( n) L
+ y3 s/ z4 P# b* K% @
那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
. ~% y) I9 e4 v) ]+ ~; D如果他们两个同时想做事,因为前者的阶层高,所以前者优先。5 }: l/ l8 m+ Q3 t
+ S! g$ Z# l* S. V( W* r
还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下+ D3 d( ?% f/ I8 [' k# h
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;- T' X( I: L4 U
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-7
  S8 O- W( v6 F+ U* dNVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
- K: {- ?) X5 ]; H2 ^9 z
8 y& Q% ^( M7 \0 G& mUSART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。! v2 _* S0 i+ j  M

; H5 l3 N! F' G6 R! t' |5 M) V0 g; I6 C8 ]$ `
赞 收藏 评论0 发布时间:2022-1-18 22:35

举报

0个回答

所属标签

相似技术帖

官网相关资源

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