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

【经验分享】STM32之NVIC

[复制链接]
STMCU小助手 发布时间:2022-2-2 20:00
1.1优先级分组
首先,我们先通过标识来解释手册里NVIC向量表的含义:
810734-20191003085041023-632236589.png
% r8 ~; z7 S/ i  \- s: W, y( K7 p& g
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
, h3 G. Z! H1 u/ z/ E% {! w
如果用图来形象表示,则看图1.1-8位中断分组 :

3 p" @% ^; ]) f5 l! L2 B
810734-20191003081629753-759539393.png

" e+ K8 R! x/ o
1.1 8位中断分组
stm32为了节省材料成本,并没有完全使用这8位,它忽略低4位。如下图1-2
% T* M+ h' b7 x
810734-20191003082134842-1067264450.png
1.2 高位分组

9 c1 W9 b  V' N( e: J. G9 v
                                        表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
% H- n# \! P. k0 M. s

0 M0 z: m: ~$ N5 z9 p2 J1.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"
    : w% i/ J( ?" O6 |  C9 I

  2. " F  k3 B' T+ g4 [
  3. //PA9 ----TXD--发送数据      (站在芯片角度)
    , {, g! g; `- v7 c  v1 F) a; Z
  4. //PA10 --- RXD--接收收据    (站在芯片角度)* f7 v. _* u7 H% h/ E6 `
  5. void Usart1_Init(u32 baudRate)
    ) n7 k! Q+ v4 r
  6. {
    8 s7 f& ^" {9 m5 _& I$ }+ A
  7.     u32 prio;. @, q0 ^$ `% @2 t& h8 u/ k
  8.     float USARTDIV;* g+ \! d+ B1 X3 |& ?. i% b
  9.     u16 Mantissa;  //整数
    2 }) M" k# p) E* {1 z7 R
  10.     u8 Fraction;   //小数
    * z% R( S* v( l. C  V+ J$ L
  11. . Y' u2 _, Z, A( n6 b$ O6 }7 [
  12.     /****使能GPIOA的时钟***/1 H; i7 h1 w+ P9 ^6 `$ V- M
  13.     RCC->AHB1ENR |= 1<<0;
    5 m' t9 H1 K  V! j% t

  14. 7 E% Y: R. ~# W
  15.     /****配置PA10为复用功能+上拉***/' d) F+ ^# m& V8 i6 i& h' T) u
  16.     GPIOA->MODER |= 2<<20;//复用功能. f5 K! J6 a0 x: ?' d% c
  17.     GPIOA->PUPDR |= 1<<20;//上拉1 C& ^1 w$ l* I4 J. |/ K& }* Q) c
  18.     /****配置PA9位复用功能+推挽***/# b8 j7 S) Y: `
  19.     GPIOA->MODER |= 2<<18;//复用功能3 j! ~# ~, \4 k. P4 r5 p2 N. a
  20.     GPIOA->OTYPER &=~(1<<9);//推挽, j8 j0 }  e1 n( I% f; m
  21. ) {& g4 Z2 j* d8 b! X0 d5 }
  22.     /****PA9选择复用功能7,TXD***/
    7 l* ~3 @; J; D
  23.     GPIOA->AFR[1] |= 7<<4 ;
    $ ^) S1 l4 q2 `6 J; Q
  24.     /****PA10选择复用功能7,RXD***/
    ( ]1 y* u) w$ }* }. f
  25.     GPIOA->AFR[1] |= 7<<8 ;
    4 |" U& J  R! K( m; Y, C
  26.    
    * H  V. J# T6 B$ \- @
  27.     /****使能串口1的时钟***/
    1 D: o' U# ~1 d% h
  28.     RCC->APB2ENR |= 1<<4;$ J- O" G* O7 p9 [$ L

  29. 6 o. \1 ]6 c6 t; a( N
  30.     /****设置数据帧格式***/& ?* i/ t3 h" G) @  u
  31.     USART1->CR1 |= 1<<15;//OVER8设置为1
    3 \" ~% W; o: O/ r' r$ [4 W( o! g
  32.         USART1->CR1 &=~(1<<12);//将串口1的数据帧设置为“1 起始位, 8 数据位, n 停止位 ”; I# q, M/ B! \% R% a5 {2 A: h% ?
  33.     USART1->CR2 &=~(3<<12);//1位停止位
    1 n( B4 ]/ S6 u- ], [( J
  34.     USART1->CR1 &=~(1<<10);//禁止奇偶校验
    " J3 u& O. Z( L$ ]" K7 L
  35.    
    + t: X& e8 R# s, c' k
  36.     /****设置波特率***/4 y$ p0 ]/ F- Y3 v" {* A
  37.     //USARTDIV =  fCK/8*(2- OVER8 )/TxRx 波特率, d, ?( W$ ]0 r
  38. " K8 H; Y/ L6 k" T
  39.     USARTDIV = (float)84000000/8/baudRate;
    & H  @# O7 ^1 h  |
  40.     Mantissa = (int)USARTDIV;
    ! D* X# C! W# N
  41.     Fraction = (u8)((USARTDIV-Mantissa)*16);/ V9 c8 F- J4 o
  42.     USART1->BRR = Mantissa<<4 | Fraction;
    4 \1 u/ c: i- m
  43.    
    : Y2 J# M# H9 x) U
  44.     5 A1 J+ T6 s6 k
  45.     USART1->CR1 |= 1<<5;  //使能串口接收中断
      D% h% z! _9 S! O' V& i9 G, D
  46.     NVIC_SetPriorityGrouping(5);  //设置优先级分组设置为组5,注意:一个工程只能有一个分组" y3 {6 R9 h0 x- {* G
  47.     prio = NVIC_EncodePriority(5,2,2); //组5,抢占优先级为2,响应优先级为2; h+ J# S8 B# C7 e
  48.     NVIC_SetPriority(USART1_IRQn,prio);- n) C- ~/ H+ h( T4 k9 N
  49.     NVIC_EnableIRQ(USART1_IRQn);  //使能串口1中断通道USART1_IRQn==37  也可以用37表示串口1的通道编号
    ( I/ ?$ B7 Z. c' Y# v! v7 f
  50.      
    " `8 H7 f2 B5 V2 L% r
  51.     USART1->CR1 |= 1<<3;//使能发送器
    $ E/ w4 s7 a/ A0 K! O
  52.     USART1->CR1 |= 1<<2;//使能接收器
    ( _) V2 n* v- _7 W! w
  53.     USART1->CR1 |= 1<<13;//使能串口11 ~% R7 Q: V/ k* ~$ ~6 M
  54. }
    # d/ E  U" r' E  o, x
  55. //中断服务程序代码,在接收到一个字节是会进入串口中断服务函数
    ) N9 t, O* W+ L) S
  56. void USART1_IRQHandler(void)7 T( g! @1 U# T! \
  57. {( m2 n/ F) A0 F! A$ p
  58.     u8 data;* D$ \4 l" h1 j1 J
  59.     if(USART1->SR&(1<<5)). ]( J1 h# O  E
  60.     {& u7 `; i: |5 C5 `( P7 r+ B
  61.         data = USART1->DR;; ~/ u* f: z4 @
  62.         /*******接收到一个字节原样回发*******/
    5 X; b3 u! t8 d5 X2 \% o
  63.         USART1->DR = data;
    7 _; P6 O# s- [& s4 c! @! _
  64.         while(!(USART1->SR&(1<<6))); 1 K! j2 X7 `1 X( b; y
  65.         USART1->SR &=~(1<<6);  //清零
    & w2 {; c* E$ \: w' P" i4 c5 |
  66.     }
    2 n! i1 g; T, r2 }* o! ~2 Y( m, Q' H! `, ~
  67. }
复制代码
0 W: M) m4 A2 i
赞 收藏 评论0 发布时间:2022-2-2 20:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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