超詳細基于stm32hal庫的esp8266WiFi模塊驅動程序(可直接移植)

目錄

前言:

1 前期準備

1.1 了解mqtt通信協議

1.1.1核心組件

1.2 ESP8266固件燒錄

1.3 啟動EMQX服務器

1.3.1大概了解emqx的使用

2 驅動代碼講解應用

2.1 硬件接線

2.2 AT指令

2.3 驅動代碼

2.4 效果展示


前言:

esp8266支持mqtt通信協議,在一些只能在局域網環境下通信來說是十分便捷的(比如智能家居環境),下面這個工程就是stm32單片機結合esp8266作為客戶端與其他客戶端設備互相通信。

1 前期準備

1.1 了解mqtt通信協議

????????MQTT (Message Queuing Telemetry Transport) 是一種輕量級、開放標準、基于發布/訂閱模式的消息傳輸協議。它最初由 IBM 和 Eurotech 在 1999 年設計,用于連接石油管道上的遠程傳感器與衛星鏈路。如今,它已成為物聯網 (IoT) 領域事實上的標準通信協議。

1.1.1核心組件

1. 發布者 (Publisher): 產生并發送消息的客戶端(設備或應用)。例如:在我們的工程里我們將單片機采集到的數據通過串口轉發給esp8266,而esp充當消息的發布者。
2. 訂閱者 (Subscriber): 接收其感興趣消息的客戶端(設備或應用)。例如:手機 App 訂閱溫度讀數以顯示,或者空調控制器訂閱溫度讀數來決定是否開啟。
3. 代理服務器 (Broker): MQTT 通信的核心樞紐。它負責:
接收來自發布者的消息。
根據消息的主題 (Topic) 將其過濾并轉發給所有訂閱了該主題的訂閱者。
管理客戶端連接(認證、授權、會話狀態)。
存儲 QoS 消息以確保可靠傳輸(根據 QoS 級別)。
處理遺囑消息 (Last Will & Testament)。

在這個工程里我們使用開源的mqtt服務系統EMQX.


4. 主題 (Topic): 這是 MQTT 實現通信的關鍵機制。 主題是一個 UTF-8 字符串,充當消息的“地址”或“路由標簽”。發布者發布消息時必須指定一個主題。訂閱者通過訂閱特定的主題(或使用通配符)來表明它希望接收哪些主題的消息。例如:home/livingroom/temperature, factory/machine42/vibration。
5. 消息 (Message): 包含實際傳輸的數據(Payload),可以是任何格式(JSON, XML, 二進制, 純文本等)。消息總是與一個主題相關聯

1.2 ESP8266固件燒錄

esp8266要使用mqtt通信需要燒錄含mqtt的固件網上可以找到很多教程(一些廠家出廠自帶固件)

1.3 啟動EMQX服務器

需要在本地部署emqx服務器過程不難

這里推薦一個教程Windows下載安裝EMQX_emqx下載-CSDN博客

1.3.1大概了解emqx的使用

在首頁我們可以查看到連接服務器的設備有哪些(每一個設備有自己獨立端口點開可以查看)

我們可以在服務器里創建客戶端位置如下

使用規則也很簡單最基本的,訂閱了同一個主題的設備,當其他設備發送消息的時候,己設備可以看到,同樣的當己設備發布消息的時候,其他跟我訂閱同一主題的設備就可以收到己設備發送的消息。也是這樣實現了多個設備之間的互相通信。

2 驅動代碼講解應用

2.1 硬件接線

只需要用到esp8266的4各引腳,gnd,3.3v,tx,rx(tx rx分別與單片機的串口交叉相連)如下圖

2.2 AT指令

esp8266可以使用AT查看設備的一些遠行狀態下面給出以下常用的AT指令

2.3 驅動代碼

這里我使用stm32hal庫寫了一段容易移植的代碼,文件構成為ESP8266.c(關于esp8266的驅動代碼),ESP8266.h,comation.c(系統驅動代碼),comation.h,head.h(包含要用到的頭文件)只需要在主函數里初始化一下就可以使用了。

因為該模塊可以商店自動連接WiFi所以我在初始化的時候沒有連接WiFi,如果想要換WiFi可以調用下面函數

/* @briefWIFI重連* @param* @return*/
void ESPWIFI_Reconnect(void)
{//斷開WiFiUART_Printf(&huart2, "AT+CWQAP");HAL_Delay(1000);//連接WiFiUART_Printf(&huart2, "AT+CWJAP=\"%s\",\"%s\"\r\n",WIFI_NAME,WIFI_PASSWORD);
}

ESP8266.c

/** ESP8266.c**  Created on: Aug 11, 2025*      Author: ccc*/
#include "head.h"/** @brief esp初始化連接服務器* @param* @return* */
char esp_response[RESP_BUFFER_SIZE];//接收緩存區
uint16_t resp_index = 0;//接受標志位
uint8_t esprx_byte;
void Inint_esp8266(void)
{HAL_UART_Receive_IT(&huart2, &esprx_byte, 1);HAL_Delay(30);// 配置認證UART_Printf(&huart2, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",MQTT_CLIENT_ID,MQTT_USERNAME,MQTT_PASSWORD);HAL_Delay(1000);// 連接服務器UART_Printf(&huart2, "AT+MQTTCONN=0,\"%s\",1883,0\r\n",MQTT_BROKER);HAL_Delay(3000);// 訂閱主題UART_Printf(&huart2, "AT+MQTTSUB=0,\"%s\",1\r\n",MQTT_TOPIC);HAL_Delay(1000);}
/** @brief esp響應函數* @param* @return* */
void ESP8266_ReceiveHandler(UART_HandleTypeDef *huart)
{//  處理接收到的字節// 檢查緩沖區是否已滿if(resp_index >= RESP_BUFFER_SIZE - 1){resp_index = 0; // 重置緩沖區,防止溢出}// 存儲接收到的字節esp_response[resp_index++] = esprx_byte;//  檢測是否收到完整響應(以換行符結束)if(esprx_byte == '\n'){esp_response[resp_index] = '\0'; // 添加字符串結束符//  打印原始響應UART_Printf(&huart1, "ESP8266get: %s\n", esp_response);//  處理關鍵響應(以下消息使用串口1轉發)if(strstr(esp_response, "OK") != NULL){UART_Printf(&huart1, "Getsuccessful!\n");}else if(strstr(esp_response, "ERROR") != NULL){UART_Printf(&huart1, "Getfailed!\n");}else if(strstr(esp_response, "+MQTTCONNECTED:0") != NULL){UART_Printf(&huart1, "MQTTConnection successful!\n");}else if(strstr(esp_response, "+MQTTDISCONNECTED:0") != NULL){UART_Printf(&huart1, "MQTTDisconnect!\n");}else if(strstr(esp_response, "MQTTSUBRECV:0") != NULL){// 解析MQTT消息// 格式: +MQTTSUBRECV:0,<topic>,<length>,<message>char *topic_start = strchr(esp_response, ',') + 1;char *topic_end = strchr(topic_start, ',');char *length_start = topic_end + 1;char *length_end = strchr(length_start, ',');char *msg_start = length_end + 1;// 提取主題int topic_len = topic_end - topic_start;char topic[topic_len + 1];strncpy(topic, topic_start, topic_len);topic[topic_len] = '\0';// 提取消息長度int msg_len = atoi(length_start);// 提取消息內容char message[msg_len + 1];strncpy(message, msg_start, msg_len);message[msg_len] = '\0';UART_Printf(&huart1, "getMQTTmessage: [topic] %s [message] %s\n", topic, message);}memset(esp_response, 0, sizeof(esp_response));resp_index = 0; // 重置緩沖區索引}//  重新啟動接收,等待下一個字節HAL_UART_Receive_IT(&huart2, &esprx_byte, 1);
}
/** @brief esp發送函數* @param* @return* */
void Publish_Message(const char *message)
{// AT+MQTTPUB=0,<topic>,<message>,<qos>,<retain>UART_Printf(&huart2, "AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n", MQTT_TOPIC, message);HAL_Delay(100);
}/* @briefWIFI重連* @param* @return*/
void ESPWIFI_Reconnect(void)
{//斷開WiFiUART_Printf(&huart2, "AT+CWQAP");HAL_Delay(1000);//連接WiFiUART_Printf(&huart2, "AT+CWJAP=\"%s\",\"%s\"\r\n",WIFI_NAME,WIFI_PASSWORD);
}

ESP8266.h

/** ESP8266.h**  Created on: Aug 11, 2025*      Author: ccc*/#ifndef ESP8266_H_
#define ESP8266_H_#include "head.h"#define MQTT_BROKER        "192.168.124.20"  //服務器地址ip
#define MQTT_PORT          1883	//服務器端口號  1883不限制端口號
#define MQTT_CLIENT_ID     "mcus-test-client"	//客戶端唯一標識
#define MQTT_USERNAME      "user"  //用戶名,如不需要可留空
#define MQTT_PASSWORD      "pass"  //密碼,如不需要可留空
#define MQTT_TOPIC	       "test2" //要訂閱的主題
#define WIFI_NAME          "IPhone"//wifi名
#define WIFI_PASSWORD  	   "lyl975418"//wifi密碼#define RESP_BUFFER_SIZE 256
extern char esp_response[RESP_BUFFER_SIZE];
extern uint16_t resp_index;
extern uint8_t esprx_byte;void Inint_esp8266(void);
void ESP8266_ReceiveHandler(UART_HandleTypeDef *huart);
void Publish_Message(const char *message);
void ESPWIFI_Reconnect(void);
#endif /* ESP8266_H_ */

comation.c

/** comation.c**  Created on: Aug 11, 2025*      Author: ccc*/
#include "head.h"
/** @brief格式化輸出到串口上* @param* @return* */
void UART_Printf(UART_HandleTypeDef *USARTx, char *fmt,...)
{unsigned char UsartPrintfBuf[296];va_list ap;unsigned char *pStr = UsartPrintfBuf;va_start(ap, fmt);vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);							//格式化va_end(ap);while(*pStr != '\0'){HAL_UART_Transmit (USARTx ,(uint8_t *)pStr++,1,10);}}
/* @brief串口中斷回調函數* @param* @return* */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART2){//HAL_UART_Receive_IT(&huart2, &esprx_byte, 1);ESP8266_ReceiveHandler(&huart2);}}

comation.h

/** comation.h**  Created on: Aug 11, 2025*      Author: ccc*/#ifndef COMATION_H_
#define COMATION_H_
#include "head.h"void UART_Printf(UART_HandleTypeDef *USARTx, char *fmt,...);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
#endif /* COMATION_H_ */

head.h

/** head.h**  Created on: Aug 11, 2025*      Author: ccc*/#ifndef HEAD_H_
#define HEAD_H_
/**@系統頭文件*/
#include "main.h"
#include "i2c.h"
#include "icache.h"
#include "usart.h"
#include "gpio.h"
#include "stdarg.h"
#include "stdio.h"
#include "stdbool.h"
#include <string.h>
#include <stdlib.h>/** 自定義頭文件* */
#include "ESP8266.h"
#include "comation.h"
#endif /* HEAD_H_ */

2.4 效果展示

我們使用python寫的客戶端發布主題時,esp8266可以收到在串口助手展示

同樣的我們使用esp8266發送消息時python也可以收到

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92988.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92988.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92988.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

redis認識緩存擊穿

緩存擊穿是指 一個非常熱點的數據&#xff08;被高并發訪問&#xff09;在緩存中過期失效的瞬間&#xff0c;導致大量并發請求同時穿透緩存&#xff0c;直接落到底層數據庫&#xff0c;造成數據庫瞬間壓力劇增甚至崩潰的現象。關鍵特征和你的描述解析“數據庫沒有就需要命中的數…

TF-IDF——紅樓夢案例

目錄 用 TF-IDF 挖掘《紅樓夢》各回目核心關鍵詞&#xff1a;一個 NLP 實踐案例 一、案例背景與目標 二、實現步驟 步驟 1&#xff1a;數據準備與分卷處理 1. 導入模塊與創建目錄 2. 打開源文件并初始化變量 3. 逐行處理文本內容 4. 寫入卷內容并過濾前兩行 5. 關閉最后…

【軟考中級網絡工程師】知識點之 IP QoS 技術

目錄一、IP QoS 技術是什么1.1 定義與概念1.2 重要性和應用場景二、IP QoS 技術原理2.1 流量分類與標記2.2 流量整形與限速2.3 擁塞避免與管理2.4 資源預留協議&#xff08;RSVP&#xff09;三、IP QoS技術模型3.1 盡力而為服務模型3.2 綜合服務模型&#xff08;IntServ&#x…

Git 常用命令速查表

一、倉庫初始化與克隆命令說明git init在當前目錄初始化本地倉庫git clone <遠程倉庫地址>克隆遠程倉庫到本地&#xff08;例&#xff1a;git clone https://github.com/user/repo.git&#xff09;二、文件狀態與提交命令說明git status查看工作區 / 暫存區文件狀態git a…

第五十四章:AI模型的“壓縮大師”:GPTQ、AWQ與bitsandbytes實戰量化

AI模型壓縮前言&#xff1a;讓訓練好的AI模型“輕裝上陣”第一章&#xff1a;回顧與挑戰&#xff1a;訓練后量化&#xff08;PTQ&#xff09;的必要性1.1 量化原理與精度類型回顧&#xff1a;FP32到INT4/INT81.2 PTQ&#xff08;Post-Training Quantization&#xff09;&#x…

在Word和WPS文字一頁中實現一欄與多欄混排

在Word和WPS文字的一頁中如何實現分欄和不分欄的內容混排&#xff1f;只需要使用分欄功能。把光標放在要分欄的位置&#xff0c;插入分欄即可&#xff0c;最關鍵的點是分欄應用于“插入點之后”。如果不需要分欄&#xff0c;則欄數選擇為1即可。一、Word和WPS文字的分欄設置路徑…

Python調用C/C++函數庫的多種方法與實踐指南

Python作為一門高級編程語言&#xff0c;以其簡潔的語法和豐富的庫生態贏得了開發者的青睞。然而&#xff0c;在計算密集型任務中&#xff0c;Python的性能往往無法滿足要求。Python調用C/C函數庫成為提升應用性能的關鍵技術路徑&#xff0c;通過將底層計算邏輯用C/C實現&#…

【21】OpenCV C++實戰篇——OpenCV C++案例實戰二十七《角度測量》

OpenCV C案例實戰二十七《角度測量》 利用opencv獲取三點所形成直線的角度

程序在計算機中的運行方式

程序在計算機中的運行是一個涉及硬件、操作系統和軟件協同工作的復雜過程。我們可以將其分解為幾個關鍵階段來理解&#xff1a;1. 程序的誕生&#xff1a;從源代碼到可執行文件 編寫代碼&#xff1a;程序員使用高級編程語言&#xff08;如C、Python、Java&#xff09;編寫源代碼…

虛擬卡券管理平臺詳細設計文檔

文章目錄**1. 文檔概述**1.1 目標1.2 核心能力**2. 業務場景分析**2.1 用戶場景2.2 關鍵業務流程卡券核銷流程&#xff1a;**3. 整體架構設計**3.1 技術棧3.2 微服務拆分**4. 功能模塊詳細設計**? 4.1 卡券生命周期管理**4.1.1 卡券類型設計****4.1.2 關鍵狀態機**? 4.2 卡券…

Oracle參數Process

RDBMS&#xff1a; 19.28 參考文檔&#xff1a; IF:How to determine an optimum value for PROCESSES parameter (Doc ID 2012693.1) All About the Initialization Parameter PROCESSES and the Related Issues (Doc ID 2673195.1) How to calculate the proper value from …

【數據結構入門】樹

目錄 1.樹的概念 父子結點 根節點|葉節點 結點的度 葉子結點或終端結點 兄弟結點 樹的度 結點的層次 樹的高度或深度 結點的祖先 堂兄弟結點 子孫 森林 2. 樹的結構定義 2.1 左孩子右兄弟結構 2.2 數組表示法 3.樹&非樹 1.樹的概念 樹是一種非線性的數據結…

手把手教你用 Flink + CDC 實現 MySQL 數據實時導入 StarRocks(干貨)

手把手教你用 Flink CDC 實現 MySQL 數據實時導入 StarRocks&#xff08;干貨&#xff09; 如何利用 Apache Flink 結合 CDC&#xff08;Change Data Capture&#xff0c;變更數據捕獲&#xff09;技術&#xff0c;將 MySQL 的數據實時導入 StarRocks&#xff0c;打造高效的實…

Rust:anyhow 高效錯誤處理庫核心用法詳解

以下是 anyhow 庫在 Rust 中的核心用法詳解&#xff08;結合最佳實踐和示例&#xff09;&#xff1a; &#x1f530; 一、anyhow 的核心價值 用于簡化錯誤處理&#xff0c;尤其適合&#xff1a; 需要快速原型開發的應用需要豐富錯誤上下文&#xff08;Context&#xff09;的場…

阿里云服務linux安裝單機版

一、單機安裝Redis 阿里教程 下載地址:redis下載地址 1、首先需要安裝Redis所需要的依賴&#xff1a; yum install -y gcc tcl 2、下載Redis 注&#xff1a;也可以自己下好然后上傳到云服務 wget https://gitcode.net/weixin_44624117/software/-/raw/master/software/Li…

python之uv使用

文章目錄安裝與更新standalonepip 安裝創建以及初始化項目依賴管理uv run直接在命令行運行python代碼片段直接運行項目中可執行腳本文件運行python包中快捷指令uv項目本地運行調試細節vscode 中運行調試uv項目命令行運行深入理解 uv lock, uv sync, uv lockuv lock 行為解析:uv…

【CV 目標檢測】①——目標檢測概述

一、目標檢測概述 1.目標檢測 目標檢測&#xff08;Object Detection&#xff09;的任務是找出圖像中所有感興趣的目標&#xff0c;并確定它們的類別&#xff08;分類任務&#xff09;和位置&#xff08;回歸任務&#xff09; 目標檢測中能檢測出來的物體取決于當前任務&…

C#圖形庫SciChart與ScottPlot及LiveCharts2對比

一.概述 1.SciChart SciChart 是一個專為企業級應用設計的高性能數據可視化庫&#xff0c;提供跨平臺的圖表解決方案&#xff0c;支持 .NET、JavaScript、iOS 和 Android 等多個平臺。它以卓越的渲染性能、豐富的專業圖表類型和強大的交互功能著稱&#xff0c; 廣泛應用于金…

Win10電腦密碼忘記如何進入操作系統

http://xq128.com/zj.htmlhttps://share.feijipan.com/s/LbFdbUKl下載后&#xff0c;準備一個空的U盤&#xff0c;大于4G。將U盤制作為PE盤。之后將制作好的PE盤插入到電腦中&#xff0c;啟動待去除密碼的電腦臺式機&#xff0c;啟動后一直按住F12&#xff0c;進入BIOS。選擇下…

[免費]基于Python的網易云音樂熱門歌單可視化大屏項目(flask+pandas+echarts+request庫)【論文+源碼+SQL腳本】

大家好&#xff0c;我是python222_小鋒老師&#xff0c;看到一個不錯的基于Python的網易云音樂熱門歌單可視化大屏項目(flaskpandasechartsrequest庫)&#xff0c;分享下哈。 項目視頻演示 【免費】基于Python的網易云音樂熱門歌單可視化大屏項目(flaskpandasecharts爬蟲) Py…