当前位置:首页 > 工业控制 > 电路设计项目集锦
[导读]本实验/项目的目标是在基于STM32F407ZGT6的RT-Spark开发板上实现硬件定时器中断以及前台/后台任务调度系统。通过配置两个硬件定时器TIM2和TIM3,以不同速率切换两个内置LED灯;同时在KEY_UP按钮(PC5)上设置外部中断,按下时可立即切换两个LED灯的状态。系统采用循环执行架构:中断服务例程(ISRs)负责处理紧急的后台任务并设置标志位,而主循环则处理前台的实际任务。

本实验/项目的目标是在基于STM32F407ZGT6的RT-Spark开发板上实现硬件定时器中断以及前台/后台任务调度系统。通过配置两个硬件定时器TIM2和TIM3,以不同速率切换两个内置LED灯;同时在KEY_UP按钮(PC5)上设置外部中断,按下时可立即切换两个LED灯的状态。系统采用循环执行架构:中断服务例程(ISRs)负责处理紧急的后台任务并设置标志位,而主循环则处理前台的实际任务。

注意:原始的资料/文件中建议使用PA0进行按钮中断。经过测试和检查,RT-Spark板上并没有将物理按钮连接到PA0上。

设计与测试

第一部分 — — — 硬件描述

所使用的硬件是基于STM32F407ZGT6微控制器的RT-Spark开发板。由于该板已内置两个LED和方向按钮,因此无需额外的外部元件。引脚分配如下:

第一部分 1.1 — — — 软件设置

•打开 STM32CubeMX

•转到“文件”→“新建”→“STM32 项目”

•在芯片选择器中,搜索 STM32F407ZGT66 并选中它

•点击下一步

•前往项目管理器,设置您偏好的项目名称

•将工具链/IDE设置为STM32CubeIDE

•在左上角的“文件”中保存项目,或直接按 Ctrl + S

第1.2部分 — — 配置GPIO引脚以连接LED

•在引脚分配与配置选项卡中,找到引脚 PF11

•点击并将其设置为 GPIO 输出

•进入系统核心 → GPIO,点击 PF11,并将用户标签设置为 LED_RED

•找到引脚 PF12,将其设置为 GPIO 输出

•将用户标签设置为LED_BLUE

•保存项目并生成代码

第1.3部分 — — 配置系统时钟

在设置定时器之前,系统时钟必须以84 MHz运行。默认情况下,CubeMX生成的代码在16 MHz的原始HSI上运行,这会导致定时器计算完全错误。这是本次实验/项目中遇到的第一个问题:由于ARR被设置为最大值4,294,967,295,而不是9999,LED持续亮着。

•转到时钟配置选项卡

•找到 HCLKCLKCLK 框,输入 84,然后按回车键

•CubeMXMX 将自动配置 PLL 以达到 84 MHz

•保存并重新生成代码

第1.4节 — — 配置TIM2和TIM3

TIM222 每 11 秒(1 Hz)触发一次,TIM333 每 0.55 秒(2 Hz)触发一次。根据第 222 节的定时器周期公式:f_timer = f_APB / (PSC + 1) / (ARR + 1)

对于TIM2:84,000,000 / (8399+1) / (9999+1) = 1 Hz

对于TIM3:84,000,000 / (8399+1) / (4999+1) = 2 Hz

CubeMX 的步骤:

•进入定时器 → TIM2,将时钟源设置为内部时钟

•将预分频器设置为8399,计数周期设置为9999

•在 NVIC 设置中,启用 TIM22 全局中断。

•将优先级设置为0

•进入定时器 → TIM3,将时钟源设置为内部时钟

•将预分频器设置为8399,计数周期设置为4999

•在 NVIC 设置中,启用 TIM33 全局中断。

•将优先级设置为1

•进入系统核心 → NVIC NVIC 并确认优先级

•保存并重新生成代码

第1.5部分 — — 配置调试引脚

•PE000 被配置为 DEBUG_PIN 用于定时测量。

•该引脚在TIM2中断服务程序的开始和结束时被切换。

•以及任务A,允许使用TISR和TTask进行测量

•DWTWT 循环计数器。

•找到引脚 PE0 → 设置为 GPIO 输出

•进入系统核心 → GPIO,点击 PE00 并设置

•用户标签到DEBUG_PIN

•保存并重新生成代码

第1.6部分 — — 配置按钮

实验室最初要求使用PA0,但RT-Spark板上并没有物理按键。在查阅RT-Thread文档后发现,KEY_UP引脚位于PC5,因此改用PC5。实验室还要求使用上升沿+下拉电阻,但该板上的KEY_UP按钮为低电平激活,按下时会连接到GND,而正确的配置应为下降沿+上拉电阻。

•找到引脚 PC5 → 设置为 GPIO_EXTI5

•进入系统核心 → GPIO,点击 PC55 并设置:

•GPIOGPIO 模式:外部中断模式(下降沿)

•GPIO 上拉/下拉:上拉

•进入系统核心 → NVIC,启用 EXTI EXTI EXTI 线[9:5]中断,将优先级设置为 2

第二部分 — — — 软件架构与实现

第二部分 1 — — — 前景/背景架构

系统使用带有中断的循环执行机制。有两个优先级层次:后台(中断服务例程,ISRs)——在被触发时运行,处理紧急任务,并设置标志以通知前台。

前台(主循环)——持续运行,检查标志位并执行实际任务。这比使用 HAL_Delay()() 进行轮询更高效,因为在定时器事件之间,CPUCPU 可以自由进行其他工作。

第2.2部分 — — 全局标志变量

三个标志变量被声明为 volatile,因此编译器不会优化掉主循环中的读取操作:

volatile uint8_t task_adc_ready = 0;

volatile uint8_t task_display_ready = 0;

volatile uint32_t tick_count = 0;

第2.3部分 — — 定时器回调(后台任务)

HAL定时器回调函数在一个函数中处理TIM2和TIM3。htim->Instance字段用于标识是哪个定时器触发了该事件:

第2.4部分 — 主循环(前台任务)

第2.5部分 — — — 按钮中断(事件触发)

第三部分 — 结果

第3.1部分 — LED闪烁输出

刷写代码后,观察到以下情况:

•红色LED每1秒通过TIM2中断闪烁一次

•绿色LED每0.5秒闪烁一次,通过TIM3中断实现

•按下 KEY_UP(PC5)会立即切换两个LED灯。

•前景/背景调度正常工作

第3.2部分 — — 序列图

下方的时序图展示了系统运行3秒的过程,包括TIM2和TIM3以各自的速度触发,标志位传递至主循环,并在约t=1.2秒处发生按钮按下事件。该图表使用Lucidchart创建。

第3.3部分 — 时间测量

使用 ARM Cortex-M4 上的 DWT(数据断点与跟踪)循环计数器获取了真实的时间值。该计数器是一个 32 位寄存器,以 84 MHz 的精度计数 CPU 时钟周期(1 个周期周期 ≈ 11.9 ns)。代码中已启用 DWTWT 计数器:

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;

DWT->CYCCNT = 0;

DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

在TIM2中断服务例程(ISR)的入口/出口处,以及当task_adc_ready = 1和if (task_adc_ready for TLatency)时设置了断点。每次断点处使用STM32CubeIDE中的表达式窗口读取DWT->CYCCNT寄存器。

TISR测量:

DWT在ISR开始时(第69行):246

DWT在ISR末端(第76行):346

时钟周期:346 - 246 = 10000 周期

时间:100 / 84,000,000 = 1.199 微秒

延迟测量:

DWT 在 task_adc_ready = 1 时:44,094,304

DWT 在 if(task_adc_ready): 50, 141, 984

时钟周期:50,141,984 - 44,094,304 = 6,047,68000 周期

时间:6,047,680 / 84,000,000 = 7222 毫秒

时间表:

72毫秒的延迟高于理论上的20毫秒估算值。这是因为该延迟不仅包含了任务B中的HAL_Delay(20),还包括中断服务例程(ISR)完成、返回主循环以及再次回到任务adc_ready检查的时间。这与系统设计预期的情况非常吻合。

第四部分 - 分析

第五部分 — 结论

我学到的东西:

该实验展示了轮询调度与中断驱动调度之间的实际差异。使用硬件定时器可避免在主循环中使用 HAL_Delay(),从而让 CPU 在事件之间有更多时间处理其他任务。前景/后台架构是一种简洁而简单的方式,可在不依赖完整实时操作系统的情况下处理不同优先级的任务。DWTWT 循环计数器是一个有用的工具——测量到的 TISR 为 1.199 微秒,证实了保持中断服务例程(ISRs)较短的重要性,因为整个 TIM2 中断服务例程仅需 100 个时钟周期即可完成。

面临的问题:

问题1——LED在第一次闪烁后一直保持亮起且无法闪烁。系统时钟使用16 MHz的原始HSI运行,而ARR设置为4,294,967,295,而非9999。这两个问题通过将HCLK设置为84 MHz,并在CubeMX中修正ARR得以解决。

问题2——按钮中断未生效。RT-Spark板上PA0(按要求)没有物理按钮,KEY_UP位于PC5。配置已更改为PC5的下降沿+上拉,并将回调函数更新为检查GPIO_PIN_5。

问题3——在TIM3 NVIC设置选项卡中,NVIC抢占优先级被灰色显示。通过从“系统核心 → NVIC”下的全局NVIC表中修改优先级来解决该问题。

本文编译自hackster.io

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

随着世界进入第四次工业革命,工厂正逐步转向使用电子设备和数字媒体。智能工厂在发展中国家和发达国家都日益普及。然而,随着智能工厂更注重效率,安全同样重要,也必须加以考虑。本项目将致力于开发安全功能,保护工人免受被冻柜夹住等...

关键字: TOF PIR传感器 M5Stack 定时器

作为领先的嵌入式处理器模组厂商,米尔将携安路FPGA核心板和开发板亮相。我们诚邀您共聚西子湖畔,一同探索FPGA技术在边缘计算、工业控制与AI加速等领域的最新技术突破与落地实践。

关键字: FPGA 核心板 开发板

如果你曾尝试在边缘端构建过任何类型的视觉系统,比如农业监测、库存追踪等需要本地识别物体而无需向云端发送请求的场景,你可能已经遇到过同样的难题:传统微控制器(MCU)本身没有足够的内存来运行物体检测。无论是内存不足无法缓冲...

关键字: 单板计算机 开发板 STM32N6570-DK

本项目的目标是制作一个非常简单的电压表,至少具备良好的精度,并理解模数转换器(ADC)的工作原理。该项目使用了RT-Thread公司生产的RT-Spark(Spark-1)开发板。

关键字: 模数转换器 电压表 RT-Spark 开发板

该项目是一个基于 RT-Spark STM32 开发板的实时、裸机硬件接口。它充当了一个交互式的控制面板,将物理世界与数字世界连接起来。通过读取来自一个 5 个方向操纵杆的输入,该系统会立即触发数字逻辑来控制外部独立的...

关键字: 液晶显示屏 FSMC 开发板 STM32

米尔电子正式发布 MYDLMX9X 平台 V2.0.0 软件版本。本次升级以系统安全为核心,集成 EdgeLock® Secure Enclave 硬件信任根,完整实现安全启动 (AHAB) 、安全存储、安全 OTA 升...

关键字: 工业物联网 存储 开发板

这是一个使用 RT-Spark(Spark-1)开发板的简单用户界面(UI)项目,该开发板采用的是 STM32F407ZGT6 微控制器芯片。该项目专注于读取开关输入,并通过控制 LED 和在 RT-Spark 内置的液...

关键字: 开发板 微控制器 STM32F407ZGT6

上篇我们完成了 BLC、LSC、AWB、CCM 的客观标定,建立了科学的成像基准。本篇将继续主观调试、IQ 文件配置、常见问题排查等,直至完整 ISP 调试流程落地。

关键字: ISP 摄像头 开发板

为回馈广大开发者长期以来的支持,米尔电子将在本次展会现场举办福利活动,限时免费赠送15套MYD-YM90G开发板。诚邀各位行业伙伴与技术爱好者前往展台了解详情并参与领取。

关键字: FPGA 开发板

在使用未集成 ISP 的摄像头模组进行系统开发时,ISP(Image Signal Processor,图像信号处理器)调试是决定成像质量的核心环节。ISP 作为相机系统的"大脑",负责对前端图像传感...

关键字: ISP 摄像头 开发板
关闭