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

【经验分享】STM32之NVIC

[复制链接]
STMCU小助手 发布时间:2022-2-2 20:00
1.1优先级分组
首先,我们先通过标识来解释手册里NVIC向量表的含义:
810734-20191003085041023-632236589.png - E! S5 T5 k/ j8 z
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
/ o: l! k& W. R& ^9 E
如果用图来形象表示,则看图1.1-8位中断分组 :

, ~# w( L6 u* t5 D- R' S6 [
810734-20191003081629753-759539393.png
9 D( }6 v8 I8 l: J  R# E: Y
1.1 8位中断分组
stm32为了节省材料成本,并没有完全使用这8位,它忽略低4位。如下图1-2
+ R) w4 C* u) i2 f- ^0 P
810734-20191003082134842-1067264450.png
1.2 高位分组
3 j: w& t3 p7 o, {5 g: z/ P
                                        表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

* U5 O/ A6 T, d  B% r/ v3 i  f* J8 _( `# j( d/ F9 X0 `6 C7 k, K
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"
    % L! G! V* F! _& s  d2 i+ Z% P
  2. ' q7 ^$ C! _' S9 m! H% e7 O! J1 C
  3. //PA9 ----TXD--发送数据      (站在芯片角度)* i7 a1 I& i& p1 E0 T) a, J
  4. //PA10 --- RXD--接收收据    (站在芯片角度)9 C1 `5 k5 U9 T- l" f6 h& s
  5. void Usart1_Init(u32 baudRate)) c7 ^) X: w" P5 L' o9 e5 _
  6. {
    0 g' H% D* t6 ]4 r" l5 r
  7.     u32 prio;6 g" e2 i5 a7 g( S0 h& Z
  8.     float USARTDIV;/ a5 q/ o1 E9 i. o; p
  9.     u16 Mantissa;  //整数
    . p+ g, @. b3 t8 P1 l; H, c! \6 e
  10.     u8 Fraction;   //小数
    $ \3 `+ d$ y1 Q6 x9 C: W
  11. 2 D# D% ]! H0 R" `) R0 p
  12.     /****使能GPIOA的时钟***/2 ^, L8 e- U' I: `/ P
  13.     RCC->AHB1ENR |= 1<<0;2 B; E! k/ ]' N" ?5 Y
  14. $ L0 }; X: \1 n% n
  15.     /****配置PA10为复用功能+上拉***/+ \6 q* S: w1 m1 J
  16.     GPIOA->MODER |= 2<<20;//复用功能
    9 Z4 R1 k2 Y! H
  17.     GPIOA->PUPDR |= 1<<20;//上拉
    : _: J% Y8 O6 x( s6 y
  18.     /****配置PA9位复用功能+推挽***/
    1 c+ @( Z3 P8 C: \7 Z$ E
  19.     GPIOA->MODER |= 2<<18;//复用功能
    ' s5 _0 `" t5 y( a3 V: l
  20.     GPIOA->OTYPER &=~(1<<9);//推挽
    # v: p) P( J0 m# G/ [' g+ W! p* c

  21. / n+ N; f+ t/ p' N( B/ z
  22.     /****PA9选择复用功能7,TXD***/
    ' j) {8 }0 @* w7 p4 `
  23.     GPIOA->AFR[1] |= 7<<4 ;
    % M7 y4 Y. f0 Y0 E
  24.     /****PA10选择复用功能7,RXD***/7 S+ P/ r* ?5 S
  25.     GPIOA->AFR[1] |= 7<<8 ;
    ; n$ X8 y2 B! }# L
  26.     - Z& ^% A: h% H# v
  27.     /****使能串口1的时钟***/
    % ^4 N4 O) e! _; a+ U5 `: T
  28.     RCC->APB2ENR |= 1<<4;' n2 ?* Z1 b) b9 F, C0 A

  29. 7 l8 w: p# s  @  ], ~# T
  30.     /****设置数据帧格式***/
    2 k" w3 b/ a+ s- G5 q4 ^
  31.     USART1->CR1 |= 1<<15;//OVER8设置为13 Y" C% Q' b+ {6 w* o7 N3 w( q/ u) I
  32.         USART1->CR1 &=~(1<<12);//将串口1的数据帧设置为“1 起始位, 8 数据位, n 停止位 ”3 ~6 ]0 l6 n+ [
  33.     USART1->CR2 &=~(3<<12);//1位停止位$ N* B; ^' @; A! ]: N
  34.     USART1->CR1 &=~(1<<10);//禁止奇偶校验
    2 ~; A0 F/ s, l6 R; Q/ o5 G
  35.    
    . U4 h1 ~8 O' n' E- R+ t
  36.     /****设置波特率***/8 z' f! x, [: K9 ^4 L" H. v4 @
  37.     //USARTDIV =  fCK/8*(2- OVER8 )/TxRx 波特率
    7 @$ p# M5 O' Z
  38. 6 O9 m4 R6 F$ {2 e! }0 |
  39.     USARTDIV = (float)84000000/8/baudRate;0 P! @6 n9 O1 J8 S, t. Q3 n
  40.     Mantissa = (int)USARTDIV;
    9 f7 J+ g( j9 w1 P$ M( g
  41.     Fraction = (u8)((USARTDIV-Mantissa)*16);+ a) d% S* R, q! m  d# q9 a* r
  42.     USART1->BRR = Mantissa<<4 | Fraction;
    5 f/ p1 f4 R, z3 E
  43.    
    1 b& g/ I  j' b! n
  44.    
    ) h3 R3 ?0 L! p; w% V1 d
  45.     USART1->CR1 |= 1<<5;  //使能串口接收中断
    6 Z. h. p6 ~8 ]  x/ q3 e# e2 ]# e' h
  46.     NVIC_SetPriorityGrouping(5);  //设置优先级分组设置为组5,注意:一个工程只能有一个分组+ R2 Y. z  n7 ~% l
  47.     prio = NVIC_EncodePriority(5,2,2); //组5,抢占优先级为2,响应优先级为26 a! O- d$ S5 o: q9 `
  48.     NVIC_SetPriority(USART1_IRQn,prio);
    . C! j1 G. L$ F+ p2 I$ ]# e! N
  49.     NVIC_EnableIRQ(USART1_IRQn);  //使能串口1中断通道USART1_IRQn==37  也可以用37表示串口1的通道编号: o, A  Y6 q9 Z2 p: P
  50.      
    7 H2 X# N7 K+ g, F" @7 r
  51.     USART1->CR1 |= 1<<3;//使能发送器
    0 X) v5 |, a. }% Z+ {# c" I6 Q; o* ~
  52.     USART1->CR1 |= 1<<2;//使能接收器
    ! w; ~3 a9 l: S1 ?! y8 J$ Q/ A
  53.     USART1->CR1 |= 1<<13;//使能串口1# `" A! u. i; v( }% q
  54. }
    # i: U: }$ p4 u9 J( B+ R$ p
  55. //中断服务程序代码,在接收到一个字节是会进入串口中断服务函数
    ' F3 y) W7 M' q% v1 o1 t8 D* H5 h
  56. void USART1_IRQHandler(void)
    , l1 [7 f- M" r5 E! S
  57. {
      l0 Z6 X& d7 o" h2 |; _. P: e3 L
  58.     u8 data;
    6 z* d- p& T/ g; O1 C! R6 D
  59.     if(USART1->SR&(1<<5))$ }' ^  y1 x( p7 T( Y
  60.     {
    7 K2 l: F+ W' s1 x- _
  61.         data = USART1->DR;
    # F, i4 Z( ^$ H  R0 N7 i5 _
  62.         /*******接收到一个字节原样回发*******/
    % t: L8 S3 S% H! M
  63.         USART1->DR = data;6 [5 Q2 g: Y; ?6 K1 q" t
  64.         while(!(USART1->SR&(1<<6))); 7 V) a! _8 I0 W) F2 T# @5 U. z
  65.         USART1->SR &=~(1<<6);  //清零$ E0 ^/ }* r3 W- I
  66.     }
    % {" z5 T9 H' V1 Q4 i4 r
  67. }
复制代码
' r5 L' i, v# J" l) D
收藏 评论0 发布时间:2022-2-2 20:00

举报

0个回答

所属标签

相似分享

官网相关资源

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