欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器

程序员文章站 2022-04-01 21:49:59
...

简介

STM32拥有一个强大的中断系统,几乎所有外设都能产生中断,对于F103系列的单片机,ARM公司在Cortex‐M3 的内核水平上搭载了一个异常响应系统(异常就是中断), 支持为数众多的系统异常和外部中断。对于每一种中断都有一个编号,其中,编号为 1-15 的对应系统异常大于等于 16 的则全是外部中断

Cortex-M3系统异常清单:
STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器
Cortex-M3外部中断清单:
STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器
Cortex-M3提供了两百多种异常类型,但在STM32中并没有这么多,STM32的中断系统是被阉割裁剪过的,只有六十多个,但相比于51单片机也已经是十分强大了

STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器

NVIC嵌套向量中断控制器

NVIC嵌套向量中断控制器,控制着整个芯片中断相关的功能,相当于中断系统的大脑,是内核里面的一个外设,但由于ST官方在设计芯片的时候对Cortex-M3的中断系统进行了裁剪,把不需要用到的部分给去掉。

NVIC的寄存器

寄存器的结构体定义位于core_cm3.h中

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;   

其中
ISER是中断使能寄存器ICER是中断清除寄存器IP是八位8bit中断优先级寄存器,我们在配置中断的时候一般只会用到这三个寄存器

中断优先级

前面的寄存器中有出现IP八位中断优先级寄存器,但在STM32中实际只用了4个bit用于优先级的设置STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器
用于表达的优先级还分为

  • 抢占优先级(pre-emotion priority)
  • 子优先级(subpriority)
    在比较优先级的时候会先比较抢占优先级之后再比较子优先级,抢占优先级相同时比较子优先级,子优先级和抢占优先级都相同时比较中断编号

优先级分组

由于优先级中有抢占优先级和子优先级之分,因此需要对这四个位进行分组,分出对应的bit用于两种优先级的表达
STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器
控制优先级分组的是内核外设SCB中的AIRCR寄存器,有五种分配选择

中断的初始化编程

中断初始化函数为:void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
NVIC_InitTypeDef初始化结构体:

typedef struct {
	uint8_t NVIC_IRQChannel; // 中断源

	uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占优先级

	uint8_t NVIC_IRQChannelSubPriority; // 子优先级

	FunctionalState NVIC_IRQChannelCmd; // 中断使能或者失能
	
} NVIC_InitTypeDef;

这里边就已经说明了中断编程的一些要点,由于STM32几乎每一个外设都能产生中断,因此使用哪一个外设的中断的时候

  1. 需要把对应外设的负责中断的寄存器给使能

  2. 配置中断源NVIC_IRQChannel
    中断源可以在stm32f10x.h头文件中找到
    STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器

  3. 配置抢占优先级与子优先级
    NVIC_IRQChannelPreemptionPriority:抢占优先级
    NVIC_IRQChannelSubPriority:子优先级
    在这之前还需要设置优先级分组
    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);函数配置,具体使用方法可以去msic.h和msic.c查询

  4. 使能中断或失能中断
    NVIC_IRQChannelCmd:中断使能( ENABLE)或者失能( DISABLE)

  5. 编写中断服务函数
    需要注意的是,STM32的中断服务函数名字不能随意取,51中用编号区分,STM32中就没有,需要严格按照头文件中所声明的名称编写,如果函数名称与头文件定义的不一样,在执行中断的时候会跳转到启动文件中的空函数,从而进入死循环
    STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器

相关标签: STM32笔记