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

【经验分享】STM32之NVIC

[复制链接]
STMCU小助手 发布时间:2022-2-2 20:00
1.1优先级分组
首先,我们先通过标识来解释手册里NVIC向量表的含义:
810734-20191003085041023-632236589.png
  ^' F+ c! Q4 u7 k& B2 B8 A3 W
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
% r; J: B2 Y8 E  g
如果用图来形象表示,则看图1.1-8位中断分组 :
( j3 h+ K: C& v# C% ^4 N9 b( c) e
810734-20191003081629753-759539393.png
+ Q% V7 ?7 H1 f
1.1 8位中断分组
stm32为了节省材料成本,并没有完全使用这8位,它忽略低4位。如下图1-2

2 u+ x  H- Q1 t: z+ q8 e2 z
810734-20191003082134842-1067264450.png
1.2 高位分组

% K$ r  h- b; o4 w* d7 R- J  M
                                        表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
: A7 \4 _% [+ c2 I9 l+ I: F

1 R* q. h1 q6 D2 ~) x6 z% H1.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"
    % s* b, ?/ y% ~2 Z9 E
  2. . F$ a; ]: y1 U, B
  3. //PA9 ----TXD--发送数据      (站在芯片角度)
    - a0 ?4 {6 {# [/ A0 Y' v1 r5 l
  4. //PA10 --- RXD--接收收据    (站在芯片角度)1 Y8 _+ ?5 q1 R+ O
  5. void Usart1_Init(u32 baudRate)  @2 ]8 V3 n  Z. V  B0 P
  6. {3 ^% o( a1 I3 E9 m; I3 _
  7.     u32 prio;
    9 Q: Y! \6 G( }9 {
  8.     float USARTDIV;' ^: d/ D8 {5 e' H1 Z
  9.     u16 Mantissa;  //整数
    + J- ?, n/ Q( |
  10.     u8 Fraction;   //小数3 J$ ~. I% f& c* D& |! G5 K

  11. / K2 _. C6 ?# n% o$ F
  12.     /****使能GPIOA的时钟***/; r- z$ j5 G  K1 ~2 }
  13.     RCC->AHB1ENR |= 1<<0;) p3 Q8 Z: _0 u  U+ F* w

  14. 1 s* p* u4 D4 f+ ?# |
  15.     /****配置PA10为复用功能+上拉***/
    7 `, U' K; N3 _$ J. \0 N9 Q; q
  16.     GPIOA->MODER |= 2<<20;//复用功能1 U! s- t2 D3 P7 z( |! ~) V  e
  17.     GPIOA->PUPDR |= 1<<20;//上拉
    * x# F- P' |4 h
  18.     /****配置PA9位复用功能+推挽***/
    ( J) l6 A: z' f: y; H2 [0 J
  19.     GPIOA->MODER |= 2<<18;//复用功能
    . R: A2 {2 {& Q  v3 T0 E. D
  20.     GPIOA->OTYPER &=~(1<<9);//推挽
      j1 S1 L5 K  B4 u& @
  21. ! b0 q! p6 y* u' s
  22.     /****PA9选择复用功能7,TXD***/& G) d; u" F* ]2 s; E
  23.     GPIOA->AFR[1] |= 7<<4 ;
    : G, h  Y" G- V- z5 j& A
  24.     /****PA10选择复用功能7,RXD***/
    7 H! }( {+ |* y: X/ ?3 u9 W2 g, y
  25.     GPIOA->AFR[1] |= 7<<8 ;
    5 r( t- _) R7 K+ x( n5 u
  26.     : v0 \5 f# a, c/ ]7 ]  s8 i# \$ R
  27.     /****使能串口1的时钟***/
    - f' G7 M- B% O0 {5 O8 \) N. ~9 E
  28.     RCC->APB2ENR |= 1<<4;
    ' Y+ E, `7 t* _! Z6 I

  29.   ^! o( R, f& h4 t/ h
  30.     /****设置数据帧格式***/
    ; w  H7 p7 l" n$ @  z- R
  31.     USART1->CR1 |= 1<<15;//OVER8设置为1  p; f7 o* R& W9 v
  32.         USART1->CR1 &=~(1<<12);//将串口1的数据帧设置为“1 起始位, 8 数据位, n 停止位 ”, x8 g0 e2 C, s5 ~9 l3 l) P
  33.     USART1->CR2 &=~(3<<12);//1位停止位6 O) }6 X2 u3 V& n
  34.     USART1->CR1 &=~(1<<10);//禁止奇偶校验* j; v* O/ M, E, n( b% s& ~  s. k
  35.    
    5 p8 \' J0 |0 }$ L  w0 p
  36.     /****设置波特率***/7 H  h# y4 \! K3 z) P
  37.     //USARTDIV =  fCK/8*(2- OVER8 )/TxRx 波特率
    ) _  g0 s, b- w# g; q, _

  38. # F5 x8 P5 J$ W: |! E, F8 F/ U
  39.     USARTDIV = (float)84000000/8/baudRate;
    0 }! y6 Z* j# ], U7 y# i! \
  40.     Mantissa = (int)USARTDIV;& s/ m& G# k0 h: j, G5 J
  41.     Fraction = (u8)((USARTDIV-Mantissa)*16);- U9 e. }0 J2 Z& C( V  }4 [2 G5 ~
  42.     USART1->BRR = Mantissa<<4 | Fraction;
    8 d6 m* F# Z8 k
  43.     7 z, ?* B% l  w3 C
  44.     7 U4 |6 J5 a% {( ~7 r3 t9 j% k
  45.     USART1->CR1 |= 1<<5;  //使能串口接收中断
    : g) F$ o- r# X
  46.     NVIC_SetPriorityGrouping(5);  //设置优先级分组设置为组5,注意:一个工程只能有一个分组0 w; |- S2 N! q/ W% k; P: J
  47.     prio = NVIC_EncodePriority(5,2,2); //组5,抢占优先级为2,响应优先级为22 \( @; Z' D" M) ?
  48.     NVIC_SetPriority(USART1_IRQn,prio);3 ]7 V: E, v2 q6 U
  49.     NVIC_EnableIRQ(USART1_IRQn);  //使能串口1中断通道USART1_IRQn==37  也可以用37表示串口1的通道编号( X! d, B# D4 `1 G! H9 ?
  50.      
    ' H! U/ X% P# ?1 e; r
  51.     USART1->CR1 |= 1<<3;//使能发送器
    % U' g3 ~7 G: {% h' [
  52.     USART1->CR1 |= 1<<2;//使能接收器2 G! k; ]1 g+ P+ s; u( K
  53.     USART1->CR1 |= 1<<13;//使能串口1
    * w: F. U: `  m' L3 q, G9 R1 z
  54. }
    0 ^* m9 j5 l& R. L7 `2 B
  55. //中断服务程序代码,在接收到一个字节是会进入串口中断服务函数- }3 Z$ A  y4 c1 {( @7 l% C" L9 Z
  56. void USART1_IRQHandler(void)
    8 G( Z) n. {( c
  57. {0 s. M# J( y/ l9 L6 Y( ]+ ]+ f
  58.     u8 data;: B; W# f1 K0 p% w0 J
  59.     if(USART1->SR&(1<<5))8 B2 |9 Z+ _( K* B! P  I9 {2 B) m
  60.     {
    & v* {* g3 K& G' @. c% h- F
  61.         data = USART1->DR;' m4 H' z9 z9 D& g% q
  62.         /*******接收到一个字节原样回发*******/: n6 i3 d) x! z8 `: Q
  63.         USART1->DR = data;2 r: V, e$ J! M9 x
  64.         while(!(USART1->SR&(1<<6))); ! o$ \$ s. t7 J# J) A
  65.         USART1->SR &=~(1<<6);  //清零; `7 z- Q$ l/ G$ a# D/ ^
  66.     }
    ! L' v/ t1 F/ M0 R( _5 Z
  67. }
复制代码
4 H* l8 Y: E: n+ R4 }( e5 y6 V
收藏 评论0 发布时间:2022-2-2 20:00

举报

0个回答

所属标签

相似分享

官网相关资源

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