大家好,又见面了,我是你们的朋友全栈君。
NVIC
NVIC:嵌套向量中断寄存器 Nested vectored interrupt controller (NVIC)。 NVIC:是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对 Cortex-M3 内核里面的 NVIC 进行裁剪,把不需要的部分去掉,所以说 STM32 的 NVIC 是 Cortex-M3 的 NVIC 的一个子集。
NVIC 结构体的定义
代码语言:javascript复制typedef struct{
__IO uint32_t ISER[8]; //中断使能寄存器
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; //中断清除寄存器
uint32_t RESERVED1[24];
__IO uint32_t ISPR[8]; //中断使能悬起寄存器
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; //中断清除悬起寄存器
uint32_t RESERVED3[24]
__IO uint32_t IABR[8]; //中断有效位寄存器
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; //中断优先级寄存器(8Bit wide)
uint32_t RESERVED5[644];
__IO uint32_t STIR; //软件触发中断寄存器
}NVIC_Type;
在配置到时候一般只是使用 ISER《使能中断》,ICER《失能中断》,IP《设置中断优先级》
优先级的分组
优先级的分组由内核外设SCB的应用程序中断及复位控制寄存器 AIRCR的PRIGROUP[10:8]位决定,F103分为5组,具体如下:主优先级=抢占优先级。
中断优先级分组库函数 NVIC_PriorityGroupConfig()
代码语言:javascript复制 /**
* 配置中断优先级分组:抢占优先级和子优先级
* 形参如下:
* @arg NVIC_PriorityGroup_0: 0bit for 抢占优先级
* 4 bits for 子优先级
* @arg NVIC_PriorityGroup_1: 1 bit for 抢占优先级
* 3 bits for 子优先级
* @arg NVIC_PriorityGroup_2: 2 bit for 抢占优先级
* 2 bits for 子优先级
* @arg NVIC_PriorityGroup_3: 3 bit for 抢占优先级
* 1 bits for 子优先级
* @arg NVIC_PriorityGroup_4: 4 bit for 抢占优先级
* 0 bits for 子优先级
* @注意 如果优先级分组为 0,则抢占优先级就不存在,优先级就全部由子优先级控制
*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
//设置优先级分组
SCB->AIRCR = AIRCR_VECTKEY | NVIC_PriorityGroup;
}
中断编程的三个要点
中断编程的3个要点
1.使能外设某个中断,具体由每个外设的相关中断使能位控制。例如串口有发送完成中断,接收完成中断 这两个中断都是由串口控制寄存器的相关中断使能位控制
2.初始化 NVIC_InitTypeDef结构体,配置中断优先分级组,设置抢占优先级和子优先级,使能中断请求 NVIC_InitTypeDef 结构体在固件库头文件misc.h中定义
代码语言:javascript复制typedef struct {
uint8_t NVIC_IRQChannel; //中断源
uint8_t NVIC_IRQChanelPreemptionPriority; //抢占优先级
uint8_t NVIC_IRQChannelSubPriority; //子优先级
FunctionalState NVIC_IRQChannelCmd; //中断使能或者失能
} NVIC_Type;
NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即 使写错了程序也不会报错,只会导致不响应中断。具体的成员配置可参考 stm32f10x.h 头文件里面的 IRQn_Type 结构体定义,这个结构体包含了所有的中断源。
IRQn_Type 结构体定义
代码语言:javascript复制typedef enum IRQn
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** STM32 specific Interrupt Numbers *********************************************************/
WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */
TAMPER_IRQn = 2, /*!< Tamper Interrupt */
RTC_IRQn = 3, /*!< RTC global Interrupt */
FLASH_IRQn = 4, /*!< FLASH global Interrupt */
RCC_IRQn = 5, /*!< RCC global Interrupt */
EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */
EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */
EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */
EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */
DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */
DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */
DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */
DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */
DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */
DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */
DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */
#ifdef STM32F10X_HD
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
USART1_IRQn = 37, /*!< USART1 global Interrupt */
USART2_IRQn = 38, /*!< USART2 global Interrupt */
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */
TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */
TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */
TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
ADC3_IRQn = 47, /*!< ADC3 global Interrupt */
FSMC_IRQn = 48, /*!< FSMC global Interrupt */
SDIO_IRQn = 49, /*!< SDIO global Interrupt */
TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
UART4_IRQn = 52, /*!< UART4 global Interrupt */
UART5_IRQn = 53, /*!< UART5 global Interrupt */
TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
#endif /* STM32F10X_HD */
}IRQn_Type;
NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来 确定,具体参考表格 上图优先级分组真值表 。 NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定,具体参考表格 上图优先级分组真值表 。 NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。操作的 是 NVIC_ISER 和 NVIC_ICER 这两个寄存器。
3、编写中断服务函数 在启动文件 startup_stm32f10x_hd.s 中我们预先为每个中断都写了一个中断服务函数, 只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,为了方便管理我们把中断服务函数统一写在 stm32f10x_it.c 这个库文件中。关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。
编程要点简介
代码语言:javascript复制1.使能外设某个中断,具体由每个外设的相关中断使能位控制
2.初始化 NVIC_InitTypeDef结构体,配置中断优先分级组,
设置抢占优先级和子优先级,使能中断请求
3、编写中断服务函数
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/140385.html原文链接:https://javaforall.cn