STM32学习--异常与中断

1.概述

  Cortex-M3 有16个异常(实际只用15个,也叫内核中断),并提供240个外部中断(针对内核来讲),有3个优先级最高的不可屏蔽异常,即1~3号异常。
STM32学习--异常与中断_第1张图片
  F1中最多持68个可屏蔽中断(即内核中在外部中断),对应68个中断源。如USART1对应37#中断,但有多种条个可以触发该中断,如读完成、写完成、溢出等等都可以触发同一个中断源,进入中断函数后需根据状态位再判断具体中断原因。
  STM32中断设置中,我们常用6组寄存器。
  分别为:
  ISER[8]:中断使能寄存器组,8个32位的寄存器对应STM32中支持的256个中断源,虽然F1没有使用这么多,但也把地址空间留出来以备后续器件扩展,以下寄存器组相同。你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,后续还需中断分组、屏蔽、优先组设置、 IO 口映射等设置才算是一个完整的中断设置)。
  ICER[8]:中断除能寄存器组。该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄
存器都是写 1 有效的,写 0 是无效的。这是因为通过这种方式,使能/除能中断时只需把“当事位”写成1,其它的位可以全部为零。再也不用像以前那样,害怕有些位被写入 0 而破坏其对应的中断设置(写 0 没有效果),从而实现每个中断都可以自顾地设置,而互不侵犯——只需单一的写指令,不再需要读‐改‐写。
  ISPR[8]:中断挂起控制寄存器组,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写 0 无效。
  ICPR[8]:中断解挂控制寄存器组。其作用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断接挂。写 0 无效。
  IABR[8]:中断激活标志位寄存器组。如果为 1,则表示该位所对应的中断正在被执行。它是只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。
  IP[240]:中断优先级控制的寄存器组。IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit(只用到高4位), 同样总共可以表示 240 个可屏蔽中断F1中只用到68个。

2.优先级设置

  Cortex-M3 的中断管理将优先级分为抢占优先级和子优先级。
抢占优先级高的中断可以打断抢占优先级低的中断,子优先级不具备这个能力,但若抢占优先级相同的两个中断同时挂起时,会先响应子优先级的中断。

  Cortex-M3在实现这两种优先级时,提供一种分组机制来分配抢占优先级和子优先级的数量。在STM32F1中,通过SCB->AIRCR 中的中断分组设置来决定。
  STM32 将中断分为 5 个组,组 0~4。该分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的。具体的分配关系如下表。
STM32学习--异常与中断_第2张图片
  STM32使用4位分配优先组,表示最大支持16级中断嵌套。
  设置中断优先级步骤:
  1. 设置中断分组在需操作SCB->AIRCR寄存器,按上表进行分组。在操作SCB->AIRCR时应写入钥匙在SCB->AIRCR高4位写入钥匙,0X05FA。也可直接使用库函数进行操作。
  2. 中断分组完成后,可操作ISER和IP寄存器组,使能中断源,分配优先级即可。

3.中断向量

  在库文件stm32f10x.s中可看到中断向量表。
AREA RESET, DATA, READONLY ; 定义只读数据段,实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000)

              EXPORT  __Vectors
IMPORT  OS_CPU_SysTickHandler
       IMPORT  OS_CPU_PendSVHandler
__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
           ……………………………………………………………

  表中顺序与中断号一一对应。
  器件上电后根据boot引脚来决定PC位置,如果boot设置为flash启动,则启动后PC跳到0x08000000。此时CPU会先取2个地址,第一个是栈顶地址,第二个是复位异常地址,跳到reset_handler。这些地址与keil里面设置的target->flash起始地址相关,由编译器确定,其中参数不能随意改动。

  默认情况下,从Flash启动,中断向量表从Flash的起始地址(0x08000000)开始存放。同时映射到0x00000000处。向量表偏移寄存器(VTOR)的值为0x00000000(实际映射到0x08000000)。
  若从SRAM启动,中断向量表还是存放在Flash中(Flash才能固化存储,SRAM只能加电才有效),只不过拷贝到SRAM的首地址0x20000000处。此时向量表偏移寄存器(VTOR)的值也是0x00000000(实际映射到0x20000000)。而启动过程结束后,这个特殊的映射不复存在了(据参考手册推测的),所以,需要修改向量表偏移寄存器(VTOR)的值为0x20000000以后的值(其中TBLOFF位域要是0x200的倍数,这个是字对齐的要求(见《cortex-m3编程手册》),由于STM32的中断向量一共有68+16=84个,应该把这个数增加到下一个2的整数倍即128,然后换算成地址范围128*4=512,就得到了0x200),以便处理中断。因此,无论用哪种模式启动,复位时栈顶指针总能在0x00000000(或0x08000000)处找到,而复位向量总能在0x00000004(或0x08000004)处找到。

你可能感兴趣的:(STM32,学习)