一、简介
这里对wifi的802.11协议中比较常见的知识做一个基本的总结和整理以及对ESP8266的使用,本篇文章适合新手学习,以及应对面试需要。
WiFi协议标准包括802.11a(第一代)、802.11n(第四代,同时运行在2.4Ghz和5Ghz双频段),802.11ac(第五代),而只有采用802.11ac协议的WiFi才是真正5G WiFi),第六代技术标准也就是我们俗称的wifi6,用的是802.11ax协议。
二、WIFI基本知识
1.常见术语
(1)LAN:即局域网,是路由和主机组成的内部局域网,一般为有线网络。
(2)WAN:即广域网,是外部一个更大的局域网。
(3)WLAN(Wireless LAN,即无线局域网):前面我们说过LAN是局域网,其实大多数指的是有线网络中的局域网,无线网络中的局域网,一般用WLAN。
(4)AP:全称 Wireless Access Point, 即无线AP,用来连接 STA 和 有线网络的网络设备。类似于手机热点。
(5)Station(STA):即工作站,是指配有无线网卡的无线终端,比如:手机、电脑等。
(6)Assosiate:连接。如果一个Station想要加入到无线网络中,需要和这个无线网络中的AP关联(即Assosiate)。
(7)SSID:用来标识一个无线网络,后面会详细介绍,我们这里只需了解,每个无线网络都有它自己的SSID。
(8)BSSID:用来标识一个BSS,其格式和MAC地址一样,是48位的地址格式。一般来说,它就是所处的无线接入点的MAC地址。某种程度来说,它的作用和SSID类似,但是SSID是网络的名字,是给人看的,BSSID是给机器看的,BSSID类似MAC地址。
2. Wi-Fi安全协议
Wi-Fi安全协议扮演着至关重要的角色,它们是网络世界的守护者,保护着我们的隐私和数据免受未经授权的访问和窃听。WEP、WPA、WPA2以及最新推出的WPA3。
(1)WEP:
WEP最早于1997年推出,是为了保护无线网络上的数据通信而设计的。当时,Wi-Fi技术还处于起步阶段,人们开始意识到需要一种安全协议来防止未经授权的访问和窃听。WEP被认为是一个里程碑,因为它是第一个为Wi-Fi网络提供安全保护的标准。WEP的工作原理是利用加密算法对无线网络传输的数据进行加密。它使用64位和128位的密钥来加密数据,并通过这些密钥来验证和解密数据包。WEP采用静态密钥,这意味着同一网络上的所有设备都使用相同的密钥进行通信。虽然这种方法可以确保消息内容对未经授权的用户来说是隐藏的,但它也正是WEP安全性的一个致命弱点。
(2)WPA:
WPA的发布是为了解决WEP存在的严重安全漏洞。WEP曾经是Wi-Fi网络最早采用的加密标准之一,但它的静态密钥和易受攻击的加密算法使得网络数据容易被窃取和篡改。WPA的问世填补了WEP的安全漏洞,并为无线网络提供了更可靠的保护。
(3)WPA2:
WPA2是一种无线安全协议,是WPA(Wi-Fi Protected Access)协议的升级版本。它于2004年推出,旨在提供更加安全的无线网络连接。WPA2采用了先进的加密标准和身份验证机制,以确保Wi-Fi网络的安全性和保密性。WPA2通过加密和身份验证机制来保护Wi-Fi网络的安全。当设备连接到受保护的Wi-Fi网络时,首先进行身份验证,确保只有授权用户才能访问网络。随后,数据通过AES加密算法进行加密,保证传输过程中的数据安全性。同时,WPA2还使用密码块链消息验证代码协议(CCMP)的计数器模式来验证数据的完整性,防止数据被篡改或损坏。
(4)WPA3
WPA3是Wi-Fi联盟于2018年发布的最新一代Wi-Fi安全协议。作为WPA2的后继者,WPA3旨在提供更强大的安全保护,解决WPA2中存在的一些安全漏洞和攻击手法,为个人和企业用户提供更安全的Wi-Fi连接。
WEP、WPA、WPA2以及WPA3 四者总结关系。
三、ESP8266简介
本次使用的是正点原子的串口WIFI模块。
ESP8266 是串口型 WIFI,速度比较低,不能用来传输图像或者视频这些大容量的数据,主要应用于数据量传输比较少的场合,比如温湿度信息,一些传感器的开关量等。
1.三种模式说明
ATK-MW8266D 模块支持三种工作模式,分别为: STA、 AP、 STA+AP。
(1)STA 模式
在此模式下, ATK-MW8266D 模块可连接其他设备提供的无线网络, 例如通过 WIFI 连接至路由器, 从而可以访问互联网,进而实现手机或电脑通过互联网实现对设备的远程控制。
(2)AP 模式
AP 模式为默认的模式,在此模式下, ATK-MW8266D 模块将作为热点供其他设备连接,从而让手机或电脑直接与模块进行通讯,实现局域网的无线控制。
(3)STA+AP 模式
该模式为 STA 模式与 AP 模式共存的一种模式, ATK-MW8266D 模块既能连接至其他设备提供的无线网络,又能作为热点,供其他设备连接,以实现广域网与局域网的无缝切换,方便操作使用。除了上述的三种工作模式外, ATK-MW8266D 模块在进行 UDP 连接或作为 TCP 客户端连接时,能够进入透传模式,进入透传模式后, ATK-MW8266D 将会原封不动地把从 TCP服务器或其他 UDP 终端接收到的消息,通过 UART 发送至与之连接的设备。
2.重要概念
透传,即透明传输功能。Host 通过 uart 将数据发给 ESP8266,ESP8266 再通过无线网络将数据传出去;ESP8266 通过无线网络接收到的数据。ESP8266 只负责将数据传到目标地址,不对数据进行处理,发送方和接收方的数据内容、长度完全一致,传输过程就好像透明一样。
TCP/UDP通信,可以在B站上面了解。
3.常用指令集
ESP8266指令集:
AT+RESTORE 恢复出厂设置
AT+CIPCLOSE 关闭 TCP 连接、 UDP 传输或 SSL 连接
AT+CWMODE=1
AT+RST
AT+CWJAP="guilin88","12345678"
AT+CIPMUX=0 开启单连接
AT+CIPSTART="TCP","192.168.147.95",6688 建立 TCP 连接到 192.168.4.XXX:8086
AT+CIPMODE=1 开启透传模式(仅单连接 Client 时支持)
AT+CIPSEND 开始发送数据
四、代码编写
1.atk_mw8266d.c
#include "atk_mw8266d.h"
#include "main.h"
#include <string.h>
#include <stdio.h>
#include <usart.h>
/**
* @brief ATK-MW8266D硬件初始化
* @param 无
* @retval 无
*/
static void atk_mw8266d_hw_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
ATK_MW8266D_RST_GPIO_CLK_ENABLE();
gpio_init_struct.Pin = ATK_MW8266D_RST_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Pull = GPIO_NOPULL;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(ATK_MW8266D_RST_GPIO_PORT, &gpio_init_struct);
}
/**
* @brief ATK-MW8266D硬件复位
* @param 无
* @retval 无
*/
void atk_mw8266d_hw_reset(void)
{
ATK_MW8266D_RST(0);
HAL_Delay(100);
ATK_MW8266D_RST(1);
HAL_Delay(500);
}
//自己写的发送指令函数
uint8_t atk_mw8266d_send_at_cmd(char *cmd, char *ack, uint32_t timeout)
{
atk_mw8266d_uart_printf("%s\r\n", cmd);
return ATK_MW8266D_EOK;
}
/**
* @brief ATK-MW8266D初始化
* @param baudrate: ATK-MW8266D UART通讯波特率
* @retval ATK_MW8266D_EOK : ATK-MW8266D初始化成功,函数执行成功
* ATK_MW8266D_ERROR: ATK-MW8266D初始化失败,函数执行失败
*/
uint8_t atk_mw8266d_init(uint32_t baudrate)
{
atk_mw8266d_hw_init(); /* ATK-MW8266D硬件初始化 */
atk_mw8266d_hw_reset(); /* ATK-MW8266D硬件复位 */
atk_mw8266d_uart_init(baudrate); /* ATK-MW8266D UART初始化 */
//printf("开始AT测试指令...");
if (atk_mw8266d_at_test() != ATK_MW8266D_EOK) /* ATK-MW8266D AT指令测试 */
{
return ATK_MW8266D_ERROR;
}
return ATK_MW8266D_EOK;
}
/**
* @brief ATK-MW8266D恢复出厂设置
* @param 无
* @retval ATK_MW8266D_EOK : 恢复出场设置成功
* ATK_MW8266D_ERROR: 恢复出场设置失败
*/
uint8_t atk_mw8266d_restore(void)
{
uint8_t ret;
ret = atk_mw8266d_send_at_cmd("AT+RESTORE", "ready", 3000);
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D AT指令测试
* @param 无
* @retval ATK_MW8266D_EOK : AT指令测试成功
* ATK_MW8266D_ERROR: AT指令测试失败
*/
uint8_t atk_mw8266d_at_test(void)
{
uint8_t ret;
uint8_t i;
for (i=0; i<2; i++)
{
ret = atk_mw8266d_send_at_cmd("AT", "OK", 500);
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
}
return ATK_MW8266D_ERROR;
}
/**
* @brief 设置ATK-MW8266D工作模式
* @param mode: 1,Station模式
* 2,AP模式
* 3,AP+Station模式
* @retval ATK_MW8266D_EOK : 工作模式设置成功
* ATK_MW8266D_ERROR : 工作模式设置失败
* ATK_MW8266D_EINVAL: mode参数错误,工作模式设置失败
*/
uint8_t atk_mw8266d_set_mode(uint8_t mode)
{
uint8_t ret;
switch (mode)
{
case 1:
{
ret = atk_mw8266d_send_at_cmd("AT+CWMODE=1", "OK", 500); /* Station模式 */
break;
}
case 2:
{
ret = atk_mw8266d_send_at_cmd("AT+CWMODE=2", "OK", 500); /* AP模式 */
break;
}
case 3:
{
ret = atk_mw8266d_send_at_cmd("AT+CWMODE=3", "OK", 500); /* AP+Station模式 */
break;
}
default:
{
return ATK_MW8266D_EINVAL;
}
}
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D软件复位
* @param 无
* @retval ATK_MW8266D_EOK : 软件复位成功
* ATK_MW8266D_ERROR: 软件复位失败
*/
uint8_t atk_mw8266d_sw_reset(void)
{
uint8_t ret;
ret = atk_mw8266d_send_at_cmd("AT+RST", "OK", 500);
if (ret == ATK_MW8266D_EOK)
{
HAL_Delay(1000);
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D设置回显模式
* @param cfg: 0,关闭回显
* 1,打开回显
* @retval ATK_MW8266D_EOK : 设置回显模式成功
* ATK_MW8266D_ERROR: 设置回显模式失败
*/
uint8_t atk_mw8266d_ate_config(uint8_t cfg)
{
uint8_t ret;
switch (cfg)
{
case 0:
{
ret = atk_mw8266d_send_at_cmd("ATE0", "OK", 500); /* 关闭回显 */
break;
}
case 1:
{
ret = atk_mw8266d_send_at_cmd("ATE1", "OK", 500); /* 打开回显 */
break;
}
default:
{
return ATK_MW8266D_EINVAL;
}
}
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D连接WIFI
* @param ssid: WIFI名称
* pwd : WIFI密码
* @retval ATK_MW8266D_EOK : WIFI连接成功
* ATK_MW8266D_ERROR: WIFI连接失败
*/
uint8_t atk_mw8266d_join_ap(char *ssid, char *pwd)
{
uint8_t ret;
char cmd[64];
sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"", ssid, pwd);
ret = atk_mw8266d_send_at_cmd(cmd, "WIFI GOT IP", 10000);
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D获取IP地址
* @param buf: IP地址,需要16字节内存空间
* @retval ATK_MW8266D_EOK : 获取IP地址成功
* ATK_MW8266D_ERROR: 获取IP地址失败
*/
uint8_t atk_mw8266d_get_ip(char *buf)
{
uint8_t ret;
char *p_start;
char *p_end;
ret = atk_mw8266d_send_at_cmd("AT+CIFSR", "OK", 500);
if (ret != ATK_MW8266D_EOK)
{
return ATK_MW8266D_ERROR;
}
p_start = strstr((const char *)atk_mw8266d_uart_rx_get_frame(), "\"");
p_end = strstr(p_start + 1, "\"");
*p_end = '\0';
sprintf(buf, "%s", p_start + 1);
return ATK_MW8266D_EOK;
}
/**
* @brief ATK-MW8266D连接TCP服务器
* @param server_ip : TCP服务器IP地址
* server_port: TCP服务器端口号
* @retval ATK_MW8266D_EOK : 连接TCP服务器成功
* ATK_MW8266D_ERROR: 连接TCP服务器失败
*/
uint8_t atk_mw8266d_connect_tcp_server(char *server_ip, char *server_port)
{
uint8_t ret;
char cmd[64];
sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%s", server_ip, server_port);
ret = atk_mw8266d_send_at_cmd(cmd, "CONNECT", 5000);
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D进入透传
* @param 无
* @retval ATK_MW8266D_EOK : 进入透传成功
* ATK_MW8266D_ERROR: 进入透传失败
*/
uint8_t atk_mw8266d_enter_unvarnished(void)
{
uint8_t ret;
ret = atk_mw8266d_send_at_cmd("AT+CIPMODE=1", "OK", 500);
ret += atk_mw8266d_send_at_cmd("AT+CIPSEND", ">", 500);
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D退出透传
* @param 无
* @retval 无
*/
void atk_mw8266d_exit_unvarnished(void)
{
atk_mw8266d_uart_printf("+++");
}
/**
* @brief ATK-MW8266D连接原子云服务器
* @param id : 原子云设备编号
* pwd: 原子云设备密码
* @retval ATK_MW8266D_EOK : 连接原子云服务器成功
* ATK_MW8266D_ERROR: 连接原子云服务器失败
*/
uint8_t atk_mw8266d_connect_atkcld(char *id, char *pwd)
{
uint8_t ret;
char cmd[64];
sprintf(cmd, "AT+ATKCLDSTA=\"%s\",\"%s\"", id, pwd);
ret = atk_mw8266d_send_at_cmd(cmd, "CLOUD CONNECTED", 10000);
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
/**
* @brief ATK-MW8266D断开原子云服务器连接
* @param 无
* @retval ATK_MW8266D_EOK : 断开原子云服务器连接成功
* ATK_MW8266D_ERROR: 断开原子云服务器连接失败
*/
uint8_t atk_mw8266d_disconnect_atkcld(void)
{
uint8_t ret;
ret = atk_mw8266d_send_at_cmd("AT+ATKCLDCLS", "CLOUD DISCONNECT", 500);
if (ret == ATK_MW8266D_EOK)
{
return ATK_MW8266D_EOK;
}
else
{
return ATK_MW8266D_ERROR;
}
}
2.atk_mw8266d_usart.c
#include "atk_mw8266d_usart.h"
#include "usart.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
static UART_HandleTypeDef g_uart_handle; /* ATK-MW8266D UART */
static struct
{
uint8_t buf[ATK_MW8266D_UART_RX_BUF_SIZE]; /* 帧接收缓冲 */
struct
{
uint16_t len : 15; /* 帧接收长度,sta[14:0] */
uint16_t finsh : 1; /* 帧接收完成标志,sta[15] */
} sta; /* 帧状态信息 */
} g_uart_rx_frame = {0}; /* ATK-MW8266D UART接收帧缓冲信息结构体 */
static uint8_t g_uart_tx_buf[ATK_MW8266D_UART_TX_BUF_SIZE]; /* ATK-MW8266D UART发送缓冲 */
/**
* @brief ATK-MW8266D UART printf
* @param fmt: 待打印的数据
* @retval 无
*/
void atk_mw8266d_uart_printf(char *fmt, ...)
{
va_list ap;
uint16_t len;
va_start(ap, fmt);
vsprintf((char *)g_uart_tx_buf, fmt, ap);
va_end(ap);
len = strlen((const char *)g_uart_tx_buf);
// HAL_UART_Transmit(&g_uart_handle, g_uart_tx_buf, len, HAL_MAX_DELAY);
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)g_uart_tx_buf, len);
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)g_uart_tx_buf, len);
}
/**
* @brief ATK-MW8266D UART重新开始接收数据
* @param 无
* @retval 无
*/
void atk_mw8266d_uart_rx_restart(void)
{
g_uart_rx_frame.sta.len = 0;
g_uart_rx_frame.sta.finsh = 0;
}
/**
* @brief 获取ATK-MW8266D UART接收到的一帧数据
* @param 无
* @retval NULL: 未接收到一帧数据
* 其他: 接收到的一帧数据
*/
uint8_t *atk_mw8266d_uart_rx_get_frame(void)
{
if (g_uart_rx_frame.sta.finsh == 1)
{
g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = '\0';
return g_uart_rx_frame.buf;
}
else
{
return NULL;
}
}
/**
* @brief 获取ATK-MW8266D UART接收到的一帧数据的长度
* @param 无
* @retval 0 : 未接收到一帧数据
* 其他: 接收到的一帧数据的长度
*/
uint16_t atk_mw8266d_uart_rx_get_frame_len(void)
{
if (g_uart_rx_frame.sta.finsh == 1)
{
return g_uart_rx_frame.sta.len;
}
else
{
return 0;
}
}
/**
* @brief ATK-MW8266D UART初始化
* @param baudrate: UART通讯波特率
* @retval 无
*/
void atk_mw8266d_uart_init(uint32_t baudrate)
{
g_uart_handle.Instance = ATK_MW8266D_UART_INTERFACE; /* ATK-MW8266D UART */
g_uart_handle.Init.BaudRate = baudrate; /* 波特率 */
g_uart_handle.Init.WordLength = UART_WORDLENGTH_8B; /* 数据位 */
g_uart_handle.Init.StopBits = UART_STOPBITS_1; /* 停止位 */
g_uart_handle.Init.Parity = UART_PARITY_NONE; /* 校验位 */
g_uart_handle.Init.Mode = UART_MODE_TX_RX; /* 收发模式 */
g_uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; /* 无硬件流控 */
g_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16; /* 过采样 */
HAL_UART_Init(&g_uart_handle); /* 使能ATK-MW8266D UART
* HAL_UART_Init()会调用函数HAL_UART_MspInit()
* 该函数定义在文件usart.c中
*/
}
/**
* @brief ATK-MW8266D UART中断回调函数
* @param 无
* @retval 无
*/
void ATK_MW8266D_UART_IRQHandler(void)
{
uint8_t tmp;
if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_ORE) != RESET) /* UART接收过载错误中断 */
{
__HAL_UART_CLEAR_OREFLAG(&g_uart_handle); /* 清除接收过载错误中断标志 */
(void)g_uart_handle.Instance->ISR; /* I先读SR寄存器,再读RDR寄存器 */
(void)g_uart_handle.Instance->RDR;
}
if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_RXNE) != RESET) /* UART接收中断 */
{
HAL_UART_Receive(&g_uart_handle, &tmp, 1, HAL_MAX_DELAY); /* UART接收数据 */
if (g_uart_rx_frame.sta.len < (ATK_MW8266D_UART_RX_BUF_SIZE - 1)) /* 判断UART接收缓冲是否溢出
* 留出一位给结束符'\0'
*/
{
g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = tmp; /* 将接收到的数据写入缓冲 */
g_uart_rx_frame.sta.len++; /* 更新接收到的数据长度 */
}
else /* UART接收缓冲溢出 */
{
g_uart_rx_frame.sta.len = 0; /* 覆盖之前收到的数据 */
g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = tmp; /* 将接收到的数据写入缓冲 */
g_uart_rx_frame.sta.len++; /* 更新接收到的数据长度 */
}
}
if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_IDLE) != RESET) /* UART总线空闲中断 */
{
g_uart_rx_frame.sta.finsh = 1; /* 标记帧接收完成 */
HAL_UART_Transmit_DMA(&huart1, g_uart_rx_frame.buf, sizeof(g_uart_rx_frame.buf));
__HAL_UART_CLEAR_IDLEFLAG(&g_uart_handle); /* 清除UART总线空闲中断 */
}
}
3.功能编辑
#include "myTask_ATK8266D.h"
#include "atk_mw8266d.h"
#include "usart.h"
#include "main.h"
#include "stdio.h"
#include "string.h"
#define DEMO_WIFI_SSID "guilin88"
#define DEMO_WIFI_PWD "12345678"
#define DEMO_TCP_SERVER_IP "192.168.1.3"
#define DEMO_TCP_SERVER_PORT "8080"
// static uint8_t AT_RESTORE[] = "AT+RESTORE\r\n"; //恢复出厂设置
// static uint8_t AT[] = "AT\r\n";//检查指令
// static uint8_t AT_MODESTA[] = "AT+CWMODE=1\r\n";//设置为STA模式
// static uint8_t AT_RST[] = "AT+RST\r\n";//重启生效
//连接WIFI的名称和密码
static uint8_t AT_JAP[] = "AT+CWJAP=\"guilin88\",\"12345678\"\r\n";//连接WIFI名称和密码,
static uint8_t AT_MUX0[] = "AT+CIPMUX=0\r\n";//开启单链接
static uint8_t AT_START[] = "AT+CIPSTART=\"TCP\",\"192.168.147.95\",6688\r\n";//建立TCP连接
static uint8_t AT_CIPMODE1[] = "AT+CIPMODE=1\r\n";//开启透传模式命令
static uint8_t AT_SEND[] = "AT+CIPSEND\r\n";//开始传输命令
// static uint8_t AT_QUIT[] = "+++"; //退出透传
void myTask_ATK8266D(void)
{
// printf("正在进入STA模式下的透传...\r\n");
// printf("发送的指令是:");
// // 1.恢复出厂设置
// //printf("发送的指令是:");
// HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_RESTORE, sizeof(AT_RESTORE));
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_RESTORE, sizeof(AT_RESTORE));
// HAL_Delay(2000);
// // 2.检查指令
// printf("发送的指令是:");
// HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT, sizeof(AT));
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT, sizeof(AT));
// HAL_Delay(2000);
// // 3.设置为STA模式
// printf("发送的指令是:");
// HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_MODESTA, sizeof(AT_MODESTA));
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_MODESTA, sizeof(AT_MODESTA));
// HAL_Delay(2000);
// HAL_Delay(2000);
// // 4.重启生效
// printf("发送的指令是:");
// HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_RST, sizeof(AT_RST));
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_RST, sizeof(AT_RST));
//
// HAL_Delay(2000);
// HAL_Delay(1000);
// HAL_Delay(1000);
// 5.连接WIFI的名称和密码
printf("发送的指令是:");
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_JAP, sizeof(AT_JAP));
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_JAP, sizeof(AT_JAP));
HAL_Delay(2000);
HAL_Delay(2000);
HAL_Delay(2000);
HAL_Delay(2000);
HAL_Delay(2000);
// 6.开启单链接
printf("发送的指令是:");
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_MUX0, sizeof(AT_MUX0));
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_MUX0, sizeof(AT_MUX0));
HAL_Delay(1000);
// 7.建立TCP连接
printf("发送的指令是:");
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_START, sizeof(AT_START));
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_START, sizeof(AT_START));
HAL_Delay(1000);
HAL_Delay(1000);
// 8.开启透传模式命令
printf("发送的指令是:");
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_CIPMODE1, sizeof(AT_CIPMODE1));
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_CIPMODE1, sizeof(AT_CIPMODE1));
HAL_Delay(1000);
// 9.开始传输命令
//while(strstr((const char *)ATCmdRxBuffer, "<") == NULL){
printf("发送的指令是:");
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)AT_SEND, sizeof(AT_SEND));
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)AT_SEND, sizeof(AT_SEND));
HAL_Delay(1000);
}
参考正点原子,附源代码。