【瑞萨RA_FSP】WiFi——ESP8266模块通讯


一、Wifi模块简介

ESP8266-12F是启明6M5开发板板载的一个WiFi模块。 该模块核心处理器ESP8266在较小尺寸封装中集成了业界领先的Tensilica L106超低功耗32位微型MCU。 带有16位精简模式,主频支持80MHz和160MHz。 支持RTOS,集成Wi-Fi MAC/BB/RF/PA/LNA,板载天线。 支持标准的IEEE802.11 b/g/n协议,完整的TCP/IP协议栈。 用户可以使用该模块为现有的设备添加联网功能,也可以构建独立的网络控制器。 尤其是有过物联网开发经验的人,必然绕不过ESP8266,其低廉的价格、超高的性能和便利的开发环境,毫无疑问是业界中里程碑一样的存在。 而在启明6M5开发板中只需要通过SCI9 UART串口和AT指令就可以对ESP8266进行简单的配置。

二、ESP8266功能介绍

ESP8266整体架构如下图所示。
在这里插入图片描述
ESP8266强大的片上处理和存储能力,使其可通过GPIO口集成传感器及其他应用的特定设备,大大地降低了前期开发的成本。 以下为ESP8266的整体特性。

  • 完整的802.11b/g/n Wi-Fi SoC模块

  • 内置Tensilica L106超低功耗32位微型MCU,主频支持80MHz和160MHz,支持RTOS

  • 内置1路10位高精度ADC

  • 支持UART/GPIO/ADC/PWM/SPI/I2C接口

  • 采用SMD-22封装

  • 集成Wi-Fi MAC/BB/RF/PA/LNA

  • 支持多种休眠模式,深度睡眠电流低至20uA

  • 串口速率最高可达4Mbps

  • 内嵌Lwip协议栈

  • 支持STA/AP/STA+AP工作模式

  • 支持安卓、IOS的Smart Config(APP)/AirKiss(微信)一键配网

  • 支持串口本地升级和远程固件升级(FOTA)

  • 通用AT指令,可快速上手

  • 支持二次开发,集成了Windows、Linux开发环境

1. 通用输入/输出接口(GPIO)

ESP8266总共有22个管脚,如下图所示,通过配置适当的寄存器可以给它们分配不同的功能。 每一个GPIO都可以单独配置,如上拉/下拉,或者设置为高阻态。 当被配置为输⼊时,可通过读取寄存器获取输⼊值。 输⼊也可以被设置为边缘触发或电平触发来产⽣CPU中断。 这些管脚可以与其它功能复用,例如I2C、I2S、SPI、ADC、UART、PWM、IR遥控等。
在这里插入图片描述
ESP8266管脚功能定义
在这里插入图片描述
ESP8266引脚功能介绍
在这里插入图片描述
在这里插入图片描述

2. 使用UART与WIFI通讯

ESP8266模组与MCU的连接如下表所示:
在这里插入图片描述
在下方开发板原理图中,可以看到J34的1,2引脚代表着开发板的SCI9 UART串口中的TX、RX接口。 而3,4引脚是ESP8266的SCI9 UART中的RX、TX接口,在实际的开发板中,J34的1,3引脚和2,4引脚一般是通过跳帽连接的,这代表了开发板可以通过SCI9 UART与WIFI模块进行通讯。 也就是说,想要配置ESP8266,就需要与SCI9 UART中的P601与P602两个引脚建立通信。
在这里插入图片描述

3. ESP8266工作模式介绍

ESP8266总共有三种工作模式,分别是STA(Station)、AP(Wireless Access Point)、以及STA+AP模式。

STA 模式:在STA模式下,ESP8266就像一个接收设备,此时它可以接受来自其它无线路由器发射的信号,从而连接互联网,让搭载ESP8266的设备实现远程控制。

AP 模式:在AP模式下,ESP8266成为了发射设备,也就是成为了一个热点,手机和电脑等设备都可以连接到这个热点,从而使无线设备能够与ESP8266进行远程通信。

STA + TA 模式:两种模式共同使用,既可以作为客户端连接到别的网络,也可以作为Wifi热点使用,实现广域网与局域网的无缝切换。

三、AT指令

AT(Attention)指令集是从终端设备(Terminal Equipment,TE)或数据终端设备(Data Terminal Equipment,DTE)向终端适配器(Terminal Adapter,TA)或数据电路终端设备(Data Circuit Terminal Equipment,DCE)发送的。

在ESP8266芯片出厂时,厂家已经在芯片内部烧写了固件,这使得能够通过一些常见的AT指令去控制它。 当然,也可以通过获取SDK的方式重新烧写固件,修改和添加想要的功能。

四、实验:STA模式测试

在这之前首先要了解一下透传模式,简单的讲就是ESP8266将通过串口接收到的数据, 直接进行转发到所设置的目标服务器的端口上,不需要关心WIFI协议是如何来实现数据的传输。只需要在ESP8266上设置好服务器地址即可。

1. 文件结构

└─ src
├─ led
│ ├─ bsp_led.c
│ └─ bsp_led.h
├─ debug_uart
│ ├─ bsp_debug_uart.c
│ └─ bsp_debug_uart.h
├─ bsp_esp8266
│ ├─ bsp_wifi_esp8266.c
│ └─ bsp_wifi_esp8266.h
└─ hal_entry.c
首先,打开网络调试助手,选择协议类型为TCP Server,也就是客户端模式,具体配置如下图所示。

2. 宏定义函数

首先在bsp_wifi_esp8266.h文件中将我们所需要的数据以及指令用宏定义封装起来。 后续需要更改配置信息只需要在宏定义中稍加修改就可以。

 /*宏定义调试信息*/
 #define ESP8266_DEBUG   1

 #if     (ESP8266_DEBUG == 1)
 #define     ESP8266_DEBUG_MSG(fmt, ... )        printf ( fmt, ##__VA_ARGS__ )
 #else
 #define     ESP8266_DEBUG_MSG(fmt, ... )
 #endif


 #define   ID             "AP_DEVICE"           //要连接的热点的名称
 #define   PASSWORD       "123456789"           //要连接的热点的密钥

 #define   SeverIP        "192.168.103.166"     //要连接的服务器IP
 #define   SeverPort      "8000"                //要连接的服务器端口

 #define ESP8266_MODULE_ENABLE     R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_15, BSP_IO_LEVEL_HIGH);  //使能ESP8266模块
 #define ESP8266_MODULE_DISABLE    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_15, BSP_IO_LEVEL_LOW);   //关闭ESP8266模块

 /*红灯闪烁*/
 #define ESP8266_ERROR_Alarm()     R_PORT4->PODR ^= 1<<(BSP_IO_PORT_04_PIN_00 & 0xFF); \
                                   R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);

 /*清除UART9数据缓冲区函数*/
 #define   Clear_Buff()   memset( At_Rx_Buff , 0 , sizeof(At_Rx_Buff) ); \
                          Uart9_Num = 0;

3. ESP8266-STA功能函数

随后在bsp_wifi_esp8266.c文件中添加配置ESP8266所需要的函数。

_Bool               Uart9_Receive_Flag = false; //用来判断UART9接收以及发送数据是否完成
_Bool               Uart9_Show_Flag = false;    //控制UART9收发数据显示标志

 /*用来接收UART9数据的缓冲区*/
 char                At_Rx_Buff[256];
 uint8_t             Uart9_Num = 0;

 /*自动配置ESP8266函数*/
 void ESP8266_STA_Test(void)
 {
    
    

    ESP8266_DEBUG_MSG("\r\n正在初始化ESP8266...\r\n");
    ESP8266_UART9_Init();

    ESP8266_DEBUG_MSG("\r\n设置STA模式中...\r\n");
    ESP8266_STA();

    ESP8266_DEBUG_MSG("\r\n正在连接WIFI中...\r\n");
    ESP8266_STA_JoinAP( ID , PASSWORD , 20 );
    Link_Mode( 0 );

    ESP8266_DEBUG_MSG("\r\n正在连接服务器中...\r\n");
    ESP8266_STA_JoinServer( SeverIP , SeverPort , 20 );

    ESP8266_DEBUG_MSG("\r\n正在配置为透传发送模式...\r\n");
    ESP8266_STA_Transmission();
    ESP8266_Send_Data();

 }

 /*ESP8266 (SPI9 UART) 初始化函数*/
 void ESP8266_UART9_Init(void)
 {
    
    
    fsp_err_t err = FSP_SUCCESS;

    err = R_SCI_UART_Open(g_uart9_esp8266.p_ctrl, g_uart9_esp8266.p_cfg);
    assert(FSP_SUCCESS == err);
 }

 /*向ESP8266发送AT指令函数*/
 void ESP8266_AT_Send(char * cmd )
 {
    
    
    /*向ESP8266(UART9)发送指令*/
    R_SCI_UART_Write(&g_uart9_esp8266_ctrl, (uint8_t *)cmd, strlen(cmd));

    /*AT指令发送完成标志*/
    Uart9_Receive_Flag = false;

 }

 /*设置ESP8266为 STA 模式*/
 void ESP8266_STA ( void )
 {
    
    
    ESP8266_AT_Send ( "AT+CWMODE=1\r\n" );

    /*等待设置完成*/
    while ( !Uart9_Receive_Flag )
    {
    
    
          if (strstr( At_Rx_Buff , "OK\r\n" ))
          {
    
    
          ESP8266_DEBUG_MSG("\r\nESP8266已切换为STA模式\r\n");
          Clear_Buff();      //清除缓冲区数据
          }
    }
 }

 /*设置ESP8266为 AP 模式*/
 void ESP8266_AP ( void )
 {
    
    
    ESP8266_AT_Send ( "AT+CWMODE=2\r\n" );

    /*等待设置完成*/
    while ( !Uart9_Receive_Flag )
    {
    
    
          if (strstr( At_Rx_Buff , "OK\r\n" ))
          {
    
    
          ESP8266_DEBUG_MSG("\r\nESP8266已切换为AP模式\r\n");
          Clear_Buff();      //清除缓冲区数据
          }
    }
 }

 /*设置ESP8266为 STA + AP 模式*/
 void ESP8266_STA_AP ( void )
 {
    
    
       ESP8266_AT_Send ( "AT+CWMODE=3\r\n" );

       /*等待设置完成*/
       while ( !Uart9_Receive_Flag )
       {
    
    
          if (strstr( At_Rx_Buff , "OK\r\n" ))
          {
    
    
          ESP8266_DEBUG_MSG("\r\nESP8266已切换为STA+AP模式\r\n");
          Clear_Buff();      //清除缓冲区数据
          }
       }
 }

 /*ESP8266连接WiFi函数*/
 void ESP8266_STA_JoinAP( char * id ,  char * password , uint8_t timeout ) //timeout:期望连接时间,单位为秒
 {
    
    
    char  JoinAP_AT[256];

    uint8_t i;

    sprintf( JoinAP_AT , "AT+CWJAP=\"%s\",\"%s\"\r\n" , id , password);

    ESP8266_AT_Send( JoinAP_AT );

    /*判断Wifi连接是否成功*/
    for(i = 0; i <= timeout; i++)
    {
    
    
          if ( strstr( At_Rx_Buff , "OK\r\n" ) )
          {
    
    
                ESP8266_DEBUG_MSG("\r\nWifi连接成功\r\n");
                Clear_Buff();      //清除缓冲区数据
                break;
          }
          if ( strstr( At_Rx_Buff , "ERROR\r\n" ) )    //根据ESP8266的固件版本不同有不同的响应,一般为“FAIL”或“ERROR”
          {
    
    
                if( strstr( At_Rx_Buff , "+CWJAP:1\r\n" ))
                ESP8266_DEBUG_MSG("\r\nWifi连接超时,请检查各项配置是否正确\r\n");

                if( strstr( At_Rx_Buff , "+CWJAP:2\r\n" ))
                ESP8266_DEBUG_MSG("\r\nWifi密码错误,请检查Wifi密码是否正确\r\n");

                if( strstr( At_Rx_Buff , "+CWJAP:3\r\n" ))
                   ESP8266_DEBUG_MSG("\r\n无法找到目标Wifi,请检查Wifi是否打开或Wifi名称是否正确\r\n");

                if( strstr( At_Rx_Buff , "+CWJAP:4\r\n" ))
                ESP8266_DEBUG_MSG("\r\nWifi连接失败,请检查各项配置是否正确\r\n");

                while(1)
                {
    
    
                ESP8266_ERROR_Alarm();
                }      //LED灯警告错误,红灯闪烁
          }
          if ( i == timeout )
          {
    
    
                ESP8266_DEBUG_MSG("\r\nWifi连接超出期望时间,请检查各项配置是否正确\r\n");
                while(1)
                {
    
    
                ESP8266_ERROR_Alarm();
                }      //LED灯警告错误,红灯闪烁
          }
          R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
       }
 }

 /*设置连接模式为单连接或者多连接*/
 void Link_Mode( uint8_t mode )
 {
    
    
       switch ( mode ){
    
    
          case 0 :
             ESP8266_AT_Send("AT+CIPMUX=0\r\n"); //设置为单连接模式,透传只有在单连接模式下才能进行
             break;
          case 1 :
             ESP8266_AT_Send("AT+CIPMUX=1\r\n"); //设置为多连接模式,服务器只有在多连接模式下才能打开
             break;
       }

       /*等待设置完成*/
       while ( !Uart9_Receive_Flag )
       {
    
    
          if (strstr( At_Rx_Buff , "OK\r\n" ))
          {
    
    
                if( mode )
                ESP8266_DEBUG_MSG("\r\nESP8266已切换为多连接模式\r\n");
                else
                ESP8266_DEBUG_MSG("\r\nESP8266已切换为单连接模式\r\n");
                Clear_Buff();      //清除缓冲区数据
          }
       }
 }

 /*ESP8266连接服务器函数*/
 void ESP8266_STA_JoinServer( char * server_id ,  char * port , uint8_t timeout ) //timeout:期望连接时间,单位为秒
 {
    
    
    char  JoinServer_AT[256];

    uint8_t i;

    sprintf( JoinServer_AT , "AT+CIPSTART=\"TCP\",\"%s\",%s\r\n" , server_id , port );

    ESP8266_AT_Send( JoinServer_AT );

       /*判断服务器连接是否设置成功*/
       while ( !Uart9_Receive_Flag )
       {
    
    
          /*超时判断,timeout:期望最长等待时间*/
          for(i = 0; i <= timeout; i++)
         {
    
    
          if (strstr( At_Rx_Buff , "OK\r\n" ))
          {
    
    
                ESP8266_DEBUG_MSG("\r\n服务器连接成功\r\n");
                Clear_Buff();      //清除缓冲区数据
                break;
          }
          if (strstr( At_Rx_Buff , "ERROR\r\n" ))
          {
    
    
                ESP8266_DEBUG_MSG("\r\n服务器连接失败,请检查服务器是否打开以及参数是否正确\r\n");
                while(1)
                {
    
    
                ESP8266_ERROR_Alarm();
                }      //LED灯警告错误,红灯闪烁
          }
          if ( i == timeout )
          {
    
    
                ESP8266_DEBUG_MSG("\r\n服务器连接超出期望时间,请检查各项配置是否正确\r\n");
                while(1)
                {
    
    
                ESP8266_ERROR_Alarm();
                }      //LED灯警告错误,红灯循环闪烁
          }
          R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
         }
       }
 }

 /*设置ESP8266为透传模式*/
 void ESP8266_STA_Transmission( void )
 {
    
    
       ESP8266_AT_Send ( "AT+CIPMODE=1\r\n" );

       /*等待设置完成*/
       while ( !Uart9_Receive_Flag )
       {
    
    
          if (strstr( At_Rx_Buff , "OK\r\n" ))
          {
    
    
          ESP8266_DEBUG_MSG("\r\nESP8266已切换为透传模式\r\n");
          Clear_Buff();      //清除缓冲区数据
          }
       }
 }

 /*设置ESP8266为发送数据模式*/
 void ESP8266_Send_Data( void )
 {
    
    
       ESP8266_AT_Send ( "AT+CIPSEND\r\n" );

       /*等待设置完成*/
       while ( !Uart9_Receive_Flag )
       {
    
    
             if (strstr( At_Rx_Buff , "OK\r\n" ))
             {
    
    
                ESP8266_DEBUG_MSG("\r\nESP8266已进入透传发送模式\r\n\r\n>");
                Uart9_Show_Flag = true;
                Clear_Buff();      //清除缓冲区数据
             }
     }
 }

4. 中断回调函数

 /*Wifi串口回调函数*/
 void esp8266_uart9_callback(uart_callback_args_t * p_args)
 {
    
    
       switch(p_args->event)
       {
    
    
          case UART_EVENT_RX_CHAR:

                At_Rx_Buff[Uart9_Num++] = ( char ) p_args->data;  //将UART9收到的数据放到Buff缓冲区中

                /*进入透传模式后打开串口调试助手收发数据显示*/
                if( Uart9_Show_Flag )
                R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)&(p_args->data), 1);

                break;

          case UART_EVENT_TX_COMPLETE:
          {
    
    
                Uart9_Receive_Flag = true;      //ESP8266回应完成标志

                break;
          }
          default:
                break;
       }
 }

5. hal_entry入口函数

void hal_entry(void)
 {
    
    
    /* TODO: add your own code here */

    Debug_UART4_Init(); // SCI4 UART 调试串口初始化

    ESP8266_STA_Test(); // ESP8266 自动配置函数

    while(1){
    
    }

 #if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
 #endif
 }

猜你喜欢

转载自blog.csdn.net/Dustinthewine/article/details/131328947