用两个stm32实现ESP8266_01s的串口通信

两个ESP8266一个作为服务器一个作为客户端实现互相通讯

  1. 前言

看到网上用遥控器控制小车的视频感觉非常酷,刚好对ESP8266_01s这款mini的无线模块情有独钟(性价比非常高),之前一直使用arduino对这块板子进行物联网的设计,可以说是物联网的yyds了。除此之外还可以用AT指令对其进行配置,让两块板子进行通信。

2.思路

  1. 做什么:单片机 控制 ESP8266_01s。

  1. 怎么做:a.STM32核心板提供ESP8266_01s所需要的硬件环境;
     b.程序中写好特定格式的命令,通过串口发送给ESP8266_01s。

用两个stm32实现ESP8266_01s的串口通信_第1张图片

3.硬件

stm32f103c8t6

用两个stm32实现ESP8266_01s的串口通信_第2张图片

esp8266_01s

用两个stm32实现ESP8266_01s的串口通信_第3张图片

双轴按键摇杆

用两个stm32实现ESP8266_01s的串口通信_第4张图片

4.软件

先利用电脑通过串口发送信息给 ESP8266_01s模块,熟悉一下流程。

选择正确的 COM 号(WIFI与你电脑相连的串口),然后设置波特率为 115200,勾选发送新行 (必选!即自动添加回车换行功能)然后发送 AT指令 到 ESP8266_01s模块。

然后理清楚一下服务器(主机)和客户端(从机)分别需要执行什么AT指令。

服务器(主机)

AT指令

客户端(从机)

AT指令

检测模块是否在线

AT

检测模块是否在线

AT

修改服务器WIFI名和密码

AT+CWSAP=“esp8266_01s”,“a1234567”,11,3

设置 WIFI 模式1

AT+CWMODE=1

设置 WIFI 模式2

AT+CWMODE=2

重启生效

AT+RST

重启生效

AT+RST

连接服务器的WIFI

AT+CWJAP=“esp8266_01s”,“a1234567”

建立服务器指令

AT+CIPSERVER=1,8089

连接服务器

AT+CIPSTART=“TCP”,“你的服务器 IP 地址”,8089

获取服务器IP地址

AT+CIFSR

开启透传模式

AT+CIPMODE=1

开始透传

AT+CIPSEND

  1. 利用串口调试助手发送'AT'指令给它,它会返回'OK'的响应。如果没有响应有可能是固件的问题,需要重新刷一下原厂的固件,原厂默认是'AT'指令固件一般可以直接用。如果要开启透传模式需要刷入透传模式的固件才可以使用,固件包可以到安可信官网进行下载。

  1. 关于AT指令的使用细则网上已经有很多资料,我不再赘述,可以参考这篇文章 (2条消息) 两个ESP8266相互通信_点灯大师~的博客-CSDN博客

  1. 在我进行‘AT’指令进行数据传输时只有客户端可以开启透传模式,服务端怎么也开不起来,有懂的大佬可以在评论区指点一下

完成了esp8266与电脑的串口通信我们就可以尝试用单片机与它进行通信

服务端代码

//ESP8266服务端
void esp8266_server(void)
{
    //设置工作模式 1: station模式 2:AP模式 3:兼容AP+station模式
    esp8266_send_cmd("AT+CWMODE=3","OK",50);
    
    //让WiFi模块重启
    esp8266_send_cmd("AT+RST","ready",20);
    
    delay_ms(1000);         //延时等待重启
    delay_ms(1000);
    delay_ms(1000);
    delay_ms(1000);
    
    //0:单路连接模式 1:多路连接模式
    esp8266_send_cmd("AT+CIPMUX=1","OK",20);
    //建立服务器server指令
    esp8266_send_cmd("AT+CIPSERVER=1,8089","OK",20);
    /修改无线名字和密码指令
    esp8266_send_cmd("AT+CWSAP=\"ONE-ETA\",\"a1234567\",11,3","OK",20);
}


//向esp8266发送命令
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
    u8 res=0; 
    USART3_RX_STA=0;
    u3_printf("%s\r\n",cmd);    //发送命令
    if(ack&&waittime)        //需要等待应答
    {
        while(--waittime)    //等待倒计时
        {
            delay_ms(10);
            if(USART3_RX_STA&0X8000)//接收期待应答结果
            {
                if(esp8266_check_cmd(ack))
                {
                    printf("ack:%s\r\n",(u8*)ack);
                    break;//得到有效数据
                }
                    USART3_RX_STA=0;
            } 
        }
        if(waittime==0)res=1; 
    }
    return res;
} 


//ESP8266发送命令后,检测收到的应答
u8* esp8266_check_cmd(u8 *str)
{
    char *strx=0;
    if(USART3_RX_STA&0X8000)        //接收的第一次数据
    { 
        USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
        strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
    } 
    return (u8*)strx;
}


//向esp8266发送数据
u8* esp8266_send_data(u8 *cmd,u16 waittime)
{
    char temp[5];
    char *ack=temp;
    USART3_RX_STA=0;
    u3_printf("%s",cmd);    //发送命令
    if(waittime)        //需要等待应答
    {
        while(--waittime)    //等待倒计时
        {
            delay_ms(10);
            if(USART3_RX_STA&0X8000)//接收期待的应答结果
            {
                USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
                ack=(char*)USART3_RX_BUF;
                printf("ack:%s\r\n",(u8*)ack);
                USART3_RX_STA=0;
                break;//得到有效数据
            } 
        }
    }
    return (u8*)ack;
} 

客户端代码

//ESP8266模块和PC进入透传模式
void esp8266_start_trans(void)
{
   //设置工作模式 1: station模式 2:AP模式 3:兼容AP+station模式
    esp8266_send_cmd("AT+CWMODE=1","OK",50);
    
    //让WiFi模块重启
    esp8266_send_cmd("AT+RST","ready",20);
    
    Delay_ms(1000);         //ÑÓʱ3SµÈ´ýÖØÆô³É¹¦
    Delay_ms(1000);
    Delay_ms(1000);
    Delay_ms(1000);
    
    //让模块连接上自己的路由器
    (esp8266_send_cmd("AT+CWJAP=\"hao\",\"h123456.\"","WIFI GOT IP",600));

    //0:单路连接模式 1:多路连接模式
    esp8266_send_cmd("AT+CIPMUX=0","OK",20);

    //建立TCP连接
    (esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"192.168.4.1\",8080","CONNECT",200));

    //是否开启透传模式 0:关闭 1:开启
    esp8266_send_cmd("AT+CIPMODE=1","OK",200);

    //透传模式下开始发送数据指令
    esp8266_send_cmd("AT+CIPSEND","OK",50);
}

//ESP8266退出透传指令
//返回值 0:退出成功;1:退出失败
u8 esp8266_quit_trans(void)
{
    u8 result=1;
    u3_printf("+++");
    Delay_ms(1000);                    
    result=esp8266_send_cmd("AT","OK",20);//退出透传判断
    return result;
}


//向esp8266发送命令
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
    u8 res=0; 
    USART3_RX_STA=0;
    u3_printf("%s\r\n",cmd);    //发送命令
    if(ack&&waittime)        //需要等待应答
    {
        while(--waittime)    //等待倒计时
        {
            delay_ms(10);
            if(USART3_RX_STA&0X8000)//接收期待应答结果
            {
                if(esp8266_check_cmd(ack))
                {
                    printf("ack:%s\r\n",(u8*)ack);
                    break;//得到有效数据
                }
                    USART3_RX_STA=0;
            } 
        }
        if(waittime==0)res=1; 
    }
    return res;
} 


//ESP8266发送命令后,检测收到的应答
u8* esp8266_check_cmd(u8 *str)
{
    char *strx=0;
    if(USART3_RX_STA&0X8000)        //接收的第一次数据
    { 
        USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
        strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
    } 
    return (u8*)strx;
}


//向esp8266发送数据
u8* esp8266_send_data(u8 *cmd,u16 waittime)
{
    char temp[5];
    char *ack=temp;
    USART3_RX_STA=0;
    u3_printf("%s",cmd);    //发送命令
    if(waittime)        //需要等待应答
    {
        while(--waittime)    //等待倒计时
        {
            delay_ms(10);
            if(USART3_RX_STA&0X8000)//接收期待的应答结果
            {
                USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
                ack=(char*)USART3_RX_BUF;
                printf("ack:%s\r\n",(u8*)ack);
                USART3_RX_STA=0;
                break;//得到有效数据
            } 
        }
    }
    return (u8*)ack;
} 

5.遇见的问题

在进行服务端串口进行数据接收的时候,智能出现数据的前两位,后来发现是我将printf放入了中断服务函数当中去了,可能printf会占用你的时间,最好将printf放入while循环当中打印接收到的数据。接收到的数据最好存入数组当中,方便我们对接收的数据进行判断。

附:我们的模块是基于TCP通信的,我们也可以在手机上下载一个TCP调试助手,方便我们去调试小车

6.总结

这是我的第一篇博客,主要就是记录自己在做的过程当中遇到的一些问题,之前都是看别人的博客来解决自己的问题,现在也希望自己的东西可以帮助到别人。

你可能感兴趣的:(stm32,物联网)