STM32CUBE快速入门02
一、实验目的
本次实验所涉及并要求掌握的知识点。
1. 配置和使用STM32外部中断功能
(1)学习外部中断的工作机制,如中断触发条件(上升沿、下降沿、双边沿触发)和中断优先级。
(2)掌握中断处理的基本流程,包括中断产生、中断处理函数的执行以及中断标志的清除。
二、实验内容
1. 抢占优先级相同的中断试验
根据图 1所示的开发板LED和开关按键电路图,使用STM32中断功能设计并实现具有如下功能的程序:
-
- 按KeyLeft,使LED1输出翻转,按KeyRight,使LED2输出翻转;
- 按下KeyLeft键后再快速按下KeyRight键,KeyRight键控制的LED2并不会立刻变化,需等待1秒后才变化。
2. 抢占优先级不同的中断试验
根据图 1所示的开发板LED和开关按键电路图,使用STM32中断功能设计并实现具有如下功能的程序
-
- 按KeyLeft,使LED1输出翻转,按KeyRight,使LED2输出翻转;
- 按下KeyRight键(优先级为2)后快速再按下KeyLeft键,KeyLeft键(优先级为1)控制的LED1会立刻变化。
- 主要实验步骤
- 抢占优先级相同的中断试验
(1)程序设计思路
首先,通过配置 KeyLeft 和 KeyRight 按键的外部中断,当按键按下时触发相应的中断服务例程(ISR)。
当按下 KeyLeft 时,翻转 LED1 的状态,并将 KeyLeft_Pressed 标志设置为 1,表示 KeyLeft 被按下。
若按下 KeyRight,则根据 KeyLeft 的状态来决定是否延迟操作。如果 KeyLeft 已按下,记录当前时间(使用 HAL_GetTick() 获取系统时间),并判断上次按下 KeyRight 的时间。
如果当前时间与上次按下 KeyRight 的时间差小于 1 秒(currentTime - KeyRight_DelayStartTime < 1000),则通过 HAL_Delay() 延迟剩余时间,并在延迟后翻转 LED2,同时重置 KeyLeft_Pressed,表示 KeyLeft 按键状态已清除。如果 KeyLeft 没有按下,则直接翻转 LED2。
通过 HAL_GetTick() 来检查 KeyRight 是否需要等待 1 秒再执行操作,避免按键抖动和控制延迟。
(2)程序流程图
- 关键步骤与代码分析
- MX配置
- 按键、LED与MCU连接的GPIO引脚的设置如下,两个按键引脚设置为外部中断触发方式
- 在SYS组件中,设置Debug为Serial Wire
- 在RCC组件中,设置HSE为Crystal/Ceramic Resonator
- 在NVIC组件中,首先在Priority Group下拉列表框里选择优先级分组,这里选择2bits for pre-emption priority 2 bits for subpriority,即选择2位用于抢占优先级,2位用于次优先级;设置EXTI line2 interrupt和EXTI line4 interrupt中断优先级相同,均为1。
- 将KEY_LED目录添加到项目的头文件搜索路径和源程序搜索路径里
②关键代码分析及实现
- 生成代码中的主程序main.c已经完成了GPIO引脚的初始化,包括外部中断的初始化设置,还生成了外部中断ISR的代码框架
- 在main.h中生成了按键KeyRight、KeyLeft、LED1、LED2的引脚号、端口和宏定义
GPIO和EXTI中断初始化
文件gpio.c中的函数MX_GPIO_Init()实现了GPIO引脚和EXTI中断的初始化。这个函数对LED、按键进行初始化,并对外部中断进行设置。
EXTI中断的ISR
在文件stm32f4xx_it.c中自动生成了ISR的代码框架,ISR调用中断函数HAL_GPIO_EXTI_Callback()
- 在gpio.c重新实现中断回调函数HAL_GPIO_EXTI_Callback()
- 定义
KeyLeft_LastPressTime,KeyRight_LastPressTime,KeyLeft_Pressed,KeyRight_DelayStartTime四个变量分别记录KeyLeft按下的时间,KeyRight按下的时间,KeyLeft的状态,KeyRight按下的起始时间。
(4)结果分析
按KeyLeft,使LED1输出翻转,按KeyRight,LED2输出翻转;按下KeyLeft键后再快速按下KeyRight键,KeyRight键控制的LED2需等待1秒后才变化。
2. 抢占优先级不同的中断试验
(1)程序设计思路
配置 KeyLeft 和 KeyRight 按键的外部中断,通过 EXTI (外部中断) 触发回调函数。
设置KeyLeft优先级为1,KeyRight优先级为2
回调函数:按下KeyLeft时翻转LED1,按下KeyRight时翻转LED2
(2)程序流程图
(3)关键步骤与代码分析
① MX配置
- 在GPIO组件的模式和配置页面,对按键引脚的外部中断触发方式、LED引脚进行设置
- 在SYS组件中,设置Debug为Serial Wire
- 在RCC组件中,设置HSE为Crystal/Ceramic Resonator
- 在System Core分组里,单击NVIC,在其模式与配置界面进行中断设置,首先在Priority Group下拉列表框里选择优先级分组,选择2 bits for pre-emption priority 2 bits for subpriority,即选择2位用于抢占优先级,2位用于次优先级
- EXTI line2 interrupt优先级设为2,EXTI line4 interrupt优先级设为1
②关键代码分析
- 生成代码中的主程序main.c已经完成了GPIO引脚的初始化,包括外部中断的初始化设置
- GPIO和EXTI中断初始化
文件gpio.c中的函数MX_GPIO_Init()实现了GPIO引脚和EXTI中断的初始化
- EXTI中断的ISR
在文件stm32xx_it.c中自动生成了ISR的代码框架
- 重新实现中断回调函数
当KeyLeft按下时,翻转LED1;当KeyRight按下时,翻转LED2。由于在MX配置KeyLeft的优先级高于KeyRigth,实现优先翻转LED1
- 实验结果分析
按KeyLeft,使LED1输出翻转,按KeyRight,使LED2输出翻转;按下KeyRight键(优先级为2)后快速再按下KeyLeft键,KeyLeft键(优先级为1)控制的LED1会立刻变化。