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()清除中断标志位。

Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.