一、STM32的中断系统
理解中断、 中断源、 中断向量、中断优先级、 中断服务函数…等基础概念。
ARM Cortex M3内核支持256个中断,包括16个内核中断和240个外设中断,拥有256个中断优先级别。
STM32的中断通道可能会由多个中断源共用。这就意味着,某一个中断服务函数也可能被多个中断源所共用。所以,在中断服务函数的入口处,需要有一个判断机制,用以辨别是那个中断触发了中断。
STM32微处理器的内核中有一个NVIC(嵌套向量中断控制器)的设备,它对中断进行统一的协调和控制,其中最主要的工作就是控制中断通道的使能和确定中断的优先级。
STM32中有2个优先级的概念:抢占优先级和响应优先级,每个中断都需要指定这两种优先级。
如果两个抢占优先级相同的中断同时到达,NVIC会根据他们的响应优先级高低来决定先处理哪一个。如果两个同时到达的中断的抢占优先级和响应优先级都相等,则根据中断的自然排位顺序来决定响应哪一个。
二、STM32的外部中断
外部中断EXTI是STM32微处理器实时处理外部事件的一种机制,由于中断请求主要来自GPIO端口的引脚,所以称为外部中断。
STM32F013微处理器有19个能产生事件/中断请求的边沿检测器,每个输入线可以独立地配置成输入类型(脉冲或挂起)和对应的触发事件(上升沿、下降沿或双边沿触发),也可以独立地屏蔽。
EXTI0~EXTI15:GPIO端口引脚。
EXTI16:PVD输出,可编程电压监测。
EXTI17:RTC闹钟。
EXTI18:USB唤醒。
STM32芯片有16个外部中断源EXTIO~EXTI15,分别对应着7个中断向量,也就是对应着7个中断服务函数。
EXTIO、EXTI1、EXT12、EXTI3、EXTI4:专用。
EXTI5~EXTI9:共用。
EXTI10~EXTI15:共用。
EXTI0的连接引脚是:PAO~PG0,即每个端口组的0号引脚。
以此类推。
外部中断触发条件:上升沿触发、下降沿触发或双边沿触发。
注意:不能配置成高电平触发和低电平触发。
三、外部中断的程序设计思路
传统STM32外部中断设计步骤:
【1】将GPIO初始化为输入端口。
【2】配置相关I/O引脚与中断线的映射关系。
【3】设置该I/O引脚对应的中断触发条件。
【4】配置NVIC,并使能中断。
【5】编写中断服务函数。
基于STM32CubeMX的外部中断设计步骤:
【1】在STM32CubeMX中指定引脚,配置中断初始化参数。
选择GPIO引脚的功能,设置中断信号触发条件,使能NVIC对应的中断通道。
【2】重写该I/O引脚对应的中断回调函数。
四、外部中断初始化配置
【1】将GPIO设置为:GPIO_EXTI功能。
【2】设置中断触发条件:上升沿、下降沿、上升沿或下降沿。
【3】使能相关的NVIC通道。(千万别忘了)
五、外部中断初始化函数剖析
//外部中断初始化相关的操作在gpio.c文件中的MX_GPIO_Init()函数完成。
void MX_GPIO_Init(void)
{
/*=====================
此处省略引脚设置的基本代码。
======================*/
/* EXTI interrupt init 外部中断初始化*/
HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0); //设置EXIT3中断的优先级
HAL_NVIC_EnableIRQ(EXTI3_IRQn); //使能EXIT3中断通道
HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
}
六、外部中断服务函数的编写
七、练习:外部中断信号控制LED灯开关
在STM32F103ZET6开发板上,利用STM32CubeMX和Keil5协同开发,完成以下功能:
(1)将KEY1,即 PE3置为外部中断输入, 下降沿触发,在中断服务函数中, 切换LED1的开关状态。
(2)将KEY0,即 PE4置为外部中断输入, 上升沿触发,在中断服务函数中, 切换LED0的开关状态。
由于在前两节的学习笔记中,已经介绍过开发板的原理图,与上拉电阻的原理,因此在此处,查找原理图部分不做详细介绍。详见:基于HAL库开发的STM32学习笔记二:STM32的按键开发基础
想要实现以上内容,还是分为以上两部分,第一部分是利用STM32CubeMX进行全局基本配置,第二步是利用Keil5来重写中断回调函数。
由于外部中断的初始化函数由STM32CubeMX辅助生成,用户只需要重写中断回调函数即可。
第一部分:配置STM32CubeMX
配置STM32CubeMX的详细步骤见基于HAL库开发的STM32学习笔记一:STM32的GPIO开发基础。这里只说明配置外部中断时需要注意的细节。
【1】引脚设置时,引脚模式选择中断模式,EXTI模式。
【2】引脚设置时,设置为对应边沿触发模式,由于引脚和按键连接,需要将引脚设置为上拉模式。
【3】使能相关的NVIC通道,在NVIC选项卡中勾选对应NVIC通道。(很重要)
第二部分:Keil5中代码的编写
前面已经进行过过外部中断的程序设计思路的理解,初始化函数的剖析与中断服务函数的编写,且初始化函数与中断服务函数都是由STM32CubeMX生成,此处只对中断服务函数进行重写。
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==GPIO_PIN_3)
{
HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
}
if(GPIO_Pin==GPIO_PIN_4)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
}
}
/* USER CODE END 0 */
写完代码后,在Keil5里编译好后,就可以下载到单片机中。利用Keil的在线调试功能,通过设置断点,可以更好的观察到中断服务函数的运行过程,会对外部中断服务函数有一个更好的理解。同时在按键操作中,也可以体会到上升沿与下降沿触发中断的区别。
以下是几篇自己学习过程中发现的比较好的文章,有助于对中断的理解:
以上内容为本人学习b站小蜜蜂老师的基于STM32CubeMX的嵌入式开发基础教程所做的笔记,其中有一些为个人的理解与感悟,如有疏漏之处,敬请大佬指正。