CKS32F4xx系列产品NVIC中断优先级管理单元讲解

mcu微课堂
cks32f4xx系列产品nvic中断优先级管理
第三期 2023.2.2
本课将为大家讲解cks32f4xx系列产品的中断优先级管理单元nvic。cm4内核共支持256个中断,其中包含了16个内核中断和240个外部中断,具有256级可编程中断设置。但cks32f4xx系列只使用了cm4内核的一部分,共有98个中断,包括16个带有fpu核的cm4中断和82个可屏蔽中断,而我们常用的就是这82个可屏蔽中断。
nvic寄存器简介
mdk为nvic相关寄存器其定义了如下的结构体:
typedef struct { __io uint32_t iser[8]; /*!< interrupt set enable register */ uint32_t reserved0[24]; __io uint32_t icer[8]; /*!< interrupt clear enable register */ uint32_t rserved1[24]; __io uint32_t ispr[8]; /*!< interrupt set pending register */ uint32_t reserved2[24]; __io uint32_t icpr[8]; /*!< interrupt clear pending register */ uint32_t reserved3[24]; __io uint32_t iabr[8]; /*!< interrupt active bit register */ uint32_t reserved4[56]; __io uint8_t ip[240]; /*!< interrupt priority register, 8bit wide */ uint32_t reserved5[644]; __o uint32_t stir; /*!aircr 中的中断分组设置来决定。
nvic中断分组
    这里简单介绍一下 cks32f4 的中断分组:cks32f4将中断分为5个组,组0~4。该分组的设置是由 scb->aircr 寄存器的 bit10~8 来定义的。具体的分配关系如下:
通过这个表,我们就可以清楚的看到组0~4对应的配置关系,例如组设置为3,那么此时所有的82个中断,每个中断的中断优先寄存器的高四位中的最高3位是抢占优先级,低1位是响应优先级。每个中断,你可以设置抢占优先级为0~7,响应优先级为1或0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
    这里需要注意两点:
    第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
    第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
    结合实例说明一下:假定设置中断优先级组为2,然后设置中断3(rtc_wkup中断)的抢占优先级为2,响应优先级为1。中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。那么这3个中断的优先级顺序为:中断7>中断3>中断6。其中中断3和中断7都可以打断中断6的中断。而中断7和中断3却不可以相互打断!
软件实现
通过以上介绍,我们熟悉了cks32f4中断设置的大致过程。接下来我们介绍如何使用库函数实现以上中断分组设置以及中断优先级管理,使得我们以后的中断设置简单化。nvic中断管理函数主要在misc.c文件里面。
首先要讲解的是中断优先级分组函数nvic_prioritygroupconfig,其函数申明如下:
void nvic_prioritygroupconfig(uint32_t nvic_prioritygroup);  
    这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分组确定就最好不要更改。这个函数我们可以找到其实现:
void nvic_prioritygroupconfig(uint32_t nvic_prioritygroup) { assert_param(is_nvic_priority_group(nvic_prioritygroup)); scb->aircr = aircr_vectkey_mask | nvic_prioritygroup; }  
    从函数体可以看出,这个函数唯一目的就是通过设置scb->aircr寄存器来设置中断优先级分组,查看其定义为:
#define is_nvic_priority_group(group) (((group) == nvic_prioritygroup_0) || ((group) == nvic_prioritygroup_1) || ((group) == nvic_prioritygroup_2) || ((group) == nvic_prioritygroup_3) || ((group) == nvic_prioritygroup_4))  
    可以看到这个定义对应上表中的分组范围0-4。如果我们需要设置系统的中断优先级分组值为2,那么方法是:nvic_prioritygroupconfig(nvic_prioritygroup_2);这样就确定了一共为“2位抢占优先级,2位响应优先级”。设置好了系统中断分组,接下来设置中断的抢占优先级和响应优先级,这里需要用到一个重要的函数为中断初始化函数nvic_init,其函数声明为:voidnvic_init(nvic_inittypedef*nvic_initstruct),其中nvic_inittypedef是一个结构体,我们可以看看结构体的成员变量:
typedef struct { uint8_t nvic_irqchannel; uint8_t nvic_irqchannelpreemptionpriority; uint8_t nvic_irqchannelsubpriority; functionalstate nvic_irqchannelcmd; } nvic_inittypedef;  
    nvic_inittypedef结构体中间有四个成员变量,这四个成员变量的作用是:
    nvic_irqchannel:
    定义初始化的是哪个中断,这个我们可以在cks32f4xx.h中定义的枚举类型irqn的成员变量中可以找到每个中断对应的名字。例如串口1对应usart1_irqn。
    nvic_irqchannelpreemptionpriority:
    定义这个中断的抢占优先级别;
nvic_irqchannelsubpriority:
    定义这个中断的响应优先级别。
    nvic_irqchannelcmd:
    该中断通道是否使能。比如我们要使能串口1的中断,同时设置抢占优先级为1,响应优先级位2,初始化的方法是:
nvic_inittypedef nvic_initstructure;nvic_initstructure.nvic_irqchannel = usart1_irqn;//>>串口 1 中断 nvic_initstructure.nvic_irqchannelpreemptionpriority=1 ;//>> 抢占优先级为 1 nvic_initstructure.nvic_irqchannelsubpriority = 2;//>> 响应优先级位 2 nvic_initstructure.nvic_irqchannelcmd = enable; //>>irq 通道使能 nvic_init(&nvic_initstructure);  
    这里我们讲解了中断的分组的概念以及设定优先级值的方法,至于每种优先级还有一些关于清除中断,查看中断状态,这在后面课堂中我们讲解每个中断的时候会详细讲解到。
课程总结
    中断优先级设置的步骤:
    1.系统初始化的时候设置中断分组:
    确定组号,也就是确定抢占优先级和响应优先级的分配位数。调用函数为nvic_prioritygroupconfig();
    2.设置所用到的中断的中断优先级别:
    对每个中断调用函数nvic_init();确定具体的抢占优先级和响应优先级,并使能通道。


交流电源线上的常见故障与保护解决方案
未来几年可穿戴设备影响最大的5大领域
详解光模块和光纤连接器应用指南
西门子S7-200PLC编程通信口参数设置
小米mix2确认支持面部识别功能,这年代手机也要看颜值了啊!
CKS32F4xx系列产品NVIC中断优先级管理单元讲解
HTC VR重拳出击 下周将发布首款VR游戏
高阻抗电弧炉的设计特点和应用
二季度全球智能手机增长放慢至15% 创6年来最低水平
用于Pt湿法蚀刻的铂薄膜图案化方案
智能电表,让生活更智能
以单片机为控制中心的智能微波信号源发生器设计
基于人工智能技术的地震监测系统将是未来预报地震的发展新方向
任天堂Switch Pro硬件配置参数
中芯国际拟转让所持控股子公司中芯长电半导体的全部股本权益
利用蜂鸣器和单片机演奏简单的音乐电路设计
NVIDIA 校招 | 基础设施部门正在热招!
《仿真分析小技巧8》---巧妙利用.doping文件快速修改材料掺杂参数
装备制造企业数字化平台总体架构及集成实现
MTK8766核心板与4g开发板的规格
s