
一、前言很多单片机项目都会遇到一个很现实的问题数据能上传但时间不对。比如你在服务器上看到的可能是固定时间、开机计时或者根本没有时间字段。这样后面做历史数据统计、告警分析、曲线展示都会很麻烦。这篇文章只讲一件事1.STM32 如何通过 ESP-01S 获取北京时间2.STM32 如何把北京时间写进 MQTT 报文3.STM32 如何把数据上传到服务器云端二、整体思路整个流程其实很简单1.STM32 上电初始化2.ESP-01S 连接 WiFi3.通过 NTP 获取北京时间4.STM32 解析时间字符串5.组装成 JSON 报文6.通过 MQTT 上传到服务器三、硬件准备本例使用的硬件很简单STM32F103C8T6ESP-01S WiFi 模块USB 转 TTLMQTT 服务器串口连接建议如下STM32 USART3_TX 接 ESP-01S RXSTM32 USART3_RX 接 ESP-01S TX3.3V 供电供电不稳可以上5VGND 共地四、ESP-01S 需要执行的 AT 命令先确认模块在线AT设置 STA 模式ATCWMODE1连接路由器ATCWJAP你的WiFi名,你的WiFi密码配置 NTPATCIPSNTPCFG1,8,cn.ntp.org.cn,ntp.sjtu.edu.cn查询当前北京时间ATCIPSNTPTIME?演示结果五、北京时间是怎么来的这里最关键的一步就是 NTP。我们发这条命令ATCIPSNTPCFG1,8,cn.ntp.org.cn,ntp.sjtu.edu.cn它的意思是1开启 NTP8时区偏移代表北京时间 UTC8后面两个是 NTP 服务器地址然后查询时间ATCIPSNTPTIME?返回可能类似CIPSNTPTIME:Thu Jun 26 09:19:25 2026 OK六、STM32 端如何读取时间STM32 不需要自己去算时间只需要把 ESP-01S 返回的字符串解析出来。核心思路是先发 ATCIPSNTPTIME?再找返回值中的 CIPSNTPTIME:然后把时间存成统一格式示意代码static HAL_StatusTypeDef WifiTime_QueryCurrent(char *timeText, uint16_t size) { if (ESP01S_SendCommand(ATCIPSNTPTIME?\r\n, OK, 5000U) ! HAL_OK) { return HAL_ERROR; } const char *p strstr(ESP01S_GetLastResponse(), CIPSNTPTIME:); if (p NULL) { return HAL_ERROR; } p strlen(CIPSNTPTIME:); // 这里继续解析时间字符串 return HAL_OK; }七、如何把北京时间写进 MQTT 报文拿到北京时间后就可以把它写进 JSON 里。例如{ saleid: 10100001, gateid: 10100001001, type: report, time: 2026-06-26 09:19:25, sequence: 11, source: da, meter: [ { id: ENV001, status: 1, name: RadarDHT11, values: { Temp: 31.5, Humi: 45.6 } } ] }八、为什么推荐 MQTTPUBRAW在实际测试中直接用 ATMQTTPUB 容易遇到转义问题尤其 JSON 里面有很多引号和逗号。所以更稳的方式是ATMQTTPUBRAW0,report/allpoints,69,0,0九、结语这套方案的核心其实很简单STM32 负责控制和组包ESP-01S 负责联网和 NTPMQTT 负责上传北京时间由 NTP 获取