基于 STM32F103ZE(正点原子战舰开发板)与 ESP32-C3 网络模块的桌面天气时钟,运行 FreeRTOS 多任务系统。LCD 实时展示 WiFi 状态、本地日期时间、城市天气与室内温湿度。
| 模块 | 说明 |
|---|---|
| WiFi 状态 | 通过 ESP32-C3 AT 指令连接无线路由器,实时显示 SSID 与连接状态 |
| 日期时间 | STM32 RTC(LSE 晶振)运行,每小时通过 SNTP(阿里云 NTP)自动校时并回写 RTC |
| 室外天气 | 每 10 分钟从心知天气(Seniverse)API 拉取数据,展示城市名、天气文字、天气代码对应图标、气温度数 |
| 室内环境 | 每 5 秒通过 I²C 读取 AHT20 温湿度传感器,显示室内温度(°C)与湿度(%) |
| UI 渲染 | 独立 UI 线程通过消息队列串行化所有 LCD 写入,防止刷屏冲突 |
| 外设 | 连接 | 用途 |
|---|---|---|
| ESP32-C3 | USART2 (PA2/PA3, 115200bps) | AT 指令、WiFi、SNTP、HTTP |
| TFTLCD (FSMC) | FSMC Bank1 NE4 (PG12) | 并行 LCD 驱动(ILI9341/NT35310 等) |
| AHT20 | I²C2 (PB10/PB11, 100kHz, 地址 0x38) | 室内温湿度采集 |
| RTC | LSE (32.768kHz) | 掉电保持实时时钟 |
| USART1 (DMA) | PA9/PA10, 115200bps | printf 调试日志 |
| 任务 | 栈大小 | 优先级 | 职责 |
|---|---|---|---|
defaultTask |
4 KB | Normal | 启动序列:外设初始化 → 欢迎页 → WiFi 连接 → 创建定时器与主循环任务 |
ui_task |
2 KB | Normal | 显示服务器,从 17 槽消息队列消费 UI 指令(FILL / STRING / IMAGE / CIRCLE / CLEAR) |
main_task |
512 字 | Normal+1 | 事件分发器,接收定时器通知,调度各数据更新任务 |
| 定时器 | 周期 | 作用 |
|---|---|---|
time_sync_timer |
10 分钟(失败指数退避至 1s) | SNTP 校时并回写 RTC |
wifi_update_timer |
1 秒 | 轮询 AT+CWJAP?,SSID 变化时重绘 WiFi 状态栏 |
time_update_timer |
1 秒(自动重载) | 读 RTC 并刷新时钟显示 |
inner_update_timer |
5 秒 | 读取 AHT20 并刷新室内温湿度 |
outdoor_update_timer |
10 分钟 | HTTPS GET 心知天气 API,解析 JSON 并刷新天气区域 |
smart weather rtos/
├── Core/ # STM32CubeMX 生成
│ ├── Src/main.c # 入口、系统时钟、MX 初始化、FreeRTOS 启动
│ ├── Src/freertos.c # defaultTask 创建
│ ├── Src/rtc.c # RTC 初始化(LSE)
│ ├── Src/fsmc.c # FSMC Bank1 NE4 16-bit
│ ├── Src/i2c.c # I2C2(AHT20)
│ └── Src/usart.c # USART1(printf) + USART2(ESP32-C3 AT)
├── APP/ # 应用层代码
│ ├── app.h # WiFi SSID/PASSWORD 定义、版本号
│ ├── app_process.c # 启动流程、欢迎/连接/主界面绘制
│ ├── loop.c # FreeRTOS 定时器 + main_task 事件分发
│ ├── ui/ui.{c,h} # UI 消息队列、ui_task 渲染服务器
│ ├── weather/weather.{c,h} # 心知天气 JSON 解析
│ └── font/ & image/ # 点阵字库(16~76px)/ 天气图标
├── Drivers/zhe/ # 外设驱动
│ ├── esp_AT/esp_at.{c,h} # ESP-AT 指令封装(WiFi / SNTP / HTTP)
│ ├── aht20/driver_aht20.{c,h}# AHT20 I²C 驱动
│ ├── FSMC_LCD/driver_lcd.{c,h}# LCD 底层驱动(ILI9341 等)
│ └── cpu_delay/cpu_delay.{c,h}# DWT 微秒延时
├── Middlewares/Third_Party/FreeRTOS/ # FreeRTOS 10.3.1 + CMSIS-RTOS V2
└── MDK-ARM/ # Keil MDK 项目文件
└── smart weather.uvprojx # Keil uVision 5 项目
-
WiFi:ESP-AT 指令集(Station 模式),
AT+CWJAP连接无线路由器 -
NTP:阿里云 SNTP 服务器(
ntp1/2/3.aliyun.com),AT+CIPSNTPCFG=1,8,AT+CIPSNTPTIME?查询 -
天气 API:心知天气(Seniverse)v3 接口,HTTPS GET,URL 示例:
https://api.seniverse.com/v3/weather/now.json?key=YOUR_KEY&location=CITY&language=zh-Hans&unit=c响应 JSON 解析
results[0].now.{text, code, temperature}与location.{name, path}。
WiFi 凭证与心知天气 API Key 定义在 APP/app.h:
#define WIFI_SSID "Your_SSID"
#define WIFI_PASSWRD "Your_Password"
⚠️ 发布前请勿提交真实凭证,建议改为从 EEPROM 或用户配置区读取。
- Keil MDK-ARM uVision 5(项目文件:
MDK-ARM/smart weather.uvprojx) - STM32CubeMX(可选,用于修改硬件配置,打开
.ioc文件)
- 用 Keil uVision 打开
MDK-ARM/smart weather.uvprojx - 选择目标芯片 STM32F103ZE
- 点击 Build(或快捷键
F7)
- 连接 J-Link / ST-Link 到开发板
- 点击 Download(或快捷键
F8) - 系统自动重启并进入欢迎页
┌──────────────────────────────┐
│ [WiFi] SSID │ ← 顶部状态栏(10,10)~(230,155)
│ 76pt 时:分(闪烁分隔符) │
│ 20pt 日期 星期 │
├──────────────┬─────────────────┤
│ 室内环境 │ 城市名称 │ ← 底部双栏(10,165)~(230,310)
│ 54pt °C │ 54pt °C │
│ 64pt %RH │ [天气图标] │
└──────────────┴─────────────────┘
- 心知天气 API Key 硬编码在源码
APP/loop.c中,请在发布前替换为新密钥或改为从外部存储读取。 - WiFi 密码同理,建议增加配置模式(AP 热点 + Web 配网)以替代烧录时预置。
| 问题 | 说明 |
|---|---|
| FSMC 时序与 UI 坐标不匹配 | FSMC 配置为 SSD1963 800×480 时序,但 UI 坐标基于 240×320 面板;实际使用时请确认 LCD 型号并统一配置 |
| EEPROM 驱动未启用 | Drivers/zhe/E2PROM_24C02/ 代码存在但未接入构建系统,配置存储功能待实现 |
| ESP-AT 驱动为阻塞式 | USART2 收发使用轮询,存在一定阻塞风险,后续可改为 DMA + 中断方案 |
| API Key 明文存储 | WiFi 密码与心知天气 Key 直接写源码,发布前需迁移至安全存储 |
本项目代码仅供学习与个人使用。部分驱动代码源自正点原子 HAL 库,按 ST HAL 许可证条款执行。