STM32之中断简介
一、F407在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中系统异常10个,外部中断82个。
除了个别异常的优先级被定死外,其他异常的优先级都是可以编程的。结构体: IRQn_Type包含全部异常声明。
二、嵌套向量中断控制器 NVIC,在STM32中NVIV 是 Cortex-M4的一个子集。结构体如下:
typedef struct { __IO uint32_t ISER[8]; /* 中断使能寄存器 */ uint32_t RESERVED0[24]; __IO uint32_t ICER[8]; /* 中断清除寄存器 */ uint32_t RSERVED1[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]; /* 中断优先级寄存器 */ uint32_t RESERVED5[644]; __O uint32_t STIR; /* 软件触发中断寄存器 */ } NVIC_Type;
在配置中断时,我们一般只使用 ISER , ICER ,IP。
2.2 NVIC库函数,我们一般很少使用,因为有更为简便的设置方法。
三、中断优先级定义
3.1 优先级的定义
在NVIC中有一个专门的寄存器:中断优先级寄存器NVIC_IPRx(x = 0..981) 用来专门配置外部中断的优先级。但是在绝大多数的M4芯片中都精简设计,实际的优先级用的更少,
在F407中只是用了高四位来定义优先级。用于表示优先级的这四位,有分为抢占优先级和子优先级,如果多个中断同时响应,抢占优先级高的就会抢占优先执行权,如果抢占优先级相同,那就会比较子优先级。
如果抢占优先级和子优先级都相同,就比较他们的硬件中断编号,编号越小,优先级越高。
3.2 中断优先级分组
设置优先级分组可调用库函数 : void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) 来实现。在F407优先级总共分了5组:
四、中断编程
4.1 使能外设某个中断,这个具体由每个外设的相关中断使能位控制,比如串口有发送完成中断,接受完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。
4.2 初始化NVIC_InitTypeDef 结构体,配置中断优先级分组,设置抢占优先级和子优先级,使能中断请求。
typedef struct { uint8_t NVIC_IRQChannel; /* 中断源 */ uint8_t NVIC_IRQChannelPreemptionPriority; /* 中断抢占优先级 */ uint8_t NVIC_IRQChannelSubPriority; /* 中断子优先级 */ FunctionalState NVIC_IRQChannelCmd; /* 中断使能或者失能 */ } NVIC_InitTypeDef;
1) 结构体 IRQn_Type 定义了所有中断源
2) 抢占优先级和子优先级 ,具体的值要根据优先级分组来确定
3)中断使能或失能 是操作的NVIC_ISER 和NVIC_ICER这两个寄存器
4.3 编写中断服务函数
在启动文件 startup_stm32f40xx.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是空的,为的只是初始化向量表。实际的中断服务函数都需要我们重新编写,中断服务函数我们统一写在 stm32f4xx_it.c 这个库文件中。
关于中断服务函数的函数名必须跟启动文件里面预设的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,就会直接跳转到启动文件里预设的空函数,并在里面无线循环,实现不了中断。