发布时间:2022-09-19 20:30
目录
前言
一、基础知识
1.NVIC基础知识
2.抢占优先级&响应优先级
3.中断向量表
4.中断优先级分组
二、配置中断相关寄存器
三、库函数配置
1.中断参数初始化函数
2.中断优先级设置步骤
总结
STM32单片机的一个强大之处在于用于庞大的中断体系,掌握STM32对中断优先级的定义是学好STM32中断的前提。本次我们讲解STM32关于中断优先级NVIC的定义。我们以基本原理、寄存器介绍和库函数配置这一 顺序来讲解。
(图片来自STM32中文参考手册)
看到中断向量表后,想必大家都会心生疑问:STM32有几十个中断,怎么管理呢?
这就要讲解中断管理方法了,首先对STM32的中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。
分组配置是在寄存器SCB->AIRCR中配置:
以下是位于CM3内核中的与NVIC分组相关的寄存器:
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */
} NVIC_Type;
中断优先级控制的寄存器组:IP[240]
全称是:Interrupt Priority Registers。240个8位寄存器,每个中断使用一个寄存器来确定优先级。STM32F10x系列一共60个可屏蔽中断,使用IP[59]~IP[0]。每个IP寄存器的高4位用来设置抢占和响应优先级(根据分组),低4位没有用到。
中断失能寄存器组:ICER[8]
作用:用来失能中断。32位寄存器,每个位控制一个中断的失能。STM32F10x只有60个可屏蔽中断,所以只使用了其中的ICER[0]和ICER[1]。ICER[0]的bit0~bit31分别对应中断0~31。ICER[1]的bit0~27对应中断32~59;配置方法跟ISER一样。
中断挂起控制寄存器组:ISPR[8]
作用:用来挂起中断
中断解挂控制寄存器组:ICPR[8]
作用:用来解挂中断
中断激活标志位寄存器组:IABR[8]
作用:只读,通过它可以知道当前在执行的中断是哪一个。如果对应位为1,说明该中断正在执行
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
typedef struct
{
uint8_t NVIC_IRQChannel; //设置中断通道
uint8_t NVIC_IRQChannelPreemptionPriority;//设置响应优先级
uint8_t NVIC_IRQChannelSubPriority; //设置抢占优先级
FunctionalState NVIC_IRQChannelCmd; //使能/使能
} NVIC_InitTypeDef;
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); //根据上面指定的参数初始化NVIC寄存器
①系统运行后先设置中断优先级分组,调用函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
整个系统执行过程中,只设置一次中断分组。
②针对每个中断,设置对应的抢占优先级和响应优先级:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
③ 如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。
要想学习STM32中断,要先掌握STM32对优先级的分组。本讲以原理、相关寄存器介绍和库函数配置的顺序对STM32的NVIC中断优先级进行讲解,希望读者反复研究,为以后的学习打好基础。