NVIC

K60 使用CM4内核的NVIC中断优先级洗系统。每个中断都可以配置自己的优先级

但是NVIC本身又比较复杂。首先要将优先级分组(整个芯片的优先级系统分组),可以分成4组

#define NVIC_PriorityGroup_0         ((uint32_t)0x7) /*!< 0 bits for pre-emption priority   4 bits for subpriority */


#define NVIC_PriorityGroup_1         ((uint32_t)0x6) /*!< 1 bits for pre-emption priority   3 bits for subpriority */

#define NVIC_PriorityGroup_2         ((uint32_t)0x5) /*!< 2 bits for pre-emption priority   2 bits for subpriority */

#define NVIC_PriorityGroup_3         ((uint32_t)0x4) /*!< 3 bits for pre-emption priority   1 bits for subpriority */

#define NVIC_PriorityGroup_4         ((uint32_t)0x3) /*!< 4 bits for pre-emption priority   0 bits for subpriority */

首先解释2个名词:
  • pre-emption priority  将占优先级: 比子优先级高端。。 也就是说,抢占优先级高的(0比1高,越小越高) 可以打断正在执行的低抢占优先级中断。


  • subpriority   子优先级。   只有2个中断具有相同的抢占优先级的情况下,才有意义。这种情况下,同时2个中断发生时,子优先级高的先发生。

说白了就是,我抢占优先级高的,我就是霸权~  比我抢占优先级低的,你们子优先级是多少也没用。我一律最优先。但是和我同属一个抢占优先级的中断我就搞不定了,那就看我们谁子优先级高谁先发生吧。。。

例子: 

    printf("NVIC Test\r\n");
    uint32_t PreemptPriority, SubPriority;
    NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);
    printf("SystemPrioirityGroup:%d\r\n", NVIC_GetPriorityGrouping());
    
    NVIC_SetPriority(PORTA_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 1));

    
    NVIC_SetPriority(PORTB_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 2));


首先将系统NVIC分组设置为2. 即有2位抢占,2位子优先级。这“2位”的意思就是 2个二进制数,可以代表 0,1,2,3 对吧? 所以抢占可以配成0,1,2,3四个等级,子优先也可以配成0,1,2,3  四个等级。


NVIC_SetPriority(PORTA_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 1));


这句啥意思呢, NVIC_SetPriority 和 NVIC_EncodePriority 都是ARM系统库函数,EncodePrioirity 需要3个参数,原型如下


uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)

<span style="color: rgb(68, 68, 68); font-family: Tahoma, 'Microsoft Yahei', Simsun; font-size: 14px; line-height: 12px; background-color: rgb(245, 245, 245);">第一个参数,中断分组,直接用</span><span style="word-wrap: break-word; color: rgb(68, 68, 68); font-family: Tahoma, 'Microsoft Yahei', Simsun; font-size: 14px; line-height: 12px; background-color: rgb(247, 247, 247);">NVIC_GetPriorityGrouping() 获得即可,其实就是2.</span><br style="word-wrap: break-word; color: rgb(68, 68, 68); font-family: Tahoma, 'Microsoft Yahei', Simsun; font-size: 14px; line-height: 12px; background-color: rgb(245, 245, 245);" /><span style="word-wrap: break-word; color: rgb(68, 68, 68); font-family: Tahoma, 'Microsoft Yahei', Simsun; font-size: 14px; line-height: 12px; background-color: rgb(247, 247, 247);">PreemptPriority,</span><span style="word-wrap: break-word; color: rgb(68, 68, 68); font-family: Tahoma, 'Microsoft Yahei', Simsun; font-size: 14px; line-height: 12px; background-color: rgb(247, 247, 247);">SubPriority 我就不用说了吧, 他们每个的取值范围都是0-3  这里 </span><span style="word-wrap: break-word; color: rgb(68, 68, 68); font-family: Tahoma, 'Microsoft Yahei', Simsun; font-size: 14px; line-height: 12px; background-color: rgb(247, 247, 247);">PreemptPriority = 2;   </span><span style="word-wrap: break-word; color: rgb(68, 68, 68); font-family: Tahoma, 'Microsoft Yahei', Simsun; font-size: 14px; line-height: 12px; background-color: rgb(247, 247, 247);">SubPriority = 1;</span>




NVIC即嵌套向量中断控制器,是用于处理中断的重要组件。以下是关于NVIC的详细介绍和使用说明: ### NVIC介绍 NVIC具备中断协作模型,其内部结构与中断向量表相关联。它的功能主要是对中断进行管理和控制,确保系统能够合理响应各种中断事件 [^1]。 ### NVIC的函数接口 NVIC的函数接口在MISC.H文件中,相关函数如下: - `void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)`:用于配置优先级分组。 - `void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)`:用于初始化NVIC,需传入NVIC_InitTypeDef结构体指针 [^1]。 此外,CMSIS还提供了一些NVIC相关函数: - `NVIC_EnableIRQ(IRQn)`:开启中断。 - `NVIC_DisableIRQ(IRQn)`:关闭中断。 - `NVIC_SetPriority(IRQn, prio)`:设置优先级 [^2]。 ### NVIC_InitTypeDef结构体 该结构体用于配置NVIC的相关参数,其成员变量如下: ```c typedef struct { uint8_t NVIC_IRQChannel; // 定义初始化的是哪个中断,中断名 uint8_t NVIC_IRQChannelPreemptionPriority; // 定义这个中断的抢占优先级别 uint8_t NVIC_IRQChannelSubPriority; // 定义这个中断的子优先级别 FunctionalState NVIC_IRQChannelCmd; // 中断通道是否使能 } NVIC_InitTypeDef; ``` ### NVIC的使用步骤 1. 使用`void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)`函数配置优先级分组。 2. 在`NVIC_InitTypeDef`结构体中配置通道、抢占优先级、子优先级和是否使能。 3. 使用`void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)`函数进行NVIC的初始化 [^3]。 ### 编程示例 以下是一个简单的NVIC初始化示例代码: ```c #include "misc.h" void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; // 配置优先级分组 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 配置NVIC_InitTypeDef结构体 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 假设使用USART1中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道 // 初始化NVIC NVIC_Init(&NVIC_InitStructure); } ``` ### 中断编程的完整流程 中断函数在启动文件`starup_stm32f10x_md.s`中。编程时一般有3个步骤,同时在实际应用中,如果开启了串口等外设的中断,在完成外设的相关初始化后,需要初始化NVIC设置中断优先级别,最后编写中断服务函数 [^1][^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值