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

STM32心得:NVIC中断优先级管理

[复制链接]
STMCU小助手 发布时间:2022-11-21 17:00
主要内容:9 f  i3 [  i. w& F" H: z7 ~
1) NVIC中断优先级分组;
8 D" ~- L. W+ ~' c8 W3 j2 c+ K3 K$ @2) NVIC中断优先级设置。# h1 F+ X9 ?7 f5 r8 {; G9 m
( s1 O9 H5 X4 Z, O8 J9 r, b
1. NVIC中断优先级分组) K6 F  R7 Y' N4 I0 Q/ S' S
1.1 CM3内核支持256个中断,其中包含16个内核中断和240个外部中断,并且具有256级的可编程中断设置;
6 @' a( l2 n% a+ v6 {1.2 STM32并没有使用CM3内核的全部东西,只用了它的一部分;
1 [: o$ _6 \9 J1.3 STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级;; K+ o; `3 E/ ]9 x- V4 H4 c( F
1.4 STM32F103系列上面,又只有60个可屏蔽中断(在107系列才有68个)。1 G2 L3 J; C$ U) g3 j
2. NVIC中断优先级向量表(STM32F10xx产品(非互联型))
9 E- X; G2 v1 a) @. I5 ?* m$ X2 D7 s6 T1 |4 g, m( E+ N! b
20200405154345707.png
9 H; Q2 E7 l  T0 E0 c3 C1 Q
1 n$ s( e# q: s2 u+ T 20200405154433917.png - V0 s8 J& `6 d$ ]7 G, X7 P

) i3 [/ q* V1 @3. NVIC中断优先级管理方法
/ D2 Z2 c! y* w3.1 对STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值;1 t" K% U5 E# I) j7 s0 G! B' n$ p. i
3.2 分组配置是在寄存器SCB->AIRCR中配置:
+ p( s- d4 ~$ O2 Q- s/ a# U0 X8 G' ]1 N3 p& Z- u/ Q+ {
20200405154534612.png $ v5 w9 n1 Z0 B; f

# K+ t! A7 O, M9 D+ z3.3 分组配置是在寄存器SCB->AIRCR中配置。' d3 y# p9 H, `  `; ]$ X9 R
# R. y6 o) T" k5 l
4. 抢占优先级和响应优先级区别6 |! @2 |' V4 R
4.1 高优先级(值越小越高)的抢占优先级是可以打断正在进行的低抢占优先级中断的;' W6 b0 x; N/ V* s9 K
4.2 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断;
+ q6 k+ M3 ~1 G" G/ o7 K8 v4.3 抢占优先级相同的中断,当两个中断同时发生的情况下,高响应优先级先执行;
! F' K" P9 e# l3 y: W- @- m4 s; `4.4 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。/ e6 D& [; k- F
举例:( u2 l4 ?2 b( X  y2 L
假定设置中断优先级组为2,+ D  O( k% N+ l! g- w* l
设置中断3(RTC中断)的抢占优先级为2,响应优先级为1;
: k# w! R3 h( b3 L* {0 N" c设置中断6(外部中断0)的抢占优先级为3,响应优先级为0;
6 M  d' k: D- d$ x' A" e! f设置中断7(外部中断1)的抢占优先级为2,响应优先级为0。
" D6 ~4 w- i5 X8 p% b那么这3个中断的优先级顺序为:中断7>中断3>中断6。% s  F$ c7 ?+ f. c
**备注:**一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。
: {$ D9 H) x+ q' H; r6 D# I# N: {0 s8 T" H8 B  `
5. 中断优先级分组函数:0 n' t6 p/ S& s. |) E) u# W% W

' E! P) K; r( i. L
  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
    ( y; f& e' p! Y) ~) t8 }* y
  2. {: M5 z* u. q; X; N: d
  3. assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));3 R8 ~9 H/ Y2 R8 `& w& x
  4. SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
    3 c# P! L0 Q. n% W! F5 F$ t$ b
  5. }: M5 R+ R; ~* n! r; e- n
  6. //例如NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//
复制代码
5 `/ ^% Q0 V7 c; i
6. MDK中NVIC寄存器结构体
2 |5 _* S& O. Z2 E+ T+ T' W# Y6 V* q: `' J9 u6 w
  1. typedef struct" g+ H3 ~% f, y. O* k
  2. {
    - c4 g" \; Y6 A& |5 }
  3. __IO uint32_t ISER[8];         //中断使能寄存器组//         $ y4 g9 m. a4 X! x, J& F
  4. uint32_t RESERVED0[24];                                   
    7 O$ L, @8 m. C" K3 f
  5. __IO uint32_t ICER[8];         //中断失能寄存器组//              
      t& M# K: H* s
  6. uint32_t  RSERVED1[24];                                    % E0 }0 X4 y3 O/ }
  7. __IO uint32_t ISPR[8];         //中断挂起寄存器组//           % z/ @: N" D/ e1 k
  8. uint32_t RESERVED2[24];                                   
    2 O" ]6 w* @# ^6 @( f4 S, C
  9. __IO uint32_t ICPR[8];         //中断解挂寄存器组//         
    ! s9 D" a+ q. [! b# q0 ]
  10. uint32_t RESERVED3[24];                                   
    - r: a) Q  v6 Q( V; b. P
  11. __IO uint32_t IABR[8];         //中断激活标志位寄存器组//            
    0 b- T) N- [, O' c. m: i
  12. uint32_t RESERVED4[56];                                   9 i+ K' C) C2 K( \: l7 r
  13. __IO uint8_t    IP[240];       //中断优先级控制的寄存器组//                 
    ( f7 K, r% M6 E! R! j6 Q
  14. uint32_t RESERVED5[644];                                  - h+ d' F  \. E3 @( N+ X
  15. __O  uint32_t STIR;                        
    ( d+ E2 Y- P9 z- g/ M/ q6 m% |
  16. }
    ' c, Y4 A( C9 y+ L
  17. NVIC_Type;
复制代码
, b* ^$ n) H7 q4 i5 y+ s0 o) M
7. 每个中断的优先级设置

1 b% i" W& o6 H$ C, _1.1 中断优先级控制的寄存器组:IP[240] (全称:Interrupt Priority Registers)
, k8 @- M8 f6 Z240个8位寄存器,每个中断使用一个寄存器来确定优先级。STM32F10x系列一共60个可屏蔽中断,使用IP[59]~IP[0]。每个IP寄存器的高4位用来设置抢占和响应优先级(根据分组),低4位没有用到。
# ^! T* p  E  k& ~相关函数:( _' t" @! ^; A2 l1 M* I
0 D( |. U  X( `% V" e
  1. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
复制代码

; M( c& v& _! B4 v9 l7.2 中断使能寄存器组:ISER[8] (作用:用来使能中断)% \5 o* ^* n  W
32位寄存器,每个位控制一个中断的使能。STM32F10x只有60个可屏蔽中断,所以只使用了其中的ISER[0]和ISER[1]。ISER[0]的bit0bit31分别对应中断031。ISER[1]的bit027对应中断3259。
' U: E; A/ o, p0 z% C# M相关函数:, P  Z! G& n$ `8 V8 P+ a

" c: r; r. Y" b) P& |
  1. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
复制代码

: J$ A% O2 _0 ^  Y7.3 中断失能寄存器组:ICER[8] (作用:用来失能中断)
- g, O* F9 I8 p( \32位寄存器,每个位控制一个中断的失能。STM32F10x只有60个可屏蔽中断,所以只使用了其中的ICER[0]和ICER[1]。ICER[0]的bit0bit31分别对应中断031。ICER[1]的bit027对应中断3259。
: N6 A  C9 w. y1 X- ^相关函数:8 A4 G6 c& f2 l+ s. t& q1 v0 `

. [' G3 k9 d6 d6 U- |) K8 K4 Y
  1. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
复制代码

7 J3 J- U# D+ M) }5 J7 H) R: m7.4 中断挂起控制寄存器组:ISPR[8] (作用:用来挂起中断)8 L0 ]7 U  O/ h6 P  c9 [8 a
7.5 中断解挂控制寄存器组:ICPR[8] (作用:用来解挂中断)
" ]! v+ l4 ]9 [  }( B; f& {
  c+ V5 [6 ?' D* j1 a* Q6 p# W
  1. //7.4和7.5涉及的部分相关函数//# X3 ]- t. ^+ S$ X' M& A
  2. static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);/ v$ m: p$ ?7 a3 l
  3. static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);8 G5 t& c2 U- T0 Y+ l& w' L9 ?
  4. static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn);  [7 m& I* Z' _3 ^( K
  5. //以上函数位于core_cm3.h文件中//
复制代码

& \; X0 e0 ^  ]1 D8 @7.6 中断激活标志位寄存器组:IABR [8] (作用:只读,通过它可以知道当前在执行的中断是哪一个)6 L0 o# K7 R% w; \1 B" r
如果对应位为1,说明该中断正在执行。
3 v) q- H( {# E' D+ ~, }相关函数:
5 A: d& `3 X: s( Y+ F& f; @$ m/ b$ S. K; I3 B! M$ f  D
  1. static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn);
复制代码
4 l: O' r* E8 L6 _6 Q
8. 中断参数初始化函数解读
/ ~; A* x* u4 F  ^9 O" |7 J, [

, N8 l0 {9 G5 I) C& ^. X
  1. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);  v7 j1 H8 U0 ~3 p
  2. typedef struct
    1 f$ m% p$ T# F" Y
  3. {) L& C# I1 S8 i
  4. uint8_t NVIC_IRQChannel;                             //设置中断通道//+ T% s! T: B7 [7 `5 u7 v9 z1 i! T
  5. uint8_t NVIC_IRQChannelPreemptionPriority;           //设置抢占优先级//  v! Z% Y: @& C  \9 @/ ]' p& {
  6. uint8_t NVIC_IRQChannelSubPriority;                  //设置相应优先级//
    + f2 F5 U; ]" t8 N) |9 ~$ O! ]6 q6 U
  7. FunctionalState NVIC_IRQChannelCmd;                  //使能//# l* m7 M. \8 [7 ^1 u: f
  8. }NVIC_InitTypeDef;                                   //位于misc.h文件中//
    " Y! L; G. q$ y2 i/ \7 \1 y
  9. NVIC_InitTypeDef   NVIC_InitStructure; ; E, d3 X" w( e6 h, N8 Q
  10. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;          //串口1中断,中断类型参考stm32f10x.h中的IRQn_Tpye;//
    * g) K6 j' E5 T0 U; f
  11. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;    //抢占优先级为1//: }5 o, x9 Z: p$ X# p3 ~1 a4 D/ ]
  12. NVIC_InitStructure.NVIC_IRQChannelSubPriority= 2;          //响应优先级位2//
    ; L7 a* Z2 l% o5 o( u: ]
  13. NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;             //IRQ通道使能//* [5 Y8 z0 B; |6 ^1 s' N& y
  14. NVIC_Init(&NVIC_InitStructure);                            //根据上面指定的参数初始化NVIC寄存器//
复制代码

: L3 @$ Q5 L4 Y: d+ L. y* N4 X9. 中断优先级设置步骤
1 [( F9 o9 x' t
9.1 系统运行后先设置中断优先级分组;* n7 E' U: X5 ?4 p
. s# H  r- s; f" G8 T
  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);  //整个系统执行过程中,只设置一次中断分组;//
复制代码
- S$ C' J# A# ~4 l8 O
9.2 针对每个中断,设置对应的抢占优先级和响应优先级;
) D) O$ Q( n* ~* r% k
8 ?+ J5 T# z0 C0 G6 U$ w
  1. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
复制代码
5 n# b  d( q, H% E9 S7 V/ |
9.3 如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。, f6 l7 |" H' O# C
————————————————
; o( D  N2 Q, _! z1 R( u8 H' z4 V版权声明:天亮继续睡
3 d1 ~* w* y+ s( s1 a- T( |" f$ Q; N5 Q$ G, T6 D7 u5 b  i' J
: m! k+ x! }" y7 |$ H3 v- h* S1 B
赞 收藏 评论0 发布时间:2022-11-21 17:00

举报

0个回答

所属标签

相似技术帖

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