STM32F10x中断
STM32F10x中断非常强大,每一个外设都可以产生中断,下面介绍一下原理
中断的类型
STM32F103的芯片是由Cortex-M3内核和ST的外设组成,因此,中断和两者的密切联系。所以,中断的类型分为:
系统异常:体现在内核水平。在中文参考手册里异常的种类如下:
外设中断:体现在外设水平。在中文参考手册里外设中断的种类如下:
NVIC嵌套向量中断控制器
上文提到STM32F10x的中断类型很多,为了方便管理这些中断,设置了NVIC寄存器管理。查看NVIC结构的定义请在core_m3.h工程文件中寻找。如下:
/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC
memory mapped structure for Nested Vectored Interrupt Controller (NVIC)
@{
*/
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;
/*@}*/ /* end of group CMSIS_CM3_NVIC */
这个是Cortex-M3内核里的NVIC结构体,内核定义的功能非常多,但是ST公司会对这些功能进行裁剪,剪裁后的NVIC在misc.h的文件中(至于为什么会单独形成文件请看我的文章第一节:STM32F103ZE—寄存器编程(仿51编程)-优快云博客 这里面介绍了Cortex-M3内核和ST的关系):
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
中断优先级
中断优先级是用来决定,当同时有多个中断同时产生时,系统判断哪一个中断先处理,哪一个中断后处理的问题。
在core_m3.h工程文件中NVIC结构体中的IP[]设置,同时也是NVIC在misc.h的文件中结构体的NVIC_IRQChannelPreemptionPriority和NVIC_IRQChannelSubPriority。这些都只是在不同文件的结构体定义不同,但是其操作本质的寄存器是NVIC->IPRx。因为NVIC是Cortex-M3里面的外设功能,所以NVIC的寄存器地址因该在Cortex-M3编程手册中寻找。注:NVIV是Cortex-M3内核的外设是ARM公司设计内核的外设而不是ST厂商所谓的外设,这是本质不同的。
NVIC->IPRx功能是优先级设定有8bit,ST裁剪后只使用高4位。SCB->AIRCR是优先级分组(Cortex-M3编程手册中寻找),这里并不是突兀的介绍而是Cortex-M3编程手册的说明。这两个寄存器都是对高4位的使用。高4位的功能如下:
STM32F10x中对中断优先级的定义有:主优先级和子优先级。当中断同时到达,先比较主优先级,在比较子优先级。优先级高的先执行。假如主优先级,子优先级都相同的话,系统会根据中断向量表的排序来决定谁先执行。
高4位就可以实现主,子分组的设置。
主优先级为0,主优先级不占任何位。子优先级可以使用全部的高4位,所以子优先级有0-15
主优先级为0-1,主优先级占1位。子优先级可以使用后3位,所以子优先级有0-7
主优先级为0-3,主优先级占2位。子优先级可以使用后2位,所以子优先级有0-3
主优先级为0-7,主优先级占3位。子优先级可以使用后1位,所以子优先级有0-1
主优先级为0-15,主优先级占4位。子优先级不占任何位,所以子优先级有0
中断编程顺序
1-使能中断请求
2-配置中断优先级分组
3-配置NVIC寄存器,初始化NVIC_InitTypeDef;
4-编写中断服务函数
1-使能中断请求
使能两个部分,第一个是外设中断产生的使能,第二个是NVIC接收对应外设中断的使能
2,3根据具体的外设和NVIC配置,这里不做描述。外设的头文件和misc.h会有对应的函数声明。
4-编写中断服务函数
中断服务函数写在stm32f10x_it.c文件中,函数结构如下:
void 函数名(void)
{
.......
.......
.......
}
函数名的命名需要在startup_stm32f10x_hd.s文件中的
名称要一致。
EXTI外部中断事件控制器
功能原理
EXTI全称:外部中断事件控制器。GPIO外设产生的电平变化可以产生中断。电平的变化的管理就是EXTI。
产生中断的过程大致是:GPIO产生电平的变化,EXTI检测到变化产生中断,NVIC接收中断信号。
下面介绍一下EXTI功能框图:
输入线:
总共有20根,每一根上有各个端口号的区分
当输入线的信号进入后,会经过边沿检测电路检测是上升沿还是下降沿检测触发产生一个信号1,下一步就会和软件中断进入或门。这里一部分会进入中断电路,另一部分会进入事件电路。
中断电路:经过请求挂起寄存器,在与中断屏蔽寄存器进入与门,最后送入NVIC
事件电路:首先和事件屏蔽寄存器相与门,在送入脉冲发生器。