STM32-异常与中断

在使用单片机的时候我们常用到的中断,但是但是我们常说的中断都是由(内核的)外部事件引起的、正常的紧急事件。而异常与我们所说的中断相似,但也有不同之处。

异常(内核中断)和外部中断

异常是CPU内部产生的中断,即在CPU执行特定指令的时候出现的非法情况,如除数为0等等,所以不可能在执行指令期间发生异常,只会在执行一条指令后有可能发生,所以也称同步中断。而中断则是一种异步的,它与特定的进程是无关的,又称为异步中断

CM3 内核支持 256 个中断,其中包含了 16 个内核中断(主要用于系统异常)和 240 个外部中断,并且具有 3 个固定的高优先级和256级(8位)的可编程中断设置。因为芯片设计者可以修改 CM3 的硬件描述源代码,所以做成芯片后,支持的中断源数目常常不到 240 个,并且优先级的位数也由芯片厂商最终决定,实际上支持的优先级数会少于256级(8位),如 8 级(3位),16 级(4位),32(5位) 级等。需要注意的是CM3允许的最少使用位数为3个位,即至少支持8级优先级。

STM32 有 84 个中断,包括 16 个内核中断和 68 个外部中断,具有 16 级(4位)可编程的中断优先级。而我们常用的就是这 68 个可屏蔽中断,但是 STM32 的 68 个可屏蔽中断,在 STM32F103 系列上面,又只有 60 个(在 107 系列才有 68 个)。

内核中断

内核中断如下图所示

需要了解的是NMI,不可屏蔽中断。我们知道,对于可屏蔽中断,除了受本身的屏蔽位的控制外,还都要受一个总的控制,即CPU标志寄存器中的中断允许标志位IF(Interrupt Flag)的控制,IF位为1,可以得到CPU的响应,否则,得不到响应。对于不可屏蔽中断,CPU收到有效的NMI中断中断信号必须进行响应!不需要发出中断请求!不可屏蔽中断通常用于故障处理(如系统掉电等)。

外部中断

CM3内核的外部中断如下图所示,他们被芯片设计厂商定义为各种片上外设的中断请求接口。

中断向量表

当发生了异常并且要响应它时,CM3 需要定位其处理例程的入口地址。这些入口地址存储在所谓的“(异常)向量表”中。我们在启动文件中可以看到中断向量表,这里详细列举了该启动文件支持的所有中断,下面这个是STM32F103的启动文件。

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                DCD     FLASH_IRQHandler           ; Flash
                DCD     RCC_IRQHandler             ; RCC
                DCD     EXTI0_IRQHandler           ; EXTI Line 0
                DCD     EXTI1_IRQHandler           ; EXTI Line 1
                DCD     EXTI2_IRQHandler           ; EXTI Line 2
                DCD     EXTI3_IRQHandler           ; EXTI Line 3
                DCD     EXTI4_IRQHandler           ; EXTI Line 4
                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                DCD     ADC1_2_IRQHandler          ; ADC1_2
                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler            ; TIM2
                DCD     TIM3_IRQHandler            ; TIM3
                DCD     TIM4_IRQHandler            ; TIM4
                DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                DCD     SPI1_IRQHandler            ; SPI1
                DCD     SPI2_IRQHandler            ; SPI2
                DCD     USART1_IRQHandler          ; USART1
                DCD     USART2_IRQHandler          ; USART2
                DCD     USART3_IRQHandler          ; USART3
                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
__Vectors_End

优先级

内核中断编号1-3为3 个系统异常:复位,NMI 以及硬 fault,它们是不可编程的有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常(优先级的数值越小,则优先级越高),所有其它异常的优先级则都是可编程的(优先级不能使负数)。

CM3支持中断嵌套,NMI和外部中断优先级由NVIC中断管理器进行管理。我们知道STM32支持16级(4位)可编程优先级,与51单片机不同,这里的优先级包括了抢占优先级和响应优先级(或称亚优先级)。即抢占优先级和响应优先级共占4位,共同构成了16级(4位)优先级。根据抢占优先级和响应优先级分别占多少位,STM32 将中断分为 5 个组,组 0~4,对应关系如下:

我们可以按照需求设置为2^{m}个抢占优先级,每个抢占优先级下又有2^{4-m}个响应优先级(0≤m≤4),抢占优先级的优先级比响应优先级的优先级高。抢占优先级决定了抢占行为:当系统正在响应某异常 L 时,如果来了抢占优先级更高的异常 H,则 H 可以抢占 L。响应优先级则处理“内务”:当抢占优先级相同的异常有不止一个悬起时(有的文章称“同时发生”,其实不然,因为不可能存在绝对的“同时”),就优先处理响应优先级最高的异常。

什么是悬起?

如果一个发生的异常不能被即刻响应,就称它被“悬起”(pending)。不过,少数 fault异常是不允许被悬起的。一个异常被悬起的原因,可能是系统当前正在执行一个更高优先级异常的服务例程,或者因相关掩蔽位的设置导致该异常被除能。对于每个异常源,在被悬起的情况下,都会有一个对应的“悬起状态寄存器”保存其异常请求,直到该异常能够执行为止,这与传统的 ARM 是完全不同的。在以前,是由产生中断的设备保持住请求信号。现在NVIC 的悬起状态寄存器的出现解决了这个问题,即使后来设备已经释放了请求信号,曾经的中断请求也不会错失。

猜你喜欢

转载自blog.csdn.net/wei348144881/article/details/108999111