ESP8266基础
原理图
模式
-
STA:也称为站点模式或客户端模式,ESP8266在STA模式下可以连接到路由器或接入点(AP)的WiFi网络。这种模式允许ESP8266通过互联网进行远程控制和数据传输
-
AP:在这种模式下,ESP8266充当热点,为其他设备提供一个无线连接。其他设备可以连接到这个热点,实现局域网内的无线控制
-
STA+AP:这是STA模式和AP模式的结合,ESP82646既可以作为客户端连接到其他WiFi网络,同时也可以作为一个热点,提供无线连接给其他设备
AT指令
AT指令 | 功能 |
---|---|
AT | 测试是否正常启动 |
AT+CWMODE=1 | 设置 STA 模式 |
AT+CWMODE=2 | 设置 AP 模式 |
AT+CWMODE=3 | 设置 AP+STA 模式 |
AT+RST | 重启生效 |
AT+CWSAP=”SSID”,”password”,1,4 | 设置 AP 参数:账号为SSID ,密码为password,通道号为 1,加密方式为:WPA_WPA2_PSK |
AT+CIPMUX=0 | 开启单连接 |
AT+CIPMUX=1 | 开启多连接 |
AT+CIPSERVER=1,8080 | 开启 SERVER 模式,设置端口为 8080 |
AT+CIPSTART=”TCP”,”192.168.X.XXX”,8080 | 建立 TCP 连接到”192.168.X.XXX”,8080 |
AT+CIPSTART=”UDP”,”192.168.X.XXX”,8080 | 建立 UDP 连接到”192.168.X.XXX”,8080 |
AT+CIPCLOSE | 断开 TCP 连接 |
AT+CWQAP | 断开热点 |
AT+CIPSEND=n | 开始传输,n表示需要传输的字节数 |
AT+CIPSEND=0,n | 向 ID0 发送 n 字节数据包,n的值自己定 |
AT+CIPMODE=1 | 开启透传模式(直接发送数据) |
AT+CIPSEND | 开始发送数据 |
AT+CIPMODE=0 | 退出透传 |
AT+CWJAP=”SSID”,”password” | 加入 WIFI 热点:SSID ,密码为:password |
AT+CIFSR | 查询 ESP8266 的 IP 地址 |
AT+CIPSTA? | 查询 ESP8266 的 IP 、网关地址和子网掩码 |
代码
采用串口+DMA+空闲中断来接收数据
#ifndef _ESP8266_H_
#define _ESP8266_H_
#include "main.h"
#define WiFiName "wifi_name" //WiFi名称
#define WiFiPassword "wifi_password" //WiFi密码
#define IP "TCP_IP" //IP地址
#define PORT "8080" //端口
#define ESP8266_TIMEOUT 100000 //超时时间
#define ESP8266_RX_BUF_LEN 1024 //接收缓冲区大小
#define ESP8266_RX_MAX 256 //接收缓冲区最大值
extern uint8_t ESP8266_RX_BUF[ESP8266_RX_BUF_LEN]; //接收缓冲区
typedef enum
{
ESP8266_OK = 0,
ESP8266_Timeout,
ESP8266_Error,
ESP8266_RX_NOT_FULL
}ESP8266_Code; //返回值
typedef enum
{
false = 0,
true
}bool;
typedef enum
{
ESP8266_STATUS_IDEO = 0,
ESP8266_STATUS_AT,
ESP8266_STATUS_TX_RX
}ESP8266_STATUS; //用于判断当前是AT测试还是数据传输
extern ESP8266_STATUS ESP8266_Status ;
HAL_StatusTypeDef ESP8266_Init(void); //初始化
ESP8266_Code ESP8266_SendAT(char *atCode); //发送AT指令
#endif
#include "esp8266.h"
#include "usart.h"
#include "stdio.h"
#include "string.h"
uint8_t ESP8266_RX_BUF[ESP8266_RX_BUF_LEN] = {0}; // 接收缓存
bool ESP8266_RX_FLAG = false; // 接收完全标志
uint16_t ESP8266_RX_NUM = 0; // 接收数据长度
ESP8266_STATUS ESP8266_Status = ESP8266_STATUS_IDEO; // 状态
ESP8266_Code ESP8266_SendAT(char *atCode)
{
ESP8266_Status = ESP8266_STATUS_AT;
HAL_StatusTypeDef status = HAL_UART_Transmit(&huart2, (const uint8_t *)atCode, strlen(atCode),ESP8266_TIMEOUT);
if(status != HAL_OK) // 发送失败
{
return ESP8266_Error;
}
uint16_t time = 0;
while(ESP8266_RX_FLAG != true && time < ESP8266_TIMEOUT) // 等待接收完全
{
time++;
HAL_Delay(1);
}
//接收数据后的处理
ESP8266_RX_FLAG = false;
// ESP8266_Status = ESP8266_STATUS_IDEO;
// 超时处理
if(time >= ESP8266_TIMEOUT) // 超时
{
return ESP8266_Timeout;
}
return ESP8266_OK;
}
HAL_StatusTypeDef ESP8266_Init(void)
{
HAL_StatusTypeDef status = HAL_UARTEx_ReceiveToIdle_DMA(&huart2, ESP8266_RX_BUF, ESP8266_RX_MAX);
if(status != HAL_OK)
{
// Error 显示错误信息
}
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT); // 禁止DMA半传输中断
/* 开始发送AT指令 */
char atCode[50] ;
sprintf(atCode, "AT+CWJAP=\"%s\",\"%s\"\r\n", WiFiName, WiFiPassword);
// AT指令
if(ESP8266_SendAT("AT\r\n") == ESP8266_Timeout)
{
// AT测试失败
HAL_UART_Transmit(&huart1, "AT测试失败\r\n",sizeof( "AT测试失败\r\n"), ESP8266_TIMEOUT);
return HAL_ERROR;
}
//STA模式
if(ESP8266_SendAT("AT+CWMODE=1\r\n") != ESP8266_OK) // 设置为STA模式
{
// 设置失败
HAL_UART_Transmit(&huart1, "设置失败\r\n",sizeof( "设置失败\r\n"), ESP8266_TIMEOUT);
return HAL_ERROR;
}
// 连接WiFi
if(ESP8266_SendAT(atCode) != ESP8266_OK) // 连接WiFi
{
// 连接失败
HAL_UART_Transmit(&huart1, "连接WiFi失败\r\n",sizeof( "连接WiFi失败\r\n"), ESP8266_TIMEOUT);
return HAL_ERROR;
}
if(ESP8266_SendAT("AT+CIFSR\r\n") != ESP8266_OK) // 获取IP地址
{
// 获取失败
HAL_UART_Transmit(&huart1, "获取IP地址失败\r\n",sizeof( "获取IP地址失败\r\n"), ESP8266_TIMEOUT);
return HAL_ERROR;
}
//开启透传模式
if(ESP8266_SendAT("AT+CIPMODE=1\r\n") != ESP8266_OK) // 设置透传模式
{
// 设置失败
HAL_UART_Transmit(&huart1, "设置透传模式失败\r\n",sizeof( "设置透传模式失败\r\n"), ESP8266_TIMEOUT);
return HAL_ERROR;
}
sprintf(atCode, "AT+CIPSTART=\"TCP\",\"%s\",\"%s\"\r\n", IP, PORT);
if(ESP8266_SendAT(atCode) != ESP8266_OK) // 连接TCP
{
// 连接失败
HAL_UART_Transmit(&huart1, "连接TCP失败\r\n",sizeof( "连接TCP失败\r\n"), ESP8266_TIMEOUT);
return HAL_ERROR;
}
//显示连接成功
HAL_UART_Transmit(&huart1, "连接成功\r\n",sizeof( "连接成功\r\n"), ESP8266_TIMEOUT);
return HAL_OK;
}
//DMA+空闲中断
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance == USART2)
{
ESP8266_RX_NUM += Size; // 接收数据长度
if(ESP8266_RX_NUM + ESP8266_RX_MAX >= ESP8266_RX_BUF_LEN) // 超出接收缓存
{
ESP8266_RX_NUM = 0;
}
if(ESP8266_Status == ESP8266_STATUS_AT) // AT指令
{
if(strstr((char *)ESP8266_RX_BUF, "OK") != NULL)
{
ESP8266_RX_FLAG = true; // 接收完全
HAL_UART_Transmit(&huart1,ESP8266_RX_BUF, ESP8266_RX_NUM, ESP8266_TIMEOUT); // 发送接收到的数据
memset(ESP8266_RX_BUF, 0, ESP8266_RX_NUM); // 清空接收缓存
ESP8266_RX_NUM = 0; // 接收数据长度
}
else // 未完全接收
{
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, &ESP8266_RX_BUF[ESP8266_RX_NUM], ESP8266_RX_MAX); // 继续接收下一段数据
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
return;
}
}
else if(ESP8266_Status == ESP8266_STATUS_TX_RX)
{
// 正常传输数据的处理
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, ESP8266_RX_BUF, ESP8266_RX_MAX); //开启下一次接收
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
}
}