STM32的中断操作
中断的概念是嵌入式开发和计算机系统中非常重要的部分。
可以参考学堂在线的《ARM微控制器与嵌入式系统》的相关章节。
两个概念:
- NVIC(嵌套向量中断控制器):用于设置中断优先级和中断使能。位于芯片内部。
- EXTI(外部中断/时间控制器):用于设置外部中断和事件。位于APB2总线上。
注意:异常和中断清单在stm32f10x.h中的IRQn_Type中。
NVIC相关的处理位于misc.h中,EXTI相关的处理位于stm32f10x_exti.h中。
全流程:1. 初始化GPIO 2. 初始化EXTI 3. 配置NVIC使能中断 4. 编写中断服务函数
NVIC的设置
STM32使用4bit表示中断优先级。通常首先设置优先级分组,共有五种优先级分组,分别使用0-4bit表示主优先级,剩下的表示子优先级。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
具体的设置方式使用对应的初始化结构体
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;// 中断编号 EXTI0_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;// 中断使能
NVIC_Init(&NVIC_InitStructure);
同时还需要设置中断服务函数,其函数声明写在stm32f10x_it.h中,函数定义写在stm32f10x_it.c中。中断服务函数名在汇编启动文件中定义,与中断名相对应(例如EXTI0_IRQn和EXTI0_IRQHandler)。
(考虑到相关的宏定义的有效性,也可以写在对应模块的C文件中)
EXTI的设置
EXTI包括了20个外部中断/事件线。包括中断屏蔽寄存器、边沿选择寄存器、请求挂起寄存器、软件中断事件寄存器。可以从外设事件或者GPIO输入产生中断和事件。其中的中断线路信号传入NVIC内,事件线路信号得到一个脉冲(用于其他的外设使用)。
GPIO线可以挂载到EXTI的0-15上(注意编号一一对应,例如GPIOA-3挂在EXTI3上),剩下的四根线用于特定的任务。注意这里的EXTI线的具体定义分别为EXTI0、EXTI1、EXTI2、EXTI3、EXTI4、EXTI9_5、 EXTI15_10。位于“stm32f10x_exti.h”中。
具体的设置方式使用初始化结构体:
// 先设置GPIO 注意打开AFIO时钟(用于EXTI设置)
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd((RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO),ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 将GPIO挂载到EXTI上
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,\
GPIO_PinSource0);
// 再设置EXTI线
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_LINE0;// 与GPIOpin对应
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;// Interrupt或者Event
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;// Rising或Falling或RIsing_Falling
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
中断服务函数
中断号和终端服务函数在NVIC中设置,分别参见stm32f10x.h和汇编启动文件的定义。
中断服务函数需要在stm32f10x_it.h中定义,在stm32f10x_it.c中实现,或者在对应的模块C文件中实现(考虑到宏定义的有效性)。
中断服务函数中通过EXTI_GetITStatus()获得中断标志位为SET/RESET。处理结束后通过EXTI_ClearITPendingBit()清除中断标志位。