TamotoClock
传感题目-番茄钟项目设计报告
—— 基于 STM32F407 + FreeRTOS + LVGL 的嵌入式智能番茄钟系统
主控芯片: | STM32F407 (Cortex-M4) |
图形库: | LVGL v8.x |
操作系统: | FreeRTOS |
显示屏: | 320×240 RGB565 LCD |
一、 项目概述
TamotoClock 是一款基于 STM32F407 微控制器的嵌入式智能番茄钟系统,集成了 FreeRTOS 实时操作系统、LVGL 图形库、FATFS 文件系统等多种中间件,实现了番茄工作法计时、环境温湿度监测、电池电量监控、历史数据统计等功能。项目采用分层架构设计,从底层硬件驱动到中间件层再到应用层,层次分明、职责清晰,具有良好的可维护性和可扩展性。
使用了一款电感得捷电子商城编号为F1C1- 201612- R10M,他是Signal Transformer 推出的 F1C1-2016 系列屏蔽表面贴装功率电感,采用高度仅 0.8 mm、1.0 mm 和 1.2 mm 的超薄设计,占板面积仅为 2.0 mm × 1.6 mm。该系列通过独特的铁粉合金 T-core 磁芯结构提升效率,在磁屏蔽下兼顾小尺寸、低直流电阻和高额定电流,适用于 DC/DC 转换器、手机、LCD 显示屏、电源模块及服务器中的电压调节模块等对空间和 EMI 敏感的高密度应用。
图表 1相关资料
本报告将从底层硬件驱动层、中间件层、应用层三个维度对该项目进行全面的技术分析,涵盖芯片选型、外设配置、任务调度、GUI 设计、数据持久化等关键技术点。
二、 底层硬件驱动层
2.1 主控芯片与时钟系统
项目采用 STM32F407 作为主控芯片,该芯片内置 Cortex-M4 内核,主频可达 168MHz,具备单周期乘法器和浮点运算单元(FPU),适合运行图形渲染等计算密集型任务。系统时钟通过外部高速晶振(HSE)经 PLL 倍频至 168MHz,时钟树配置为:AHB 时钟 168MHz,APB1 42MHz,APB2 84MHz,为各外设提供精确的时钟源。
2.2 外设驱动配置
项目基于 STM32 HAL 库驱动各类外设,主要包括以下几个方面:
外设 | 接口/功能 | 用途说明 |
| |
SPI1 | 配合 DMA | LCD 屏幕通信,实现高效数据传输 |
| |
I2C1 | 标准模式 | AHT20 温湿度传感器通信 |
| |
ADC1 | 12位分辨率,通道 3 | 电池电压检测(PA3) |
| |
DAC1 | 模拟输出 | 音频提示音输出 |
| |
TIM13/TIM14 | 定时器 | TIM14 提供 LVGL 时基,TIM13 用于传感器采样 |
| |
RTC | 实时时钟 | 提供时间日期功能,带备份寄存器 |
| |
SDIO + FATFS | SD 卡接口 | 文件系统支持,用于数据持久化存储 |
| |
USB Device | CDC 虚拟串口 | 调试与数据传输接口 |
| |
2.3 LCD 屏幕驱动
显示屏幕分辨率为 320×240,采用 RGB565 16位色彩格式,通过 SPI 接口与主控通信,并配合 DMA 实现高效的帧缓冲传输。LCD 驱动层封装了基础绘图函数(画点、画线、填充等),为上层 LVGL 提供显示缓冲区接口。显示缓冲区配置为 10 行显示缓冲(320×10),在保证刷新率的同时兼顾了内存占用。
2.4 AHT20 温湿度传感器驱动
AHT20 通过 I2C 接口与主控通信,驱动层采用状态机设计,支持非阻塞操作,避免传感器采集过程中占用过多 CPU 时间。采样周期为 10 分钟,由 TIM13 定时触发,在保证数据实时性的同时降低了系统功耗。
2.5 接口设计
主要设计了多种存储方式,比如ERRPROM和NAND FLASH,保证可扩展性和作为独立开发板使用。
2.6方案框图项目设计思路
本系统以 STM32F407VET6(ARM Cortex-M4F,168MHz)为核心主控芯片,围绕其构建了存储、显示、交互和电源管理四大功能模块。
存储子系统 采用三级存储架构:NAND FLASH(MT29F4Gxx) 提供大容量非易失存储,用于存放系统程序和用户数据;SDIO 接口(128MB) 支持可插拔 SD 卡,便于数据导出与扩展;EEPROM(16Kb) 用于保存关键配置参数和校准数据,掉电不丢失。三者均通过 STM32 的片上外设接口与主控进行数据交互。
显示模块 选用 ST7789 LCD 驱动芯片,通过 SPI 接口与主控连接,驱动 TFT 彩色液晶屏实现图形化用户界面的输出显示。
人机交互模块包含按键和旋转编码器两种输入方式,用于菜单导航和参数调节,满足便携设备简洁高效的操控需求。同时预留UART1 串口和SWD调试接口,方便开发调试和数据通信。
电源管理模块支持USB 输入和电池双路供电,通过选择 LDO电路在两路电源之间自动切换,后级经 LDO1和LDO2两路低压差线性稳压器分别输出不同电压轨,为各功能模块提供稳定可靠的电源。
整体方案采用模块化设计思路,各功能子系统独立清晰、接口明确,兼顾了功能完整性、开发便利性和成本可控性。
2.7 原理图PCB展示
总览:
原理图电源部分:
用1uH电感和两个电容构成滤波器,隔离数字VCC和模拟VCC,选用磁珠隔离AGND和DGND.
原理图理想二极管部分:
使用如图所示的结构,可以当mos左边大于右边时,开始通过体二极管供电,之后右边有电压之后将左边pnp三极管拉低,使mos进入线性区达到导通效果.
原理图旋转编码器:
如果不想写软件滤波,可以选用RC低通滤波,可以有效吸收脉冲,但是这个元器件东西有点问题,向着一方转的话有时候会出问题,比如出现莫名其妙的尖峰脉冲,如果有这种情况朝着另一方转就不会出现这种情况.
原理图SD卡:
在设计SD卡时,要注意接上拉电阻,如果寄生电容较大,可以降低电阻提升结电容充点电流,减少充电速度.
原理图USB部分:
使用USB和电脑通讯,或者用CDC等的时候要注意,每次重新烧录程序的时候都要重新初始化USB,插拔一下USB,设计这样一个开关,就可以解决这个问题.
PCB总览:采用四层PCB绘制:
PCB顶面:
SD卡部分做了等长处理.对大块铜皮选择直接打过孔到地面.
PCB内电层:
注意到右上角有一根导线分割了这里的GND网络,让他从蜂鸣器的下面回流回去分割PGND
PCB内电层2:
通过这里也分割开5V(上面)和3V3(下面)来给相关部分供电.
PCB底层
可以看到走线都是在顶层和底层完成的,有参考平面.
三.中间件层
3.1 FreeRTOS 实时操作系统
项目采用 FreeRTOS 作为实时操作系统,实现了抢占式多任务调度。根据不同功能的实时性要求和优先级,系统创建了四个任务:
任务名称 | 优先级/栈大小 | 功能说明 |
Default Task | Normal / 3KB | 主任务,处理 LVGL 事件、传感器数据、电池监控 |
LCD Task | Idle / 256B | 番茄钟计时任务,控制倒计时逻辑 |
UpdateData Task | Low / 256B | 统计数据更新,处理日/周/月数据聚合 |
SdFile Task | Normal / 512B | SD 卡文件读写,实现数据持久化 |
任务间通信采用 FreeRTOS 任务通知(Task Notification)机制,轻量级且高效。此外,系统还配置了一个 1 秒周期的软件定时器(encoder_timer),用于番茄钟倒计时功能。
3.2 LVGL 图形库
系统采用 LVGL v8.x 作为 GUI 框架,完成了显示驱动和输入设备的移植适配。显示驱动配置了 10 行显示缓冲区(320×10 像素),刷新回调函数通过 SPI+DMA 实现高效传输,确保界面流畅。GUI 界面使用 NXP GUI Guider 工具设计生成,包含主界面、菜单界面、番茄钟界面、设置界面和统计界面五个主要页面,支持自定义字体和图片资源。
3.3 FATFS 文件系统
FATFS 文件系统通过 SDIO 接口驱动 SD 卡,支持长文件名,用于存储番茄钟的历史统计数据。数据以二进制格式(data.bin)存储在 SD 卡上,确保断电后数据不丢失。
四、 应用层
4.1 GUI 界面设计
项目包含五个主要界面,各界面功能如下:
1. 主界面(screen_main):显示数字时钟、日期、温湿度信息,提供导航按钮进入其他功能页面。
2. 菜单界面(screen_menu):功能列表导航,支持在各功能模块间切换。
3. 番茄钟界面(screen_clock):核心功能页,包含环形进度条倒计时显示、专注/休息状态指示、开始/暂停/重置按钮及电池电量显示。
4. 设置界面(screen_setting):提供专注时间、休息时间、周期数、音量、亮度等参数的调节功能。
5. 统计界面(screen_statistic):支持日/周/月三级数据切换,以柱状图形式展示历史专注数据。
4.2 番茄钟核心业务逻辑
番茄钟工作流程包含五个阶段:初始化设置参数(专注时长、休息时长、周期数)→ 进入专注阶段,环形进度条推进倒计时,显示“Focus” → 专注结束后进入休息阶段,显示“Rest” → 循环执行 N 个周期 → 全部完成后显示“Finished!”并记录数据。倒计时由软件定时器 encoder_timer 驱动,每秒更新一次界面显示。
4.3 数据统计与持久化
统计系统实现了日/周/月三级数据聚合,分别维护最近 16 天、16 周、16 个月的历史数据。数据结构采用环形队列设计,支持新数据入队和旧数据自动淘汰。所有数据通过 FATFS 文件系统以二进制格式存储在 SD 卡上,由专门的 SdFile Task 负责读写操作,避免文件 I/O 阻塞影响主任务的实时性。
五、 软件启动流程和关键代码调试
软件流程
系统启动流程按照以下顺序执行:
1. HAL 库初始化(HAL_Init)和系统时钟配置(SystemClock_Config),将主频设置为 168MHz。
2. 外设初始化,按顺序启用 GPIO、DMA、SPI、TIM、FSMC、I2C、RTC、SDIO、FATFS、DAC、ADC 等外设。
3. 应用层初始化,包括 LVGL 初始化(lv_init)、显示驱动初始化(lv_port_disp_init)、输入设备初始化、GUI 界面初始化(setup_ui)及事件初始化(events_init)。
4. FreeRTOS 初始化(MX_FREERTOS_Init),创建各任务和定时器。
5. 启动 ADC 中断并调用 osKernelStart() 启动任务调度器,系统正式进入多任务运行状态。
关键代码说明
这段代码主要改进了lvgl的画图方式,使用DMA+SPI搬运数据优化,使用st7789芯片手册的区域刷新,可以设定需要更新的范围,进而来提升帧率和刷新速度.
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
if(disp_flush_enabled) {
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
uint16_t XS = area->x1;
uint16_t XE = area->x2;
uint16_t YS = area->y1;
uint16_t YE = area->y2;
/* 设置LCD显示窗口 */
LCD_Address_Set(XS,YS,XE,YE);
int width = area->x2 - area->x1 + 1;
int height = area->y2 - area->y1 + 1;
static uint8_t dat[320 * 2];
for(int j = 0; j < height; j++)
{
int idx = 0;
for(int i = 0; i < width; i++)
{
uint16_t c = color_p[i].full;
dat[idx++] = c >> 8;
dat[idx++] = c & 0xFF;
}
HAL_SPI_Transmit_DMA(&hspi1, dat, 2 * width);
while (hspi1.State != HAL_SPI_STATE_READY);
color_p += width;
}
}
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
六、 心得体会
PCB第一版问题:
第一版已经被我删了,所以没有图片可以放,他的问题主要是使用了一个8PIN的排线接口,那个排线接口非常的难焊接,而且容易掉下来,不是很稳固.而且当时处于快速验证阶段,有的芯片接线有问题,比如没有给NAND FLASH接BUSY接线,这样要保证他不出错,要等很久,因为没办法判断芯片状态所以需要设置更长的信号周期,来保证读写数据的正确性.
除此之外,第一版绘制没有完整地平面,稍微快速一点的信号会出现毛刺,不是特别好.
绘制的原件比较少,新版的PCB有充足的资源可以利用,方便学习.
PCB第二版问题:
第一是这个aht20的布局离LDO太近了。导致有问题,因为当时没想到LDO加热这么严重.
第二是这个第一次写这么复杂的代码,写的最后有点混乱。
第三是这个要保证有完整地平面和电源层,好多引脚没引出来这一点不太好,后面有待改进,不利于后续的改进工作.
功能展示
温湿度自动周期测量,时间日期显示:
定时器开始专注
页面可以设置很多参数:
设置Cycle定时的循环周期,Period一次多长时间,Rest休息多长时间,Counting down正计时还是倒计时.
Bright通过DAC使三极管变为压控恒流源,调节电压进行电流控制调节亮度.
Volume通过PWN占空比0-50%调节蜂鸣器的音量,这里要注意,无源蜂鸣器占空比不是越大越好.
Information页面可以看当前软件信息
Save保存数据到芯片.
选择数据显示.显示之前的数据,保存前480天数据.
七、总结
TamotoClock 项目是一个功能完整、设计精良的嵌入式番茄钟系统,充分展示了 STM32 嵌入式开发的综合能力。从底层的 HAL 外设驱动到中间件层的 FreeRTOS 多任务调度和 LVGL 图形渲染,再到应用层的番茄钟业务逻辑和数据统计功能,整个系统架构清晰、层次分明。项目在硬件资源有限的条件下,通过合理的任务分配、DMA 传输优化、状态机驱动等技术手段,实现了流畅的用户体验和可靠的数据存储, 可以低成本快速学习多种接口.,具有较高的工程参考价值。