打印
[STM32L4]

ESP8266-WIFI模块应用

[复制链接]
4947|33
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gaoke231|  楼主 | 2017-10-31 15:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 gaoke231 于 2017-10-31 15:47 编辑

1.ESP8266-WIFI数据透传实验

实验效果.jpg (106.74 KB )

实验效果.jpg
沙发
gaoke231|  楼主 | 2017-10-31 15:52 | 只看该作者
ESP8266简介:
ESP8266 是一个完整且成体系的 Wi-Fi 网络解决方案,能够搭载软件应用,或通过另一个应处理器卸载所有 Wi-Fi 网络功能。我们使用的 ESP8266 是串口型WIFI,速度比较低,不能用来传输图像或者视频这些大容量的数据,主要应用于数据量传输比较少的场合,比如温度信息,一些传感器的开关量等。当然传输的数据量虽说少,但也能一次传输几千字节的数据,而且通信非常稳定,可以满足大多数应用。

使用特权

评论回复
板凳
gaoke231|  楼主 | 2017-10-31 16:01 | 只看该作者
1.2ESP8266-WIFI 模块介绍
安信可推出的 ESP8266-WIFI 模块有很多,它们的使用方法都大同小异,我们普中STM32 开发板预留的是图 1.2.1 所示 ESP8266-WIFI 模块接口,大家只要将此模块插入开发板接口即可做此实验,无需额外连线。这里我们就以此 WIFI 模块介绍。如果大家需要将此模块设计到自己产品内,可能需要参考这个尺寸值。WIFI 模块实物图中可以看到,WIFI 模块提供了一个 2*4 的外接管脚,让我们连接到自己的电路中控制,这 8 个管脚两两间距是2.54mm。管脚功能定义如下:VCC:3.3V 电源,开发板上丝印已经标了。RST:ES8266 复位管脚,可做外部硬件复位使用。CH_PD:使能管脚,高电平有效。UTXD:串口发送管脚,与开发板上串口 2 的 RXD 相连。URXD:串口接收管脚,与开发板上串口 2 的 TXD 相连GPIO0:GPIO0为高电平代表从 FLASH 启动, GPIO0 为低电平代表进入系统升级状态,此时可以经过串口升级内部固件,这里我们不需要对此管脚操作。GPIO2:此管脚为 ESP8266 引出的一个 IO 口,这里我们不需要对此管脚操作。GND:GND 管脚,开发板上丝印已经标了其实我们不需要使用这么多管脚,只需要使用 WIFI 模块的串口 UTXDURXD管脚、RST CH_PD 管脚即可,其他的不用管。WSP8266-WIFI 模块接口与 STM32 芯片管脚连接图如下:(开发板内线路已连接好,所以直接插上模块即可)









1.png (32.58 KB )

1.png

使用特权

评论回复
地板
gaoke231|  楼主 | 2017-10-31 16:05 | 只看该作者
ESP8266 常用指令
基础 AT 指令:
(1)AT 测试指令
2AT+RST 模块重启
(3)AT+GMR 查看版本信息
(4)ATE 开关回显功能
(5)AT+RESTORE 恢复厂设置功能
(6)AT+UART 设置串口配置


使用特权

评论回复
5
gaoke231|  楼主 | 2017-10-31 16:06 | 只看该作者
ESP8266-WIFI 实验
了解了 WIFI 模块的 AT 指令格式及功能,下面我们就可以使用 STM32 串口与 WIFI 模块串口进行通信了。本教程我们要实现 STA 模式的 TCP Client 透传。简单理解就是配置 WIFI 模块为 STA 模式,让 WIFI模块连接路由器或者笔记本发出的 wifi,然后在网络调试助手上设置好连接 WIFI 的 IP 地址和端口,这时 STM32串口 2 发送的数据就可以经过 WIFI 模块传输到网络调试助手上显示,即实现了
TCP Client 透传。这里需要注意:WIFI 模块默认的时候串口波特率是 115200,8 位数据,1 位停止位,因此我们在配置 STM32 串口的时候也要按这个模式配置串口,否则不能进行数据传输。将485 模块旁的 P485 短接片短接到 WIFI 端。

使用特权

评论回复
6
gaoke231|  楼主 | 2017-10-31 16:07 | 只看该作者
本实验所实现的功能:在局域网中,WIFI 模块配置为 STA 模式,做客户端,电脑做服务端,客户端往服务端不断发数据,每间隔1 秒发送一串
www.21IC.com字符,发送的字节数为 14 字节。
要实现此功能程序,首先要初始化ESP8266-WIFI 模块所用的 IO 口及时钟,其中包括串口配置,初始化后即进入STA 模式透传,配置好 STA 模式,连接由电脑或路由器发出的wifi 后,开始传输数据。

使用特权

评论回复
7
gaoke231|  楼主 | 2017-10-31 16:09 | 只看该作者
(1)修改 WIFI 名称、密码及 IP 在下载程序到开发板前,需要看下你所在的局域网的 WIFI 名称和你电脑的
IP , 然 后 打 开 工 程 , 编 译 后 找 到 sta_tcpclent_test.h 文 件 (在 sta_tcpclent_test.c 内),把里面的宏参数修改为你所在的局域网的 WIFI 名
称和你电脑的 IP,代码如下:
#define User_ESP8266_SSID     "PUZHONG"                  //要连接的热点的名称
#define User_ESP8266_PWD     "puzhong168"       //要连接的热点的密码
#define User_ESP8266_TCPServer_IP     "192.168.191.1"             // 要连接的服务
器的 IP
#define User_ESP8266_TCPServer_PORT      "8080"              //要连接的服务器的
端口
我们程序里面的这 4 个宏参数,是针对我们使用的局域网 WIFI 名称、密码和电脑 IP,如果你要实现与你的电脑进行透传,就需要将此部分进行修改。至于怎么查看你电脑 IP,请百度。

使用特权

评论回复
8
gaoke231|  楼主 | 2017-10-31 16:10 | 只看该作者
本帖最后由 gaoke231 于 2017-10-31 16:11 编辑

2)设置串口调试助手与网络调试助手
修改完这部分程序后,将工程编译下载到开发板内(记得要插上你的WIFI模块)。打开串口调试助手和网络调试助手,此软件在“\调试工具”目录下。将串口调试助手波特率设置为 115200,数据位 8,停止位 1,特别注意,由于此串口助手刚打开会把我们开发板一直拉到复位状态,所以需要勾选下DTR,然后再取消掉,即可有信息返回到串口助手上然后打开网络调试助手,选择协议类型为 TCP Server,本地IP 地址和端口设置为前面 sta_tcpclent_test.h 文件内配置的IP 地址及端口(要保证前面配置的是你的电脑 IP 地址和端口),选择开始监听,当串口助手上显示配置ESP8266 OK,然后就会接收到由开发板串口 2 发送的“www.prechin.cn”信息,间隔时间为 1 秒。如果没有接收到,请重新复位下开发板,直到连接成功,接收到数据。


使用特权

评论回复
9
gaoke231|  楼主 | 2017-10-31 16:13 | 只看该作者
主函数
int main()
{         
        u8 i;
        Systick_Init(72);
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        USART1_Init(115200);
        LED_Init();
        KEY_Init();

        printf("21IC科技ESP8266 WIFI模块STA TCPClent透传测试\r\n");
        ESP8266_Init(115200);
       
        ESP8266_STA_TCPClient_Test();

        while(1)
        {
                i++;
                if(i%20==0)
                {
                        led0=!led0;
                }
                delay_ms(10);               
        }
}


使用特权

评论回复
10
gaoke231|  楼主 | 2017-10-31 16:15 | 只看该作者
在esp8266_drive.c中 串口3的初始化
void USART3_Init(u32 bound)
{

          GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
         
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);       

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
          GPIO_Init(GPIOB, &GPIO_InitStructure);


          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB11
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
          GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB 11  

        //Usart3 NVIC 配置
          NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                //子优先级0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器

           //USART3 初始化设置
        USART_InitStructure.USART_BaudRate = bound;//串口波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
        USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式
          USART_Init(USART3, &USART_InitStructure); //初始化串口3

          USART_ITConfig(USART3, USART_IT_RXNE|USART_IT_IDLE, ENABLE);//开启串口接受和总线空闲中断
         
        USART_Cmd(USART3, ENABLE);                    //使能串口3        
}


使用特权

评论回复
11
gaoke231|  楼主 | 2017-10-31 16:15 | 只看该作者
串口3中断
void USART3_IRQHandler( void )
{       
        u8 ucCh;
       
        if(USART_GetITStatus( USART3, USART_IT_RXNE ) != RESET )
        {
                ucCh  = USART_ReceiveData( USART3 );
               
                if(ESP8266_Fram_Record_Struct .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )
                {
                        //预留1个字节写结束符
                        ESP8266_Fram_Record_Struct .Data_RX_BUF[ ESP8266_Fram_Record_Struct .InfBit .FramLength ++ ]  = ucCh;       
                }                     
        }
                  
        if( USART_GetITStatus( USART3, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕
        {
            ESP8266_Fram_Record_Struct .InfBit .FramFinishFlag = 1;
               
                ucCh = USART_ReceiveData( USART3 );                                                              //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)
       
                TcpClosedFlag = strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
               
          }       


}

使用特权

评论回复
12
gaoke231|  楼主 | 2017-10-31 20:51 | 只看该作者
串口2初始化
void USART2_Init(u32 bound)
{


          GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
         
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);       


          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2  TXD
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
          GPIO_Init(GPIOA, &GPIO_InitStructure);
   


          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3  RXD
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
          GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA3  
  
        //Usart2 NVIC 配置
          NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                //子优先级0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器


           //USART2 初始化设置
        USART_InitStructure.USART_BaudRate = bound;//串口波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
        USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式
          USART_Init(USART2, &USART_InitStructure); //初始化串口2


          USART_ITConfig(USART2, USART_IT_RXNE|USART_IT_IDLE, ENABLE);//开启串口接受和总线空闲中断
         
        USART_Cmd(USART2, ENABLE);                    //使能串口2        
}

使用特权

评论回复
13
gaoke231|  楼主 | 2017-10-31 20:52 | 只看该作者
串口2 中断
void USART2_IRQHandler( void )
{       
        u8 ucCh;
       
        if(USART_GetITStatus( USART2, USART_IT_RXNE ) != RESET )
        {
                ucCh  = USART_ReceiveData( USART2 );
               
                if(ESP8266_Fram_Record_Struct .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )
                {
                        //预留1个字节写结束符
                        ESP8266_Fram_Record_Struct .Data_RX_BUF[ ESP8266_Fram_Record_Struct .InfBit .FramLength ++ ]  = ucCh;       
                }                     
        }
                  
        if( USART_GetITStatus( USART2, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕
        {
            ESP8266_Fram_Record_Struct .InfBit .FramFinishFlag = 1;
               
                ucCh = USART_ReceiveData( USART2 );                                                              //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)
       
                TcpClosedFlag = strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
               
          }       


}

使用特权

评论回复
14
gaoke231|  楼主 | 2017-10-31 20:57 | 只看该作者
ESP8266初始化
void ESP8266_Init(u32 bound)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(ESP8266_RST_Pin_Periph_Clock|ESP8266_CH_PD_Pin_Periph_Clock, ENABLE);


        GPIO_InitStructure.GPIO_Pin = ESP8266_RST_Pin;                          
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
        GPIO_Init(ESP8266_RST_Pin_Port, &GPIO_InitStructure);


           GPIO_InitStructure.GPIO_Pin = ESP8266_CH_PD_Pin;                          
        GPIO_Init(ESP8266_CH_PD_Pin_Port, &GPIO_InitStructure);
       
        USART2_Init(bound);
       
        ESP8266_RST_Pin_SetH;
        ESP8266_CH_PD_Pin_SetL;       
}


使用特权

评论回复
15
gaoke231|  楼主 | 2017-10-31 21:00 | 只看该作者
对ESP8266模块发送AT指令
bool ESP8266_Send_AT_Cmd(char *cmd,char *ack1,char *ack2,u32 time)
{
        ESP8266_Fram_Record_Struct .InfBit .FramLength = 0;        //从新开始接收新的数据包
        ESP8266_USART("%s\r\n", cmd);
        if(ack1==0&&ack2==0)         //不需要接收数据
        {
                return true;
        }
        delay_ms(time);          //延时time时间


        ESP8266_Fram_Record_Struct.Data_RX_BUF[ESP8266_Fram_Record_Struct.InfBit.FramLength ] = '\0';


        PC_USART("%s", ESP8266_Fram_Record_Struct .Data_RX_BUF);


        if(ack1!=0&&ack2!=0)
        {
                return ( ( bool ) strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, ack1 ) ||
                                                 ( bool ) strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, ack2 ) );
        }
        else if( ack1 != 0 )
                return ( ( bool ) strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, ack1 ) );
       
        else
                return ( ( bool ) strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, ack2 ) );
                       
}

使用特权

评论回复
16
gaoke231|  楼主 | 2017-10-31 21:04 | 只看该作者
重启WF-ESP8266模块
void ESP8266_Rst(void)
{
        ESP8266_RST_Pin_SetL;
        delay_ms(500);
        ESP8266_RST_Pin_SetH;
}


使用特权

评论回复
17
gaoke231|  楼主 | 2017-10-31 21:05 | 只看该作者
对ESP8266模块进行AT测试启动
void ESP8266_AT_Test(void)
{
        char count=0;
       
        ESP8266_RST_Pin_SetH;
        delay_ms(1000);       
        while(count < 10)
        {
                if(ESP8266_Send_AT_Cmd("AT","OK",NULL,500))
                        return;
                ESP8266_Rst();
                ++ count;
        }
}


使用特权

评论回复
18
gaoke231|  楼主 | 2017-10-31 21:05 | 只看该作者
选择ESP8266模块的工作模式
返回1:选择成功 0:选择失败
bool ESP8266_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode)
{
        switch ( enumMode )
        {
                case STA:
                        return ESP8266_Send_AT_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 );
               
                  case AP:
                          return ESP8266_Send_AT_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 );
               
                case STA_AP:
                          return ESP8266_Send_AT_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 );
               
                  default:
                  return false;
        }               
}


使用特权

评论回复
19
gaoke231|  楼主 | 2017-10-31 21:06 | 只看该作者
ESP8266模块连接外部WiFi
pSSID:WiFi名称字符串
pPassWord:WiFi密码字符串
返回1:连接成功 0:连接失败
bool ESP8266_JoinAP( char * pSSID, char * pPassWord )
{
        char cCmd [120];


        sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
       
        return ESP8266_Send_AT_Cmd( cCmd, "OK", NULL, 5000 );
       
}


使用特权

评论回复
20
gaoke231|  楼主 | 2017-10-31 21:07 | 只看该作者
ESP8266模块启动多连接
enumEnUnvarnishTx:配置是否多连接
返回1:配置成功 0:配置失败
bool ESP8266_Enable_MultipleId (FunctionalState enumEnUnvarnishTx )
{
        char cStr [20];
       
        sprintf ( cStr, "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) );
       
        return ESP8266_Send_AT_Cmd ( cStr, "OK", 0, 500 );
       
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

1310

帖子

5

粉丝