在STM32单片机上实现了一个基于FreeRTOS的多任务处理系统
扫描二维码
随时随地手机看文章
FreeRTOS是一个轻量级、开源的实时操作系统内核,专为微控制器和小型嵌入式系统设计。它提供基本的RTOS特性,如任务调度、任务间通信、同步机制和低功耗管理,同时保持最小的内存占用。
在这个项目中,FreeRTOS被用来管理STM32微控制器上的多个并发任务,实现确定性执行、模块化软件设计和安全访问共享硬件资源。RTOS调度器处理任务切换,而任务通过延迟函数显式地产生CPU控制,实现适合资源受限系统的协作多任务方法。
项目目标
该项目的目标是设计和实现一个基于rtos的多任务嵌入式系统,该系统同时:
•从I2C传感器获取温度数据
•使用模拟输入控制RGB LED亮度
•更新LCD上的图形信息
•定时执行LED闪烁任务
所有任务都独立运行,同时使用RTOS同步原语安全地共享系统资源。
步骤1:硬件和外设初始化
•使用STM32CubeMX配置系统时钟,gpio, ADC, I2C, FSMC和PWM外设
•通过FSMC使用8080并行接口初始化LCD (ST7789 v3)
•通过I2C方式初始化AHT20温湿度传感器
•验证LED和电位器输入的正确操作
引脚映射和接线连接:
GND -> Left Leg
PA1 -> Middle Leg
3.3V -> Right Leg
STM32 Dev Board -> RGB
GND -> Long Leg
PA6 -> Red Leg
PE13 -> Blue Leg
PE11 -> Green Leg
步骤2:驱动程序集成和实现
•适应/实现了ST7789驱动程序(src/drv_lcd. + inc/drv_lcd.h和drv_lcd_font.c中的字体例程)来初始化显示,设置窗口,并在FSMC上绘制文本/像素。
•实现AHT2x驱动程序(src/drv_aht21.c + inc/drv_aht21.h)执行I²C事务并将响应转换为温度/湿度值。
•增加了简单的ADC读取助手和PWM设置功能,用于LED控制。
步骤3 - RTOS任务设计
实现了四个重点的FreeRTOS任务(在src/main.c中创建):
•读取AHT2x,格式化温度字符串,更新LCD(周期性)。
•采样ADC,平滑值,映射到PWM占空比的RGB LED。
•CounterTask -在LCD上增加并显示一个计数器。
•BlinkTask -以稳定的速率切换GPIO LED。
•每个任务运行一个无限循环,并在更新后使用vTaskDelay(),以便任务自愿放弃(协作式行为)。
步骤4 -同步:保护LCD
•为LCD创建一个FreeRTOS互斥锁(xSemaphoreCreateMutex())。
•每一个多步骤的LCD操作在写入前都要获取互斥锁(设置窗口→推像素→绘制文本),然后立即返回。
•在xSemaphoreTake上使用短超时,以便任务可以跳过更新或重试,而不是死锁。
步骤5 - ADC平滑和PWM映射
•应用一个小的平滑滤波器(简单的EMA)原始ADC样本,以避免可见的LED闪烁。
•将滤波后的ADC值映射到定时器PWM占空比并更新三个通道(R/G/B)。
步骤6 -电源考虑
•启用FreeRTOS空闲处理(tickless-idle或vApplicationIdleHook),以便MCU可以在没有任务准备好时进入睡眠状态。
•确保睡眠进入不会干扰所需的中断(I²C, TIM, ADC)。
步骤7 -构建,flash和验证
在STM32CubeIDE中构建项目,并使用ST - Link进行闪现。
物理板上已验证的行为:
•LCD初始化和清除。
•温度显示,并定期更新。
•计数器在它自己的LCD区域中递增。
•电位器平滑地改变RGB亮度。
•闪烁LED以预期速率切换。
•没有LCD损坏(互斥锁保护访问)。
步骤8:观察、调整和决定
•保持LCD临界区短:在RAM中准备字符串/缓冲区,然后短暂地使用互斥锁进行写入。
•轻微增加互斥锁超时,以减少在繁忙活动期间跳过的更新。
•增加ADC平滑去除可见的闪烁。
•如果计划稍后进行较大的刷新,可以考虑使用DMA或双重缓冲来减少显示阻塞时间。
要在repo中检查的文件(工作所在的地方):
-任务创建,互斥锁创建,调度程序启动,高级流程。
•src/drv_lcd., inc/drv_lcd.h - ST7789初始化和绘图功能。
Src /drv_lcd_font.c, inc/drv_lcd_font.h -字体渲染和文本辅助程序。
•src/drv_aht21.c, inc/drv_aht21.h - AHT2x传感器驱动程序(I²C读取/转换)。
•/FreeRTOSConfig.h -本项目使用的RTOS配置。完整的repo的源代码在最后。
结果示例
本文编译自hackster.io





