如何在STM32F407ZGT6微控制器上使用定时器、中断和任务调度
在这次实验活动中,我学习了如何在STM32F407ZGT6微控制器上使用定时器、中断和任务调度。主要目标是理解中断的工作原理、多个任务如何在系统中运行,以及不同的调度方法对任务性能的影响。
首先,我配置了一个定时器中断,用于自动切换LED。接着,我又添加了另一个定时器,并创建了多个在不同时间间隔运行的任务。然后,我测量了TRelease、TLatency、TISR和TResponse等时序参数,以评估系统的性能。最后,我使用按钮触发事件,实现了一个事件驱动的系统,并将其行为与基于定时器的系统进行了比较。
第一部分:配置带中断的硬件定时器
使用STM32CubeMX创建了一个新的STM32项目。打开软件后,为STM32F407ZGT6微控制器创建了一个新项目。
在 STM32CubeMX 中搜索并选择了用于 RT-Spark 开发板的 STM32F407ZGT6 微控制器,以便将项目配置为正确的微控制器和硬件平台。之后,点击“开始项目”。
还选择了STM32CubeIDE工具链,以便能够打开、编辑、编译并上传生成的代码到STM32F407ZGT6微控制器。
机载LED被配置为GPIO输出,以便程序能够对其进行控制。PF11引脚被分配为LED_RED,而PF12引脚被分配为LED_BLUE。在STM32CubeMX中,这些引脚被设置为输出引脚,使微控制器能够在执行过程中开启或关闭LED。
TIM2定时器被设置为每1秒产生一次中断。通过调整定时器设置,使其输出1 Hz的信号,并将TIM2中断设置为最高优先级。配置完成后,生成了项目代码。
实施
第二部分:实现周期性LED切换的定时器中断服务程序
生成的项目在STM32CubeIDE中打开。随后通过导航至“Core” → “Src” → “main.c”,访问主函数文件,以便添加所需的代码。
在无限循环之前添加了代码 HAL_TIM_Base_Start_IT(&htim2),以启用中断并启动 TIM2。这样,定时器即可开始计数,并在达到设定的定时周期时自动产生中断。
已实现一个定时器回调函数来处理TIM2中断。每当定时器达到设定的时间后,回调函数将自动执行,并切换红色LED(PF11),从而使LED每秒闪烁一次。
该活动已构建并上传至RT-Spark开发板。运行程序后,观察到红色LED每秒闪烁一次,确认定时器中断功能正常工作。
第三部分:创建多任务循环执行系统
第二个定时器TIM3被配置为生成另一个不同频率的周期性中断。该定时器设置为每0.5秒产生一次中断,并且其优先级低于TIM2。配置完成后,项目代码被重新生成以应用这些更改。
添加了全局变量,以帮助中断和主循环共享信息。变量 task_adc_ready 和 task_display_ready 用于指示任务何时可运行,而 tick_count 用于计数定时器事件。
回调函数已更新,TIM2 会切换红色 LED 并通知任务 A,而 TIM3 会切换蓝色 LED 并通知任务 B。这样可以让主循环知道每个任务何时可以运行。
主循环已更新,当任务标志被设置时便会执行任务。任务A模拟ADC处理过程,而任务B模拟显示刷新。
第四部分:测量与分析响应时间
调试引脚(PE0)被配置为GPIO输出,并标记为DEBUG_PIN。
使用 DEBUG_PIN 添加了时间标记。当中断或任务开始时,该引脚被设置为高电平;当任务结束时,被设置为低电平。
第五部分:实现事件触发调度
PA0按钮被设置为中断输入,这样当按钮被按下时,微控制器就能立即作出反应。设置完成后,项目代码被重新生成。
添加了一个外部中断回调函数来检测按钮按下。当PA0按钮被按下时,该函数会立即同时切换红色LED和蓝色LED。
测试按钮中断操作。
将项目上传到电路板进行测试,LED灯继续根据定时器中断闪烁。当按钮被按下时,两个LED灯立即状态改变,表明按钮中断功能正常工作。
分析
在此活动中,使用了基于定时器和事件触发的调度方式。在基于定时器的方法中,任务会在主循环检查其标志时运行,因此可能会产生一些等待时间。而在事件触发的方法中,当发生某个事件(例如按钮按下)时,任务会立即执行。
事件触发方式响应更快,而定时器方式则适用于需要定期执行的任务。
本文编译自hackster.io





