基于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 性能优化方案

  1. 缓冲区管理

    #define RX_BUFFER_SIZE 256
    uint8_t uart_rx_buffer[RX_BUFFER_SIZE];
    HAL_UART_Receive_IT(&huart2, uart_rx_buffer, RX_BUFFER_SIZE);
    
  2. 心跳机制

    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);
}
posted @ 2025-12-02 16:46  yes_go  阅读(0)  评论(0)    收藏  举报