NVIC寄存器详解(基于STM32F103XX型号讲解)

前言:

NVIC全名为嵌套向量中断控制器(Nested vectoredinterrupt controller),用于中断分组,进而给很更好的设置抢占优先级和响应优先级。

NVIC寄存器的基本结构:

对于现在的STM32的MCU,每个中断通道的优先级都是使用NVIC寄存器中的8位来控制的,一共有2^8=256种不同等级的中断(16个内核中断+240个外部中断),由于STM32用不了那么多中断,故有些厂家根据自己使用的芯片进行了调整。

在我使用的STM32F103XX系列的单片机上,因为低四位被厂家限制取零,故只可以使用上四位寄存器进行中断方式选择,所以只有2^4=16种不同的中断。

在开始讲解NVIC寄存器的工作方式之前,先讲解两个十分重要的知识点:抢占优先级响应优先级

抢占优先级:

打断正在执行的任务A,并执行下一个新的任务B,执行完新任务B之后,在继续执行任务A,此属性由NVIC_IRQChannelPreemptionPriority 的参数配置。

类似此文中提到的中断和中断嵌套:stm32 学习记录(持续更新)-CSDN博客

响应优先级:

当两个相同抢占优先级的中断在同一时间被触发时,就先处理响应优先级较高的中断,此属性可以由NVIC_IRQChannelSubPriority 参数配置。

注意:当抢占优先级与响应优先级都相同时,就按中断号进行排队

中断优先级的分组:

此图的大致意思就是:

当为分组0时,NVIC寄存器的4位全部用于响应优先级

当为分组1时,NVIC寄存器的1位用于抢占优先级,NVIC寄存器的其它3位用于响应优先级

当为分组2时,NVIC寄存器的2位用于抢占优先级,NVIC寄存器的其它2位用于响应优先级

当为分组3时,NVIC寄存器的3位用于抢占优先级,NVIC寄存器的其它1位用于响应优先级

当为分组4时,NVIC寄存器的4位用于抢占优先级

结论:抢占优先级>响应优先级>STM32默认中断级别

NVIC寄存器的配置过程:

1.使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。

在此处共有5种配置情况(就是刚刚所讲的 “中断优先级的分组”),分别为:

NVIC_PriorityGroup_0 => 选择第0组
NVIC_PriorityGroup_1 => 选择第1组
NVIC_PriorityGroup_2 => 选择第2组
NVIC_PriorityGroup_3 => 选择第3组
NVIC_PriorityGroup_4 => 选择第4组

举个例子:将NVIC寄存器配置为0组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

2.NVIC初始化结构体的内容,配置以及初始化:

NVIC结构体的内容:
typedef struct

{

  uint8_t NVIC_IRQChannel;                 //使用的中断外设

  uint8_t NVIC_IRQChannelPreemptionPriority;  //抢断优先级

  uint8_t NVIC_IRQChannelSubPriority;  //响应优先级      

  FunctionalState NVIC_IRQChannelCmd;      

} NVIC_InitTypeDef;
NVIC结构体配置过程(以外部中断0为,优先级1组为例):
NVIC_InitTypeDef GPIOA_0Init;  //定义NVIC寄存器的初始化结构体名称

GPIOA_0Init.NVIC_IRQChannel = EXTI0_IRQn;  //设置为外部中断0

GPIOA_0Init.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级别(0~1)

GPIOA_0Init.NVIC_IRQChannelSubPriority = 1;  //响应优先级别(0~7)

GPIOA_0Init.NVIC_IRQChannelCmd = ENABLE;  //中断使能
初始化函数调用(根据刚才所写的NVIC结构体配置):
 NVIC_Init(&GPIOA_0Init);

NVIC使用过程总结:

1.中断优先级分组配置。

2.NVIC初始化结构体的配置。

3.初始化函数调用进行NVIC寄存器的初始化。

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择中断分组

NVIC_InitTypeDef GPIOA_0Init;  //定义NVIC寄存器的初始化结构体名称

GPIOA_0Init.NVIC_IRQChannel = EXTI0_IRQn;  //设置为外部中断0

GPIOA_0Init.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级别(0~1)

GPIOA_0Init.NVIC_IRQChannelSubPriority = 1;  //响应优先级别(0~7)

GPIOA_0Init.NVIC_IRQChannelCmd = ENABLE;  //中断使能

NVIC_Init(&GPIOA_0Init);//调用初始化函数对NVIC进行初始化

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于stm32f103c8t6的NVIC配置代码: ``` #include "stm32f10x.h" void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; // 设置中断优先级分组为2位抢占优先级和2位响应优先级 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 配置USART1中断 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 响应优先级为1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // 配置TIM2中断 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 响应优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } int main(void) { NVIC_Configuration(); while (1) { // 程序主逻辑 } } void USART1_IRQHandler(void) { // USART1中断服务程序 } void TIM2_IRQHandler(void) { // TIM2中断服务程序 } ``` 在上述代码中,`NVIC_Configuration`函数用于配置NVIC。首先调用`NVIC_PriorityGroupConfig`函数设置中断优先级分组为2位抢占优先级和2位响应优先级。然后配置USART1中断和TIM2中断,分别设置抢占优先级、响应优先级和使能中断。最后在`main`函数中调用`NVIC_Configuration`函数,使其生效。最后,定义了USART1和TIM2的中断服务程序,可根据实际需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值