当前位置: 首页 > web >正文

超详细基于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.xdnf.cn/news/17768.html

相关文章:

  • 嵌入式技术公开课精华笔记:CSDN专版
  • 如何将新建的Anaconda虚拟环境导入Juputer内核中?
  • C++11新增可变参数模板
  • 如何区分类的关系是关联和聚合?
  • 什么是 Spring MVC?
  • unity shader ——屏幕故障
  • Spring Boot项目通过RestTemplate调用三方接口详细教程
  • 网络协议组成要素
  • 数据结构:链表栈的操作实现( Implementation os Stack using List)
  • 飞算JavaAI 2.0.0深度测评:自然语言编程如何重塑Java开发范式
  • 六、SpringBoot多环境开发
  • MP8128GQ-Z转换器 MPS 电子元器件IC
  • 有限元方法中的数值技术:行列式、求逆、矩阵方程
  • 15_基于深度学习的苹果病害检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 自己动手造个球平衡机器人
  • NWD-RKA论文阅读
  • C++Linux八股
  • 【完美解决】在 Ubuntu 24.04 上为小米 CyberDog 2 刷机/交叉编译:终极 Docker 环境搭建指南
  • Web前端小游戏轮盘。
  • VisionPro——1.VP与C#联合
  • 派聪明RAG知识库----关于elasticsearch报错,重置密码的解决方案
  • 基于 Easy Rules 的电商订单智能决策系统:构建可扩展的业务规则引擎实践
  • 计算机网络摘星题库800题笔记 第2章 物理层
  • 【Redis在远程控制指令传递中的设计】
  • mysql参数调优之 sync_binlog (二)
  • Unity DOTS(一):ECS 初探:大规模实体管理与高性能
  • Apache Shiro
  • 小白学习pid环控制-实现篇
  • 知名车企门户漏洞或致攻击者远程解锁汽车并窃取数据
  • ENCOPIM, S.L. 参展 AUTO TECH China 2025 广州国际汽车技术展览会