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

【经验分享】STM32之NVIC

[复制链接]
STMCU小助手 发布时间:2022-2-2 20:00
1.1优先级分组
首先,我们先通过标识来解释手册里NVIC向量表的含义:
810734-20191003085041023-632236589.png
! m- \* f6 D1 C3 D; d" F4 ~
Core-M4内核最多支持256级的可编程优先级。用8位来表示优先级级别,,优先级级别分为8组,分别是组0~组7,如表1.0所示    (8位范围:0~255)
                                                   表1.1 中断分组讲解
组号
抢占优先级
        响应优先级
0
用高七位表示抢占优先级
0~127
如果CPU的中断分组选择为“组 0”,则
抢占优先级可以设置为0~127,注意:数字越小,级别越高。
最低表示响应优先级
0~1
响应优先级可以设置为0或者1,注意:数字越小级别越高。
1
用高六位表示抢占优先级
如果CPU的中断分组选择为“组 1”,
抢占优先级可以设置为0~63
低两位表示响应优先级
响应优先级可以设置为0~3
2
用高5位表示抢占优先级
如果CPU的中断分组选择为“组 2”,
抢占优先级可以设置为0~31
低三位表示响应优先级
响应优先级可以设置为0~7
3
用高4位表示抢占优先级
如果CPU的中断分组选择为“组 2”,
抢占优先级可以设置为0~15
低四位表示响应优先级
响应优先级可以设置为0~15
4
用高3位表示抢占优先级
如果CPU的中断分组选择为“组 2”,
抢占优先级可以设置为0~7
低五位表示响应优先级
响应优先级可以设置为0~31
5
用高2位表示抢占优先级
如果CPU的中断分组选择为“组 2”,
抢占优先级可以设置为0~3
低6位表示响应优先级
响应优先级可以设置为0~63
6
最高位表示抢占优先级
如果CPU的中断分组选择为“组 2”,
抢占优先级可以设置为0~1
低7位表示响应优先级
响应优先级可以设置为0~127
7
8位表示响应优先级
响应优先级可以设置为0~255
; e+ G# U+ u! S& C5 h% X- [
如果用图来形象表示,则看图1.1-8位中断分组 :

/ ^. X  e% K4 G1 c
810734-20191003081629753-759539393.png
& v* @* @/ u0 w( M% H
1.1 8位中断分组
stm32为了节省材料成本,并没有完全使用这8位,它忽略低4位。如下图1-2
7 P: o9 ?" O4 X2 s4 i
810734-20191003082134842-1067264450.png
1.2 高位分组
& g1 \2 _5 M2 o
                                        表1.2  裁剪分组讲解
组号中断优先级分组说明抢占优先级等级范围响应优先级等级范围
3所有4位用于指定抢占优先级0~15不可设置
4最高3位用于指定抢占优先级,最低1位用于指定响应优先级0~70~1
5最高2位用于指定抢占优先级,最低2位用于指定响应优先级0~30~3
6最高1位用于指定抢占优先级,低3位用于指定响应优先级0~10~7
7所有4位用于指定响应优先级不可设置0~15
& e! E+ i4 l, `$ }' ^
0 x8 x0 q" W# a( A& M
1.2 NVIC中断中断控制器相关函数NVIC分组设置
void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
位置:core_cm4.h的1453行
作用:设置优先级分组。
参数:PriorityGroup优先级分组组号
举例:STM32的优先级分组设置为组5,则对应的代码如下:NVIC_SetPriorityGrouping(5);
NVIC具体中断优先级编码
uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
作用:设置抢占优先级和响应优先级的级别
位置:core_cm4.h的1610行
参数:PriorityGroup优先级分组组号;PreemptPriority:抢占优先级;SubPriority:响应优先级
返回值:32位的编码值,编码值用于中断优先级设置
举例:优先级分组选择为组5,抢占优先级为2,响应优先级为2,代码如下:
u32 prio;
prio = NVIC_EncodePriority(5,2,2);
NVIC中断优先级设置
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
作用:将优先级分组情况以及抢占优先级和响应优先级设置到响应的中断。
参数:
IRQn :中断通道编号。
priority:是NVIC_EncodePriority函数的返回值
举例:设置串口1全局中断的优先级分组选择为组5,抢占优先级为2,响应优先级为3
对应的代码:
u32 prio;
prio = NVIC_EncodePriority(5,2,3);
NVIC_SetPriority(37,prio);
也可以写成NVIC_SetPriority(USART1_IRQn,prio);
NVIC中断使能
void NVIC_EnableIRQ(IRQn_Type IRQn)
作用:使能中断通道
参数:IRQn :中断通道编号。
举例:使能串口1全局中断,NVIC_EnableIRQ(37);  可以写成NVIC_EnableIRQ(USART1_IRQn);
NVIC中断禁能
void NVIC_DisableIRQ(IRQn_Type IRQn)
作用:禁止中断通道。
参数:IRQn :中断通道编号。
举例:禁止串口1全局中断,NVIC_DisableIRQ(37);
1.3 实例代码之串口中断:
  1. #include "stm32f4xx.h"! r7 D( V# V( R8 J. T/ W
  2. - r$ @6 I. D+ G4 ^3 k
  3. //PA9 ----TXD--发送数据      (站在芯片角度): b/ ]/ k, w6 t
  4. //PA10 --- RXD--接收收据    (站在芯片角度)
    , w  d7 A3 y; S# j+ K
  5. void Usart1_Init(u32 baudRate); r/ N5 ^  v: |. U" P- j, P! ?
  6. {) e' g0 h7 g8 @: Z& n  I
  7.     u32 prio;
    1 e1 H$ s6 o/ [2 b% L; k* \# F5 N
  8.     float USARTDIV;
    / w/ X( K6 e& `& g+ u4 n
  9.     u16 Mantissa;  //整数
    ' @6 C- L: w  F; q& j/ P' w
  10.     u8 Fraction;   //小数" c3 Z) O1 u% E$ ]

  11. 1 E8 m; B! o, R7 }: T
  12.     /****使能GPIOA的时钟***/4 Q+ f% {5 h( a" ^3 s/ j4 g
  13.     RCC->AHB1ENR |= 1<<0;
    ) k& @3 G4 G  O+ x% J  X
  14. 0 u7 W' n! o+ t
  15.     /****配置PA10为复用功能+上拉***/
    9 K' x8 u! ?. V6 j
  16.     GPIOA->MODER |= 2<<20;//复用功能6 m$ g9 d, U$ L; @6 w# @6 M5 ?
  17.     GPIOA->PUPDR |= 1<<20;//上拉2 P* V8 B) c/ g0 A
  18.     /****配置PA9位复用功能+推挽***/
    ! H9 X8 W, W6 m( s
  19.     GPIOA->MODER |= 2<<18;//复用功能" n" b; q1 o/ z# _$ k  m
  20.     GPIOA->OTYPER &=~(1<<9);//推挽% Q5 n/ \8 H# k' w, C5 ?# i

  21. 3 V' `8 l9 D2 M3 [! L
  22.     /****PA9选择复用功能7,TXD***/
    ; }' `9 }2 [/ j8 [
  23.     GPIOA->AFR[1] |= 7<<4 ;. o# {. n' P% n9 Z) I
  24.     /****PA10选择复用功能7,RXD***/8 a9 P. \: V* w7 T  u0 ]$ t
  25.     GPIOA->AFR[1] |= 7<<8 ;
    4 i: i. w% n  ]- @
  26.     5 @2 |- I% z* Z
  27.     /****使能串口1的时钟***/
    / r1 q" J2 n8 R/ t* p, K* p/ K% A3 Q
  28.     RCC->APB2ENR |= 1<<4;# c$ y$ C% h% o- u) v& o
  29.   o2 E2 ]0 D/ `# c
  30.     /****设置数据帧格式***/( q. Q  X6 ?; |( v$ ~3 Y
  31.     USART1->CR1 |= 1<<15;//OVER8设置为1# W' j! y% ^  t. N' u" G
  32.         USART1->CR1 &=~(1<<12);//将串口1的数据帧设置为“1 起始位, 8 数据位, n 停止位 ”
    5 X% F! n8 r) P: ~
  33.     USART1->CR2 &=~(3<<12);//1位停止位/ m& q7 F3 A% y3 E4 C" ?& L
  34.     USART1->CR1 &=~(1<<10);//禁止奇偶校验
    8 W0 l( q4 d8 n6 }" y) J- U
  35.     ! t9 G" R  l  L) O% u+ h
  36.     /****设置波特率***/
    + q* d3 z8 G3 i  Q- o
  37.     //USARTDIV =  fCK/8*(2- OVER8 )/TxRx 波特率
    & F7 w( |$ a) ?! c

  38. 2 g, x% D; P: c. N* T% f3 [
  39.     USARTDIV = (float)84000000/8/baudRate;
    2 x% J. w! g, e  b+ J
  40.     Mantissa = (int)USARTDIV;
      ?* Y7 N. Q! ?) o
  41.     Fraction = (u8)((USARTDIV-Mantissa)*16);
    & \9 |3 J$ Y5 C# s( o. e, g) ]& ?
  42.     USART1->BRR = Mantissa<<4 | Fraction;# c& G; _& K* k. n( F+ v
  43.    
    & ^7 |- H1 ]5 v& I+ y  J- \! h' R+ l
  44.    
    2 m( @+ E5 T6 y5 V5 U* H' x
  45.     USART1->CR1 |= 1<<5;  //使能串口接收中断
    ) b8 t$ f) a' _, M: l4 \0 o
  46.     NVIC_SetPriorityGrouping(5);  //设置优先级分组设置为组5,注意:一个工程只能有一个分组' q2 t! m) b6 g1 T# {. P
  47.     prio = NVIC_EncodePriority(5,2,2); //组5,抢占优先级为2,响应优先级为2
    6 u2 a. a% }; o5 _
  48.     NVIC_SetPriority(USART1_IRQn,prio);
    3 W0 p; c0 W5 R3 @& Y3 n- a1 Y
  49.     NVIC_EnableIRQ(USART1_IRQn);  //使能串口1中断通道USART1_IRQn==37  也可以用37表示串口1的通道编号  J, p: y6 p6 Z# F
  50.      
    # m, j- i) r4 v5 [9 |( W! m) x
  51.     USART1->CR1 |= 1<<3;//使能发送器
    & G8 z3 f5 l: S2 R
  52.     USART1->CR1 |= 1<<2;//使能接收器
    ! I5 W3 h7 j! \, x$ X9 W
  53.     USART1->CR1 |= 1<<13;//使能串口1) H7 I% \: l0 K8 t0 `' c6 _* S8 U
  54. }% {# J1 m& H) Q
  55. //中断服务程序代码,在接收到一个字节是会进入串口中断服务函数
    . [, W9 v4 E- p: S# ]
  56. void USART1_IRQHandler(void)
    / m' ]5 p8 P2 P' q9 v7 o
  57. {5 G9 q6 D/ G# f
  58.     u8 data;
    . P3 E7 _" Q  m7 |
  59.     if(USART1->SR&(1<<5))  U  P) a+ p. U4 {' j# l( s6 M5 @
  60.     {
    7 O4 e9 l4 W& R1 m
  61.         data = USART1->DR;
    . O( j  U, a* M" b
  62.         /*******接收到一个字节原样回发*******/) Y8 V5 }) Y& T- v2 b! G
  63.         USART1->DR = data;/ \  B& b0 U# ~7 c/ E! h
  64.         while(!(USART1->SR&(1<<6))); ! ?4 ?$ V2 Y1 X
  65.         USART1->SR &=~(1<<6);  //清零
    ; b: T0 K( i0 s# a  D0 }
  66.     }9 \% o; S7 ^3 p0 [( Z9 f6 J
  67. }
复制代码
+ _; N, k8 U" Y7 y
收藏 评论0 发布时间:2022-2-2 20:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版