手把手教你一步步使用基于HAL库的STM32的完成ESP8266/ESP01S通信OneNET物联网平台 一模块介绍ESP8266 WiFi 模块1. 模块核心介绍型号ESP8266-01S通用串口 WiFi 模块通信方式UART 串口TTL 电平默认波特率1152008N1协议通过AT 指令实现 MQTT 协议对接OneNet 物联网平台核心功能将 STM32 采集的温湿度、甲醛、CO₂浓度等数据上传至云端实现远程监测硬件接口VCC(3.3V)、GND、TX、RX。2. 硬件连接规则一STM32 ↔ ESP8266最小系统板VCC ↔ 3.3VGND ↔ GNDUSART3_TX(PB10)↔ ESP_RXUSART3_RX(PB11)↔ ESP_TX二STM32 ↔ ESP01SVCC ↔ 3.3VGND ↔ GNDUSART3_TX(PB10)↔ ESP_RXUSART3_RX(PB11)↔ ESP_TXEN↔VCC或者接入某个引脚3. 云平台配置WiFi 名称leoWiFi 密码123456789对接OneNet 物联网平台通过 MQTT 协议上传环境监测数据。4. 成果二初始化STM32CUBEMX 配置步骤本工程使用USART3与 ESP8266 通信配置如下步骤 1USART3 串口配置左侧Connectivity→ 选择USART3模式选择Asynchronous异步通信参数设置与 ESP8266 一致波特率115200字长8 Bits校验位None停止位1默认引脚TXPB10RXPB11。步骤 2开启串口接收中断左侧System Core→NVIC勾选USART3 global interrupt使能中断优先级默认即可。步骤 3生成工程代码点击GENERATE CODE生成工程准备添加 ESP8266 驱动。三核心代码esp8266.h esp8266.c 完整文件1. ESP8266 头文件esp8266.h#ifndef _esp8266_h#define _esp8266_h#include stdarg.h#include bsp_config.h// 物联网平台 / WiFi 配置宏 #define WIFI_SSID leo#define WIFI_PASSWORD 123456789// OneNet 平台核心参数#define WIFI_ONENET_PRODUCT_ID XXX#define WIFI_ONENET_DEVICE_NAME XXX#define WIFI_ONENET_TOKEN vXXX// MQTT 服务器参数#define MQTT_HOST_URL mqtts.heclouds.com#define MQTT_HOST_PORT 1883#define MQTT_TOPIC_POST_REPLY $sys/ WIFI_ONENET_PRODUCT_ID / WIFI_ONENET_DEVICE_NAME /thing/property/post/reply#define MQTT_TOPIC_PROPERTY_SET $sys/ WIFI_ONENET_PRODUCT_ID / WIFI_ONENET_DEVICE_NAME /thing/property/set#define AT_MQTT_USERCFG ATMQTTUSERCFG0,1,\ WIFI_ONENET_DEVICE_NAME \,\ WIFI_ONENET_PRODUCT_ID \,\ WIFI_ONENET_TOKEN \,0,0,\\#define AT_MQTT_CONN ATMQTTCONN0,\ MQTT_HOST_URL \,1883,1#define AT_MQTT_SUB_POST_REPLY ATMQTTSUB0,\ MQTT_TOPIC_POST_REPLY \,0#define AT_MQTT_SUB_PROPERTY_SET ATMQTTSUB0,\ MQTT_TOPIC_PROPERTY_SET \,0// 函数声明 void esp8266_printf(char* fmt, ...);void esp8266_rx_init(void);char esp8266_send_cmd(char *cmd, int timeout);char wifi_init(void);char mqtt_init(void);char esp8266_connect_send(const char* paramName, int value, int timeout);void uart_rx_esp8266(void);#endif2. ESP8266 驱动文件esp8266.c#include esp8266.h#include string.h#include stdio.h#include main.h#include usart.h#define TX_SIZE 245#define RX_SIZE 245char at_txbuffer[TX_SIZE] {0};char at_rxbuffer[RX_SIZE] {0};uint8_t at_rxindex 0;uint8_t at_rx 0;/*** brief ESP8266 串口接收中断处理* param 无* retval 无*/void uart_rx_esp8266(void){if(at_rxindex RX_SIZE - 1){at_rxbuffer[at_rxindex] at_rx;at_rxbuffer[at_rxindex] \0;}else{at_rxindex 0;memset(at_rxbuffer, 0, RX_SIZE);}HAL_UART_Receive_IT(huart3, at_rx, 1);}/*** brief 格式化发送数据AT指令专用* param fmt 格式化字符串* retval 无*/void esp8266_printf(char* fmt, ...){memset(at_txbuffer, 0, TX_SIZE);va_list ap;va_start(ap, fmt);vsprintf(at_txbuffer, fmt, ap);va_end(ap);uint16_t length strlen(at_txbuffer);HAL_UART_Transmit(huart3, (uint8_t*)at_txbuffer, length, 2000);}/*** brief ESP8266 接收初始化* param 无* retval 无*/void esp8266_rx_init(void){at_rxindex 0;memset(at_rxbuffer, 0, RX_SIZE);HAL_UART_Receive_IT(huart3, at_rx, 1);}/*** brief 发送AT指令并等待返回* param cmd 指令* param timeout 超时时间* retval 0成功 / -1失败*/char esp8266_send_cmd(char *cmd, int timeout){at_rxindex 0;memset(at_rxbuffer, 0, RX_SIZE);esp8266_printf(%s\r\n, cmd);HAL_UART_Transmit(huart1, (uint8_t*)cmd, strlen(cmd), 2000);while(timeout--){HAL_Delay(1);if(strstr(at_rxbuffer, OK) ! NULL ||strstr(at_rxbuffer, ready) ! NULL ||strstr(at_rxbuffer, ) ! NULL){return 0;}else if(strstr(at_rxbuffer, ERROR) ! NULL){return -1;}}return -1;}/*** brief WiFi 初始化连接* param 无* retval 0*/char wifi_init(void){HAL_Delay(2500);esp8266_printf(ATRESTORE\r\n);HAL_Delay(2500);// 设置Station模式while(esp8266_send_cmd(ATCWMODE1, 1500) -1);// 连接WiFiwhile(esp8266_send_cmd(ATCWJAP\ WIFI_SSID \,\ WIFI_PASSWORD \, 5000) -1);return 0;}/*** brief MQTT 初始化连接OneNet* param 无* retval 0*/char mqtt_init(void){// 配置MQTT用户信息while(esp8266_send_cmd(AT_MQTT_USERCFG, 4000) -1);// 连接MQTT服务器while(esp8266_send_cmd(AT_MQTT_CONN, 4000) -1);// 订阅主题while(esp8266_send_cmd(AT_MQTT_SUB_POST_REPLY, 4000) -1);while(esp8266_send_cmd(AT_MQTT_SUB_PROPERTY_SET, 1500) -1);return 0;}/*** brief 向OneNet上传传感器数据* param paramName 数据名称* param value 数据值* param timeout 超时* retval 0成功 / -1失败*/char esp8266_connect_send(const char* paramName, int value, int timeout){char cmd[256];sprintf(cmd, ATMQTTPUB0,\$sys/%s/%s/thing/property/post\,\{\\\id\\\:\\\123\\\\\,\\\params\\\:{\\\%s\\\:{\\\value\\\:%d}}}\,0,0,WIFI_ONENET_PRODUCT_ID,WIFI_ONENET_DEVICE_NAME,paramName,value);return esp8266_send_cmd(cmd, timeout);}四使用实例主函数中调用 ESP8266 驱动1. 中断回调绑定bsp_it.cUSART3 接收中断绑定 ESP8266 接收函数是数据通信的核心#include bsp_it.h#include esp8266.huint8_t rx3;void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){// ESP8266 对应 USART3if(huart-Instance USART3){uart_rx_esp866(); // 调用ESP8266接收处理函数}}2. 主函数初始化 数据上传bsp.cloop#include bsp.h#include esp8266.h// 环境监测变量uint16_t co2_dat; // CO2浓度uint16_t jiaquan_dat; // 甲醛浓度uint16_t temp_dat; // 温度uint16_t humi_dat; // 湿度void bsp_init(){// 1. 外设初始化MG90_Init();OLED_Init();co2_init();// 2. ESP8266初始化核心esp8266_rx_init(); // 初始化串口接收OLED_NewFrame();OLED_PrintString(0, 0, OneNetConnect..., font16x16, OLED_COLOR_NORMAL);OLED_ShowFrame();wifi_init(); // 连接WiFiOLED_PrintString(0, 16,WIFI_OK!, font16x16, OLED_COLOR_NORMAL);OLED_ShowFrame();mqtt_init(); // 连接OneNet MQTTOLED_PrintString(0, 32,MQTT_OK!, font16x16, OLED_COLOR_NORMAL);OLED_ShowFrame();HAL_Delay(500);}void loop(){// 1. 更新环境数据略DHT11_ReadData(DH11);humi_dat DH11.humi_int;temp_dat DH11.temp_int;jiaquan_dat formaldehyde_concentration;co2_dat eco2_concentration;// 2. 定时上传数据到OneNetstatic uint8_t send_times 0;send_times;if(send_times 1) esp8266_connect_send(Humi, humi_dat, 100);if(send_times 45) esp8266_connect_send(Temp, temp_dat, 100);if(send_times 80) esp8266_connect_send(JiaQuan, jiaquan_dat, 100);if(send_times 110){send_times 0;esp8266_connect_send(CO2, co2_dat, 100);}HAL_Delay(7);}四调试技巧步骤 1使用CH340作为中间人先把这个CH340接入到ESP8266上确保数据正确VCC ↔ 3.3VGND ↔ GNDESP_RX↔ CH340_TXESP_TX↔ CH340_RXESP_EN↔3.3V如果EN引脚没有接入将正确的AT指令通过串口助手发给CH340,CH340再将数据传入给ESP8266模块比如发送“AT”ESP8266模块会自动回复“OK”保证原始数据以及ESP8266模块没有问题。如果ESP8266模块未回复可能①波特率不正确②连接线错误③固件重新烧录带AT指令的固件。详细指令集可以查看乐鑫官网AT 命令集 — ESP-AT 用户指南 文档步骤 2发送指令默认波特是115200数据位8校验位无停止位1。测试指令指令响应功能ATOK测试AT指令复位指令指令响应功能ATRSTOK软件复位还原指令指令响应功能ATRESTOREOK恢复所有参数为默认值并重启设置为WIFI模块指令指令响应功能ATCWMODE1OK设置Wi-Fi为Station模式可以去连接热点连接WIFI指令(确保手机是2.4G的而不是5G的wifi)指令响应功能ATCWJAPleo,123456789WIFI CONNECTEDWIFI GOT IPOK连接到2.4GHz wifileo是热点名称123456789是密码设置 MQTT 用户属性指令响应功能ATMQTTUSERCFG0,1,dev,dev-ID,XXXX,0,0,OK配置MQTT参数dev:设备名称dev-ID设备IDXXX设备密钥可查开Onenet官网查看token生成工具_开发者文档_OneNET连接MQTT服务器指令响应功能ATMQTTCONN0,mqtts.heclouds.com,1883,1OK连接MQTT服务器订阅响应指令响应功能ATMQTTSUB0,$sys/id/dev1/thing/property/post/reply,0OK订阅“设备属性上报响应”主题注意id和dev1的修改订阅请求指令响应功能ATMQTTSUB0,$sys/id/dev1/thing/property/set,0OK订阅“设备属性设置请求”主题注意id和dev1的修改发送数据到物联网指令响应功能ATMQTTPUB0,\$sys/%s/%s/thing/property/post\,\{\\\id\\\:\\\123\\\\\,\\\params\\\:{\\\%s\\\:{\\\value\\\:%d}}}\,0,0,WIFI_ONENET_PRODUCT_ID,WIFI_ONENET_DEVICE_NAME,paramName,value);OK发送数据到Onenet步骤 4单片机发送测试如果上述直接使用CH340向ESP8266模块发送数据没问题下一步将代码一直到单片机中单片机发送串口数据将单片机和CH340相连单片机发送数据根据数据正确与否手动发送OK当数据测试全部完成后将串口助手获得到的单片机数据保存将数据用于CH340和ESP8266模块做最后尝试若没问题可以正常上传说明万事大吉。