- 前言
- 一、NVIC中断机制
- 二、NVIC配置函数
- 1.HAL_NVIC_SetPriorityGrouping
- 2.HAL_NVIC_SetPriority
- 3.HAL_NVIC_EnableIRQ
- 4.HAL_NVIC_DisableIRQ
- 三、NVIC配置步骤
- 总结
stm32G431总共有111个中断源,所以有时难免有两个或者两个以上的中断一起来临,或者正在处理一个中断服务函数时突然又有一个中断来临,以上种种情况微控制器要怎样运行呢?
微控制器都有一个处理中断的机制,stm32系列芯片用到的机制是:NVIC
NVIC: 嵌套向量中断控制器(Nested Vectored Interrupt Controller)
STM32中NVIC,它是属于CM4内核的器件。NVIC 控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设
但是各个芯片厂商在设计芯片的时候会对CM4内核里面的NVIC进行裁剪,把不需要的部分去掉,所以说STM32的NVIC是CM4的NVIC的一个子集
CM4内核支持256个中断,其中包含了16个系统异常和240个外部中断,并且具有256级的可编程中断设置
但 STM32并没有使用CM4内核的全部东西,而是只用了它的一部分。 stm32G431芯片有111个中断,包括9个内核中断和102个可屏蔽中断,具有16级可编程的中断优先级,常用的就是这102个可屏蔽中断
NVIC寄存器定义在core_cm4.h文件中 一般只用ISER,ICER和IP这三个寄存器
**ISER:**中断使能寄存器组,CM4 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断,对于STM32G4有102个可屏蔽中断,用到ISER[0~3]即可
使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、 IO 口映射等设置才算是一个完整的中断设置
**ICER:**中断除能寄存器组,与 ISER 的作用恰好相反,是用来清除某个中断的使能的,要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄存器都是写 1 有效的,写 0 是无效的
**IP:**中断优先级控制的寄存器组,IP 寄存器组由 240 个 8bit的寄存器组成,每个可屏蔽中断占用 8bit
每个中断的优先级由一个8bit来设定,分为高低两个位段。高位段表示抢占优先级,低位段表示响应(子)优先级。 CM4允许最少使用位数为3位,即至少要支持8级优先级
但是,每个可屏蔽中断占用的 8bit 并没有全部使用,而是只用了高 4 位
而这两个优先级各占几个位又要根据 SCB->AIRCR中的中断分组设置来决定
如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断
注: (1)抢占优先级的级别高于响应优先级,而数值越小所代表的优先级就越高
(2)抢占优先级是针对中断不同时刻发生的情况,响应优先级是针对中断同时发生的情况
二、NVIC配置函数 1.HAL_NVIC_SetPriorityGrouping函数声明(在cortex.h中)
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
NVIC_SetPriorityGrouping(PriorityGroup);
}
作用: 设置中断优先级分组
形参选择: NVIC_PRIORITYGROUP_0: 0位抢占式优先级,4位响应优先级; NVIC_PRIORITYGROUP_1: 1位抢占式优先级,3位响应优先级; NVIC_PRIORITYGROUP_2:2位抢占式优先级,2位响应优先级; NVIC_PRIORITYGROUP_3: 3位抢占式优先级,1位响应优先级; NVIC_PRIORITYGROUP_4:4位抢占式优先级,0位响应优先级
一般设置为2,这个函数在系统中只需要被调用一次,一旦分组确定就最好不要更改,否则容易造成程序分组混乱
通过调用函数 NVIC_SetPriorityGrouping 来进行中断优先级分组设置
__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
uint32_t reg_value;
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
reg_value = SCB->AIRCR; /* read old register configuration */
reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
reg_value = (reg_value |
((uint32_t)0x5FAUL IP[((uint32_t)IRQn)] = (uint8_t)((priority
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?