使用 ESP8266 实现 MQTT 功能 ------ 网络函数完善与 AT 指令实践
上次我们将所有网络相关函数设为空函数,是为了后续自定义实现 MQTT 的发送、接收、订阅等功能。本次,我们将继续完善这些函数。

1. 目标文件与实现思路
我们需要编写目标文件中的所有函数,使用 AT 指令配合 ESP8266 来实现。
由于后续可能更换为 ESP32 芯片,建议将代码结构按芯片类型分层实现,便于维护和移植。

程序分层示例

二、AT 命令测试

1. AT 命令的作用与反馈
测试 AT 命令,了解其基本用途。

- 发送 AT 命令,ESP8266 会返回 ok,表示通信正常。

- 打开使用示例,熟悉基本操作。

- 配置 WiFi 模式:
- soft:软 AP 模式,允许其他设备连接本模块
- station:STA 模式,模块连接其他路由器

- 命令参数错误时,ESP8266 会返回 error。

2. WiFi 连接流程
- 先配置 WiFi 模式,再连接 WiFi。
AT+CWMODE=3//softAP+stationmode

- 配置完成后,使用以下命令连接 WiFi:

使用ESP8266实现MQTT功能的开发笔记
上次我们将所有网络相关="你的WiFi名称","你的WiFi密码" // 连路由器,返回WIFI GOT IP的函数都设置为了空函数,目的是为了后续实现自己的MQTT发送即为成功
、接收、订阅等功能。本次笔记将
3带你逐步完善这些函数。
\[. MQTT 连接与主题订阅 1. 配置 MQTT TLS 连接DISABLE_728e0f68\]
<!-- 2参数(推荐直接填写域名,端口 -->
开发步骤概览
8883):
// 配我们需要编写的正是该文件中的所有置MQTT TLS连接参数(域函数,实现方式为:
- 通过名直接填,不用IP!端口8883)
AT+MQTTUSERCFAT指令,配合ESP8266模块G=0,5,"你的Client完成相关操作。
- 初期为保证ID","你的MQTT用户名","你的MQTT密码",0,0,"编译通过,函数可先写为空,后续"
// 设置MQTT服务器逐步补全。
- 建议针对不同芯:直接填域名+8883端口,开启片(如ESP8266、ESP32SSL加密
AT+MQTTCO)分别编写,便于后续芯片更换时NN=0,"wb3ff66a.ala.cn-hangzhou的兼容性。

--.emqxsl.cn",888-
##3,0,0,0
-
连接 MQTT 服务器。
-
主题 程序分层设计思路
建议采用订阅与发布数据:
```c
//分层结构进行程序设计,便于维护与扩展。
\[DISABLE 订阅主题,云平台下发消息ESP8266就能收到 AT+MQ_37cb9a55\]
--TTSUB=0,"你的订阅主题-
#",0
// ESP8266 一、测试AT命令

向上云平台发送数据
AT+MQ
<!-- 5 -TTPUB=0,"你的发布主题->
AT命令的基本用法",0,0,0,"要发送的数据
我们先测试AT命令的基本功能内容"
- 实现主题的,了解其用处。
\[DISAB订阅和数据的发布。  LE_b45f72ef\]
<!-- 8 -- 发送AT命令时,ESP->
4. TCP 连接与数据发送
- 连接 TCP 后,发送数据需指定长度。收到 ok 后,ESP82668266会回传OK,表示通信正常。

- 可以打开使用示例进行测试。
\[ 返回 \>,此时可发送数据。 \
- 例如,配置WIFI模式的指令如下:
- `-- 9 -->
5. 串soft`模式(软AP):其他设备可以连接你
- `口数据接收思路
- 串口接收station`模式:你可以连接数据较为复杂,需要结合发送端代码处理 OK、ERROR 等返回其他路由器
\[DISABLE状态。 1. 若命令格式正确但参数错误,会返回44a24bd0\]
6. 函数内部实现要点
-error。
\[DIS 建议采用中断方式接收数据,存ABLE_7aee37c0\]
1. 配入缓冲区(buffer),再由置WIFI模式
- 先使用如下主程序读取。
\[DISAB指令配置WIFI模式: \`\`LE_898f2c97\]
`c
AT+CWMODE=3- 使用环形缓冲区,配合读写指//softAP+stationmode
- 配置完成后2]]
7. 环形即可进行下一步。

2. 连接缓冲区设计
- 需要设计读写WIFI
- 使用以下指令连接指针,实现数据重复利用。
|------------------------|--------|
| 手写笔记内容 | 代码对应部分 |
| `UART_Write(cf router | |
-
连接成功后,ESP8266会提示WIFI已连接,并获取到IPhar *buf,int len地址。
-
查询WIFI I)` | `UART1_Write()`函数,逻辑一致 |
P地址:
```c
AT+CIFSR //WIFI I| `Tx_len = len; memcpy(xxx_bufP 查询
- 设置,buf,len) | 代码里uart1_tx_remaiSTA模式并连接路由器:
``n_len、uart1_tc AT+CWMODE=1 // 设置STx_buf |
| 启动 Tx Empty 发送空中断 |A Station模式,连路由 __HAL_UART_ENABLE_IT(&huart1,器 AT+CWJAP="你的Wi UART_IT_TXE) |
| UART_Tx_ISRFi名称","你的WiFi密码" // 连路由器,返回WIF()发送中断服务函数 | `HAL_UART_TxEmptI GOT IP即为成功
3. 连接MQTT服务器
- 配置yCallback()`,逐字MQTT TLS连接参数(推荐节写入寄存器发送 |
| 接收使用域名,端口8883):
```c
// 配置MQTT T数据 | 配套环形缓冲区接收中LS连接参数(域名直接填,不用IP!端口8883)
AT+MQ断,不丢包 |
| 串口 1 连 ESP8266、串口 2 打TTUSERCFG=0,5,"你的ClientID","你的MQTT用户名","你的MQTT印 | 按硬件分配实现 |
| 注释编码 | 全部 GB23密码",0,0,""
12 简体中文 |
- 对应
- 设置MQTT服务器(使用的环形缓冲区函数如下:
\[域名+8883端口,开启SSLDISABLE_55053246加密): AT+MQTTCONN=0,"wb3ff\]
<!-- 1266a.ala.cn-hang -->
8. main.c 配置与编译
- 在 main.c 里先注释原有内容,再zhou.emqxsl.cn",自行编写初始化与测试代码。

\[DISABLE8883,0,0,0 --- ### 4. 主题订阅与发布 - 订阅主题(云_376b268c\]
- 编译测试,逐步完善功能。
<!-- 接收):
// 订阅主题
AT+MQTTSUB=13 -->
9. 串口接收中断判定
- USART_SR_RXNE=1 表示数据0,"你的订阅主题",0
- 发布主题(ESP82寄存器非空
- USART_S66向云平台发送数据):
``R_RXNEIE=1 表示接收`c
// 发布主题
AT+MQ中断已使能
- 两者同时满足时TTPUB=0,"你的发布主题",0,0,0,"要发送的数据内容"
\[DISAB,表示已收到数据,可进行读取   --LE_16720350\]
TCP数据发送
-
- 串口发送函数示例
// =====================连接TCP后,发送数据需使用指定命令并给定数据长度,收到`ok`后,ESP8266会返回`>`= 串口1发送函数 ======================
// 功能:发送一串数据
void USART1_Sen符号,表示可以发送数据。
\[d(uint8_t \*data, uint16_t len) DISABLE_b295aaae\]
<!-- 7{
// 循环发送每一个字节
for(uint16_t i=0; i<len -->
串口数据接收处理思路
- 串口接收数据处理较; i++)
{
// 等待发送完成为复杂,需要结合发送端代码进行解析,因为返回值可能包含`OK`或`ERROR`等。
\[ while(!(huart1.Instance-\>SR \& USART_SR_TXE)); DISABLE_44a24bd // 写入数据 huart1.Instance-\>DR = data\[i\];0\]
- 具体实现细节可参考函数内部实现。

}
}
-
测试环形缓冲区与串口功能。
-
通常使用中断方式接收数据,数据存入缓冲区,后续读取该缓冲
| 功能 | 函数 | 用法说明 |
| --- | --- | --- |
| **初始区即可。

##化接收** | UART1_RX_Init(); | main 函数里调用一次 |
| * 环形缓冲区的实现
- 需要*读取接收数据** | UART_FIFO_ReadByte设计环形缓冲区,包括读写指针,实() | 任务里读环形缓冲区现数据的循环利用。

- 例如,发送如下命令:| | 发送字符串 | USART1_SendSt [[DISABLE_b02br("AT\r\n"); | 发 AT 指令、文本 |
4481]]
- 缓冲区需包含读写位置,便于数据重复利用。
参数说明
- **| 你手写笔记内容 | 本代码对应部分 || --- | -第一个参数:&uart1_rx_fifo**--- || UART_Write(char *buf,int 指定要读取的环形缓冲区(结构 len) | UART1_Write()函数,逻辑完全体指针)
- 只有串口一致 | | Tx_len = 1 的接收缓冲区,固定填 len; memcpy(xxx_buf,buf,len) |&uart1_rx_fifo
- 它不是存数据的,是 代码里uart1_tx_remain_len、`uart"指定缓冲区"
- 第二1_tx_buf | | 启动 Tx Empty 发送空中个参数:&rec_data`
- 指定读取数据断 | `__HAL_UART_ENABLE_IT(&huar存放的变量地址
- 函t1, UART_IT_TXE)| |UART_Tx_ISR()发送中断服务函数数从缓冲区读出 1 个字节,存 | HAL_UART_TxEmptyCallback()入 rec_data
for (;;)
`,逐字节写入寄存器发送 |
{
// 2| 接收数据 | 配套环形缓冲. 发送 AT 指令
USART1_SendStr("AT\r\n");
区接收中断,不丢包 |
| 串
// 3. 口 1 连 ESP8266、串处理串口数据
while(UART_FIFO_R口 2 打印 | 完全按你的硬eadByte(&uart1_rx_fifo, &data))
{
printf("%c", data);
}
/件分配实现 |
| 注释编码 |/ 4. 更新显示
Show_FIFO_Status();
全部 GB2312 简体中文 // 5. 延时
|
- 这是环形缓冲区相关的函数。
\[DISABLE vTaskDelay(pdMS_TO_TICKS(100_55053246\]
##0));
}
主函数实现与测试
- 在`- 这样即可实现 AT 指令的发送与反馈。
\[DISABmain.c\`中,先注释掉原有LE_2329ed2b\]
代码。
\[DISABLE_e--- ### 总结 通过以上流程,我1d19c6f\]
- 然后编写自己的实现。
\[DIS们可以实现 AT 指令的发送、ABLE_376b268c\]\]WiFi 连接、MQTT 通信及数据收发,为后续开发打下坚实
1. 编译并逐步调试,确保每基础。
步功能正常。

### 串口接收数据判断
1. 查阅手册可知,USART_SR_RXNE为1表示接收寄存器非空,USART_SR_RXNEIE为1表示接收中断已使能。两者同时满足即可读取数据。

1. 具体判断逻辑:

#### 串口1发送函数示例
// ====================== 串口1发送函数 ======================
// 功能:发送一串数据
void USART1_Send(uint8_t \*data, uint16_t len)
{
// 循环发送每一个字节
for(uint16_t i=0; i\