目录
[1. STA模式(Station模式)------常用](#1. STA模式(Station模式)------常用)
[2. AP模式(Access Point)](#2. AP模式(Access Point))
[二. AT指令(AT Command)](#二. AT指令(AT Command))
[1. 通讯使用](#1. 通讯使用)
[2. 常用AT指令介绍](#2. 常用AT指令介绍)
[2.1 测试指令](#2.1 测试指令)
[2.2 查询指令](#2.2 查询指令)
[2.3 设置指令](#2.3 设置指令)
[2.4 执行指令](#2.4 执行指令)
[1. 入网设置](#1. 入网设置)
[2. 连接服务器](#2. 连接服务器)
[3. 发送数据](#3. 发送数据)
[3.1 普通发送](#3.1 普通发送)
[3.2 透传发送------墙裂推荐](#3.2 透传发送------墙裂推荐)
[1. 配置成AP模式](#1. 配置成AP模式)
一.ESP8266工作模式
ESP8266支持STA, AP, STA+AP三种工作模式。
1. STA模式(Station模式)------常用
一般用于远距离传输。ESP8266通过路由器连接到互联网,终端设备通过互联网实现对设备的远程控制。ESP8266相当于一个客户端,可以向服务端进行数据的下载与传输。
类似于,手机/平板/笔记本(客户端)可以通过WIFI连接到路由器进行上网。
2. AP模式(Access Point)
一般用于近距离传输。ESP8266作为热点,提供无线接入服务、数据访问,一般的无线路由/网桥工作在AP模式下,最多支持4台设备接入。
简单来说,ESP8266此时可以当做一个服务端。此时ESP8266成为一个路由器,手机/平板/笔记本可以通过WIFI连接到ESP8266进行上网。
3.AP+STA模式
两种模式的共存模式,可以通过互联网控制实现无缝转换,方便操作。
ESP8266此时可以当作一个路由器既可以做服务端接收也可以当客户端连接路由器,进行联网传输和控制。
二. AT指令(AT Command)
1. 通讯使用
在嵌入式开发中,经常使用AT指令去开发各种通讯模块,eg:ESP8266、4G模块、GPRS模块等等。一般就是主芯片通过硬件接口(比如串口、SPI)发送AT指令给通讯模块,模块接收到数据之后回应响应的数据。
2. 常用AT指令介绍
2.1 测试指令
AT + <X> =?
测试终端设备或调制解调器的某些功能是否正常工作
2.2 查询指令
AT + <X> ?
返回参数的当前值
2.3 设置指令
AT + <X> = <...>
设置用户自定义的参数值
2.4 执行指令
AT + <X>
用于控制终端设备的具体操作
三.常用AT指令通过TCP连接到远程服务器实现收发数据示例
调试工具:安信可串口调试工具
百度网盘:通过网盘分享的文件:安信可调试工具
链接: https://pan.baidu.com/s/16lYVvQziJDcna95mG2Biww?pwd=x6b6 提取码: x6b6
--来自百度网盘超级会员v6的分享
|----------------------------------------|----------------------------------------------------|
| 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 | 开始发送数据 |
四.3种模式STM32连接
ESP8266作为设备
USB转TTL插入电脑,TX-RX RX-TX VCC-5v GND-GND
原理

PC和ESP8266由路由器建立连接,在PC端搭建一个TCP服务器就可以实现ESP8266与PC端通信。
1. 入网设置
a.设置工作模式
AT+CWMODE=1 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模
接收到的:AT+CWMODE=1
OK
b.以设备模式接入家中路由器配置
AT+CWJAP="HuaweiAP-1ED0_Guest","gcc111111" //指令
接收到的:WIFI CONNECTED
WIFI GOT IP
c.查询IP地址
AT+CIFSR //指令
接收到的:
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"4e:75:25:0d:ae:2f"
+CIFSR:STAIP,"192.168.0.148"
+CIFSR:STAMAC,"4c:75:25:0d:ae:2f"
OK
连接步骤
先查一下PC电脑IP, win+R-----cmd------ipconfig


ip:10.0.2.40 port(自己可以随便想一个):8080
2. 连接服务器
AT+CIPSTART="TCP","10.0.2.40",8080


连接成功yeah
3. 发送数据
两种方式,一种是就像串口通信那样数据长度+数据内容+巴拉巴拉,另一种方式是透传
3.1 普通发送
AT+CIPSEND=4 //设置即将发送数据的长度(这里是4个字节)
>abcd //看到大于号后,输入数据abcd,不要带回车
RESPONSE:SEND OK //结果:成功
//注意!这种情况下,每次发送前都要先发送AT+CIPSNED=长度的指令,再发数据
3.2 透传发送------墙裂推荐
这个可以随意发送数据
AT+CIPMODE=1 //开启透传模式
Response:OK
AT+CIPSEND //带回车
Response:> //这个时候就随意发送接收数据啦
退出透传模式
//在透传发送数据过程中,若识别到单独的一包数据"+++",则可退出透传模式

(取消勾选发送新行指令)
ESP8266作为服务器
USB转TTL插入电脑,TX-RX RX-TX VCC-5v GND-GND
查询IP地址:AT+CIFSR
1. 配置成AP模式
AT+CWMODE=2
Response:OK
2.使能多链接
AT+CIPMUX=1
Response:OK
3.建立TCPServer
AT+CIPSERVER=1,8888 //port = 8888(自己设定)
4.发送数据
AT+CIPSEND=0,4 //发送4个字节在连接0通道上
>abcd //看到大于号后,输入数据 abcd,不要带回车
RESPONSE:SEND OK //结果:成功
如果只有一个客户端第一个通道是0,第二个客户端是1,以此类推
5.接收数据
+IPD,0,n:xxxxxxxxx //+IPD是固定字符串,0是通道,n是数据长度,xxx是数据
6.断开连接
AT+CIPCLOSE=0
Response:0,CLOSED OK
五.STM32代码实现
1.ESP8266作为设备(正式代码按照这个来)
主要是看esp8266.c中esp8266_uart_init
测试8266是否存在------设置工作模式------设置单路链接模式------连接wifi
esp8266.h
objectivec
#ifndef __ESP8266_H__
#define __ESP8266_H__
#include "sys.h"
#define ESP8266_RX_BUF_SIZE 128
#define ESP8266_TX_BUF_SIZE 64
#define ESP8266_EOK 0
#define ESP8266_ERROR 1
#define ESP8266_ETIMEOUT 2
#define ESP8266_EINVAL 3
#define ESP8266_STA_MODE 1
#define ESP8266_AP_MODE 2
#define ESP8266_STA_AP_MODE 3
#define ESP8266_SINGLE_CONNECTION 0
#define ESP8266_MULT_CONNECTION 1
#define WIFI_SSID "LAswekasi"
#define WIFI_PWD "11111111"
void esp8266_init(uint32_t baudrate);
void esp8266__receive_data(void);
void esp8266_test(void);
#endif
esp8266.c
objectivec
#include "esp8266.h"
#include "stdio.h"
#include "string.h"
#include "delay.h"
uint8_t esp8266_rx_buf[ESP8266_RX_BUF_SIZE];
uint16_t esp8266_rx_len = 0;
uint16_t esp8266_cnt = 0, esp8266_cntPre = 0;
UART_HandleTypeDef esp8266_handle = {0};
void esp8266_uart_init(uint32_t baudrate)
{
esp8266_handle.Instance = USART2;
esp8266_handle.Init.BaudRate = baudrate;
esp8266_handle.Init.WordLength = UART_WORDLENGTH_8B;
esp8266_handle.Init.StopBits = UART_STOPBITS_1;
esp8266_handle.Init.Parity = UART_PARITY_NONE;
esp8266_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
esp8266_handle.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&esp8266_handle);
}
void esp8266_rx_clear(void)
{
memset(esp8266_rx_buf, 0, sizeof(esp8266_rx_buf));
esp8266_cnt = 0;
}
uint8_t esp8266_wait_receive(void)
{
if(esp8266_cnt == 0)
return ESP8266_ERROR;
if(esp8266_cnt == esp8266_cntPre)
{
esp8266_cnt = 0;
return ESP8266_EOK;
}
esp8266_cntPre = esp8266_cnt;
return ESP8266_ERROR;
}
uint8_t esp8266_send_command(char *cmd,char *res)
{
uint8_t time_out = 250;
esp8266_rx_clear();
HAL_UART_Transmit(&esp8266_handle, (uint8_t *)cmd, strlen(cmd),100);
while(time_out--)
{
if(esp8266_wait_receive()== ESP8266_EOK)
{
if(strstr((const char*)esp8266_rx_buf,res)!=NULL) //strstr()就是在一个大字符串里找一个小字符串,找到了就告诉你位置,找不到就返回空
{
return ESP8266_EOK;
}
}
delay_ms(10);
}
return ESP8266_ERROR;
}
uint8_t esp8266_at_test(void)
{
return esp8266_send_command("AT\r\n","OK");
}
uint8_t esp8266_set_mode(uint8_t mode)
{
switch(mode)
{
case ESP8266_STA_MODE:
return esp8266_send_command("AT+CWMODE=1\r\n","OK");
case ESP8266_AP_MODE:
return esp8266_send_command("AT+CWMODE=2\r\n","OK");
case ESP8266_STA_AP_MODE:
return esp8266_send_command("AT+CWMODE=3\r\n","OK");
default:
return ESP8266_EINVAL;
}
}
uint8_t esp8266_join_ap(char *ssid,char *pwd)
{
char cmd[64]; //构造一个字符串
sprintf(cmd,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid, pwd); //格式化字符串并输出到字符数组中
return esp8266_send_command(cmd,"WIFI GOT IP");
}
uint8_t esp8266_connection_mode(uint8_t mode)
{
char cmd[64];
sprintf(cmd,"AT+CIPMUX=%d\r\n",mode); //将格式化的数据写入一个字符串缓冲区,而不是打印到屏幕上
return esp8266_send_command(cmd,"OK");
}
void esp8266_init(uint32_t baudrate)
{
printf("esp8266初始化开始...\r\n");
esp8266_uart_init(baudrate);
//esp8266的其他初始化
printf("1.测试esp8266是否存在...\r\n");
while(esp8266_at_test())
delay_ms(500);
printf("2.设置工作模式为STA...\r\n");
while(esp8266_set_mode(ESP8266_STA_MODE))
delay_ms(500);
printf("3.设置单路链接模式...\r\n");
while(esp8266_connection_mode(ESP8266_SINGLE_CONNECTION))
delay_ms(500);
printf("4.连接wifi,SSID: %s, PWD: %s\r\n",WIFI_SSID,WIFI_PWD);
while(esp8266_join_ap(WIFI_SSID,WIFI_PWD))
delay_ms(1500);
printf("5.ESP8266初始化完成!\r\n");
}
void USART2_IRQHandler(void)
{
uint8_t receive_data = 0;
if(__HAL_UART_GET_FLAG(&esp8266_handle, UART_FLAG_RXNE) != RESET)
{
if(esp8266_cnt >= sizeof(esp8266_rx_buf))
esp8266_cnt = 0;
HAL_UART_Receive(&esp8266_handle, &receive_data, 1, 1000);
esp8266_rx_buf[esp8266_cnt++] = receive_data;
}
}
void esp8266_receive_data(void)
{
if(esp8266_wait_receive() == ESP8266_EOK)
{
printf("esp8266 recv: %s\r\n", esp8266_rx_buf);
esp8266_rx_clear();
}
}
void esp8266_test(void)
{
if(esp8266_send_command("AT","OK")== ESP8266_EOK)
{
printf("esp8266 test:%s\r\n",esp8266_rx_buf);
}
}
main.c
objectivec
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "esp8266.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
led_init(); /* 初始化LED灯 */
uart1_init(115200);
esp8266_init(115200);
while(1)
{
}
}