基于STM32和ESP8266实现MQTT功能
一、系统架构设计
1.1 硬件组成
// 硬件连接定义
#define ESP8266_UART huart2 // 使用USART2
#define ESP8266_RST PA0 // 复位引脚
#define ESP8266_CH_PD PA1 // 使能引脚
// MQTT服务器配置
#define MQTT_BROKER "test.mosquitto.org"
#define MQTT_PORT 1883
#define MQTT_CLIENT_ID "STM32-Client"
#define MQTT_TOPIC "sensor/data"
1.2 系统框图
[STM32] --UART--> [ESP8266] --Wi-Fi--> [MQTT Broker]
| | |
| 传感器数据 | 云端服务 |
| (温度/湿度) | (阿里云/AWS) |
二、核心代码实现
2.1 硬件初始化
void MX_ESP8266_Init(void) {
// 引脚配置
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
// RST引脚配置(低电平复位)
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// CH_PD使能
GPIO_InitStruct.Pin = GPIO_PIN_1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
// UART初始化
MX_USART2_UART_Init();
}
void ESP8266_Reset() {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(1000);
}
2.2 MQTT协议实现
// MQTT消息结构体
typedef struct {
char topic[32];
char payload[64];
uint8_t qos;
} MQTT_Message;
// MQTT连接状态机
typedef enum {
MQTT_DISCONNECTED,
MQTT_CONNECTING,
MQTT_CONNECTED
} MQTT_State;
MQTT_State mqtt_state = MQTT_DISCONNECTED;
// 发送AT指令函数
HAL_StatusTypeDef ESP8266_SendCommand(char* cmd, char* ack, uint32_t timeout) {
HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), timeout);
HAL_Delay(timeout);
if(strstr((char*)huart2.Instance->DR, ack) != NULL) {
return HAL_OK;
}
return HAL_ERROR;
}
// MQTT连接函数
void MQTT_Connect() {
if(mqtt_state == MQTT_CONNECTED) return;
ESP8266_SendCommand("AT+MQTTUSERCFG=0,1,\"client1\",\"user\",\"pass\",0,0,\"\"\r\n", "OK", 1000);
HAL_Delay(500);
ESP8266_SendCommand("AT+MQTTCONN=0,\"", MQTT_BROKER, "\",1883,1\r\n", "OK", 2000);
HAL_Delay(2000);
mqtt_state = MQTT_CONNECTED;
}
2.3 数据发布与订阅
// 发布数据
void MQTT_Publish(float temperature) {
char payload[64];
sprintf(payload, "{\"temp\":%.2f}", temperature);
char cmd[128];
sprintf(cmd, "AT+MQTTPUB=0,\"%s\",\"%s\",1,0\r\n", MQTT_TOPIC, payload);
ESP8266_SendCommand(cmd, "OK", 500);
}
// 订阅回调处理
void MQTT_Subscribe_Callback(char* topic, char* message) {
if(strcmp(topic, MQTT_TOPIC) == 0) {
printf("Received: %s\n", message);
// 处理接收到的控制指令
}
}
// 订阅主题
void MQTT_Subscribe() {
char cmd[64] = "AT+MQTTSUB=0,\"";
strcat(cmd, MQTT_TOPIC);
strcat(cmd, "\",1\r\n");
ESP8266_SendCommand(cmd, "OK", 1000);
}
三、多任务调度实现(FreeRTOS)
// 任务优先级定义
#define TASK_MQTT_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define TASK_SENSOR_PRIORITY ( tskIDLE_PRIORITY + 1 )
// MQTT任务函数
void vMQTT_Task(void *pvParameters) {
while(1) {
MQTT_Connect();
MQTT_Subscribe();
vTaskDelay(pdMS_TO_TICKS(60000)); // 每分钟检查连接
}
}
// 传感器任务函数
void vSensor_Task(void *pvParameters) {
while(1) {
float temp = Read_Temperature(); // 读取温度传感器
MQTT_Publish(temp);
vTaskDelay(pdMS_TO_TICKS(5000)); // 每5秒发布一次
}
}
// 主函数
int main(void) {
MX_ESP8266_Init();
MX_USART2_UART_Init();
xTaskCreate(vMQTT_Task, "MQTT_Task", 256, NULL, TASK_MQTT_PRIORITY, NULL);
xTaskCreate(vSensor_Task, "Sensor_Task", 128, NULL, TASK_SENSOR_PRIORITY, NULL);
vTaskStartScheduler();
while(1);
}
四、关键配置说明
4.1 ESP8266固件要求
- 需要烧录支持MQTT的AT固件(推荐使用ESP8266_NONOS_SDK)
- 最小固件版本:AT version 0.21.0.0
4.2 MQTT服务器配置
| 参数 | 推荐值 | 说明 |
|---|---|---|
| Broker地址 | test.mosquitto.org | 公共测试服务器 |
| 端口 | 1883 | 默认非加密端口 |
| 客户端ID | STM32-Client | 需保证唯一性 |
| QoS等级 | 1 | 保证消息至少送达一次 |
五、调试与优化
5.1 串口调试技巧
// 添加调试日志
void Debug_Log(char* msg) {
printf("[LOG] %s\r\n", msg);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 100);
}
// 错误处理示例
if(ESP8266_SendCommand("AT+CWJAP", "OK", 5000) != HAL_OK) {
Debug_Log("WiFi连接失败");
Error_Handler();
}
5.2 性能优化方案
-
缓冲区管理:
#define RX_BUFFER_SIZE 256 uint8_t uart_rx_buffer[RX_BUFFER_SIZE]; HAL_UART_Receive_IT(&huart2, uart_rx_buffer, RX_BUFFER_SIZE); -
心跳机制:
void MQTT_KeepAlive() { static uint32_t tick = 0; if(++tick >= 60000) { // 60秒发送PINGREQ ESP8266_SendCommand("AT+MQTTHEARTBEAT=0,60\r\n", "OK", 500); tick = 0; } }
六、典型应用场景
6.1 温湿度监测系统
// DHT11传感器读取
float Read_Temperature() {
uint8_t data[5] = {0};
DHT11_Read(data);
return (data[2] << 8 | data[3]) * 0.1;
}
// 主循环
while(1) {
float temp = Read_Temperature();
MQTT_Publish(temp);
vTaskDelay(pdMS_TO_TICKS(10000));
}
6.2 智能家居控制
// 订阅控制指令
void MQTT_Subscribe_Callback(char* topic, char* message) {
if(strcmp(topic, "home/light") == 0) {
if(strcmp(message, "ON") == 0) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET); // 开灯
}
}
}
参考代码 通过STM32和ESP8266实现MQTT功能 www.youwenfan.com/contentcnm/69642.html
七、扩展功能实现
7.1 OTA升级
// OTA升级函数
void OTA_Update() {
ESP8266_SendCommand("AT+OTA=1\r\n", "OK", 1000);
HAL_Delay(2000);
// 通过MQTT接收固件数据
while(1) {
MQTT_Receive_Update_Packet();
}
}
7.2 TLS加密通信
// 启用TLS加密
void MQTT_Enable_TLS() {
ESP8266_SendCommand("AT+MQTTSTARTTLS=0,443\r\n", "OK", 1000);
HAL_Delay(1000);
ESP8266_SendCommand("AT+MQTTCONN=0,\"broker.emqx.io\",443,1\r\n", "OK", 2000);
}

浙公网安备 33010602011771号