低功耗串口WiFi模块ESP8266内置一个Tensilica(泰思立达) Xtensa架构的32位处理器L106,具有5级流水线(ARM CortexM3是3级流水线),最大时钟速度为160MHz,可以使用高达16MB的外部SPI Flash。 该模块采用串口与MCU(或其他串口设备)通信,内置 TCP/IP协议栈,能够实现串口与 WIFI 之间的转换。通过该模块,传统的串口设备只需要简单的串口配置,即可通过WiFi传输自己的数据。
wifi模块具有两种模式:AP模式 、Station模式
AP模式:就是我们平常用的热点,如无线路由器,手机热点。
Station模式:就是我们连接这些热点的设备,如手机,iPad,笔记本电脑。
我们想要与esp8266wifi模块进行通信,那么就需要AT命令进行。就好比我们要和英国国人进行交流时,我们就要用英语交流。在这里,就需要用到esp8266的AT指令进行和pc之间的通信。
AT 即Attention,它由拨号调制解调器(Modem)的发明者贺氏公司(Hayes)为了控制Modem发明的控制协议。协议本身采用文本,每个命令均以AT打头,因此得名。90年代初,AT指令仅被用于Modem操作。
几年后,主要的移动电话生产厂商诺基亚、爱立信、摩托罗拉和HP共同为GSM 研制了一整套AT指令,其中就包括对SMS的控制。AT指令在此基础上演化并被加入GSM 07.05标准以及现在的GSM07.07标准,其中拨打电话、收发短信、收发传真等全部由AT命令实现。而在随后的GPRS控制,3G模块,以及工业上常用的PDU,均采用AT命令集来控制,这样AT指令也就成为了完全标准化和比较健全的标准。
AT指令是以AT作为开头,\r\n字符结束的字符串,每个指令执行成功与否都有相应的返回。其他的一些非预期的信息(如有人拨号进来、线路无信号等),模块将有对应的一些信息提示,接收端可做相应的处理。
注意:不同模块的AT命令可能不一样的,这要对着模块的AT指令手册来查看。可以通过esp8266应答的信息来判断你们之间是否建立通信了。(每当发送一个AT指令之后,相应地就会在结尾给PC发 OK或者ERROR)
这里讲解一下我们ESP8266 01S常用的AT指令:
重启、复位ESP8266命令
AT确认模块是否正常工作
设置WiFi为Station模式和使能DHCP服务
输入路由器连接密码” 连接无线路由器
设置端口8080
#include "My_esp8266.h"
#include "string.h"
#include "usart.h"
void u2_printf(char* fmt);
char esp8266_send_cmd(char *cmd,char *ack,u16 waittime);
void esp8266_test(void)//测试
{
if(esp8266_send_cmd("AT","OK",50));
}
char esp8266_send_cmd(char *cmd,char *ack,u16 waittime)//发送指令和检查接收
{
u2_printf(cmd);
if(ack&&waittime)
{
while(--waittime)
{
HAL_Delay(10);
if(strstr((const char*)RxBuffer,(const char*)ack)) //输入on,LED0亮
{
Uart2_Rx_Cnt=0;
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
return 1;
}
}
}
return 0;
}
void esp8266_start_trans(void)//ESP8266初始化
{
esp8266_send_cmd("AT+CWMODE=2","OK",50);//设置为AP模式
esp8266_send_cmd("AT+RST","ready",20);//重启
HAL_Delay(1000);
HAL_Delay(1000);
HAL_Delay(1000);
HAL_Delay(1000);
esp8266_send_cmd("AT+CWSAP=\"ESP8266\",\"12345678\",1,4","OK",200);//设置WiFi名称、密码,模式
esp8266_send_cmd("AT+CIPMUX=1","OK",20);//进入透传模式
esp8266_send_cmd("AT+CIPSERVER=1,8080","OK",200);//设置端口8080
esp8266_send_cmd("AT+CIPSEND","OK",50);//开始发送数据
}
uint8_t esp8266_quit_trans(void)//退出透传模式
{
uint8_t result=1;
u2_printf("+++");
HAL_Delay(1000);
result=esp8266_send_cmd("AT","OK",20);
return result;
}
void u2_printf(char* fmt)
{
uint8_t num=0;
char my_ch[50]={0};
while(*fmt!=0)
my_ch[num++]=*fmt++;
my_ch[num++]='\r';
my_ch[num++]='\n';
HAL_UART_Transmit(&huart2, (uint8_t *)my_ch,num, 0xffff);
while(HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX);
}
#ifndef __My_esp8266_H__
#define __My_esp8266_H__
#include "main.h"
typedef uint16_t u16 ;
extern void esp8266_test(void);
extern void u2_printf(char* fmt);
extern char esp8266_send_cmd(char *cmd,char *ack,u16 waittime);
extern void esp8266_start_trans(void);
#endif
/* USER CODE BEGIN ET */
extern char RxBuffer[256];
extern uint8_t Uart2_Rx_Cnt;
/* USER CODE END ET */
/* USER CODE BEGIN Includes */
#include
#include "My_esp8266.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
#define RXBUFFERSIZE 256 //最大接收字节数
char RxBuffer[RXBUFFERSIZE]; //接收数据
uint8_t aRxBuffer; //接收中断缓冲
uint8_t Uart2_Rx_Cnt = 0; //接收缓冲计数
uint8_t my_test_v = 0 ;
char my_order[15]={0};
char receive_flag=0;
/* USER CODE END PV */
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
if(Uart2_Rx_Cnt >= 255) //溢出判断
{
Uart2_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
}
else
{
static uint8_t Uart2_count=0;
RxBuffer[Uart2_Rx_Cnt] = aRxBuffer; //接收数据转存
if(receive_flag==0)
{
if(RxBuffer[Uart2_Rx_Cnt-Uart2_count]=='<')
{
Uart2_count++;
if((RxBuffer[Uart2_Rx_Cnt]=='>')||Uart2_count>=14)
{
uint8_t My_i=0;
for(int i=Uart2_Rx_Cnt-Uart2_count+1;i
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);
esp8266_start_trans();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// HAL_Delay(20);
if(receive_flag)
{
receive_flag=0;
if(strstr((const char*)my_order,(const char*)"")) //输入on,LED0亮
{
Uart2_Rx_Cnt=0;
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
memset(RxBuffer,0x00,sizeof(my_order)); //清空数组
my_test_v=1;
}
else if(strstr((const char*)my_order,(const char*)""))
{
Uart2_Rx_Cnt=0;
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
memset(RxBuffer,0x00,sizeof(my_order)); //清空数组
my_test_v=0;
}
else
{
Uart2_Rx_Cnt=0;
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
memset(RxBuffer,0x00,sizeof(my_order)); //清空数组
}
}
if(my_test_v==1)
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
else
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET );
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
1.esp8266和核心板的连接只需要四个引脚,vcc(3.7—5v的稳定电源,不稳定的话会不断重启),gnd,rx,tx。其中,模块的rx接核心板的tx,tx接核心板的rx。
2. 初始化(4s)后,模块就会发出名字为esp8266的热点,密码为12345678。
3 手机接入后打开“tcp连接”app(这个热点没有网络,有些手机连接后一会儿后自动就断开了,所以要设置下,我是直接把数据流量关了就行了)
4 连接(IP地址一般是192.168.4.1不正确的话需要用串口助手给wifi模块发送AT指令查看连接设备的地址,当然也可以程序上发送后在线调试看数组)
5 发送数据,记住要加英文输入法的“<>”,就能控制灯的亮灭了。
需要注意的是,esp8266wifi模块相当于一个下好程序的核心板,你只需要通过给它发送串口的AT指令来进行控制它的各种动作。初始化也不是对引脚初始化,是通过串口对它发送AT指令。所以初始化后如果不给esp8266断电的话是不用再次初始化的,因为每次初始化后重启会话4s的时间,所以想不断下程序来调试的话,可以把初始化函数(esp8266_start_trans();)注释了,就不用每次都额外等4s的时间了。