[毕设记录] WiFi完成过程文档

文档创建时间:2016年3月10日
本文档描述的是如何在stm32f10x上用串口转wifi模块ESP8266实现与上位机的通信。

模块介绍

ESP8266模块,是一款USART转WiFi模块,可以使嵌入式系统串口通过无线网络与上位机进行通信。

引脚

这个模块的引脚一般引出来的有6个:

  • VCC:电源(建议接3.3v,在5v下也可以工作,据测试发热量稍大)
  • GND:电源地
  • TXD:模块串口发送引脚(TTL电平,可接单片机的RXD)
  • RXD:模块串口接收引脚(TTL电平,可接单片机的TXD)
  • RST:复位(低电平有效)
  • IO-0:低电平是进入固件烧写模式,高电平为运行状态(默认状态)

工作模式

这个模块通常会有三种工作模式:

  • AP模式,这种模式下模块相当于一个WiFi热点,其他设备可以接入这个热点,从而实现无线通信。(和蓝牙类似,不需要网络也可以实现)
  • STA模式,这个模式下模块相当于一个WiFi设备,需要通过路由器与其他的网络设备通信。
  • AP+SAT模式,这种模式是上述两种模式的并集。

每种模式下,都有若干种“身份”。本文档,主要讨论的是模块在STA模式下充当TCP Client的使用方法。

指令介绍

模块提供了一套完整的AT指令,供我们来操作,详细的指令请参考文档,这里不逐一列出。

ESP8266用户手册

注意事项

  1. 波特率115200
  2. 输入以回车换行符‘\r\n'结尾
  3. 使用双引号表示字符串数据

具体实现

实现WiFi的功能,分成硬件和软件部分。硬件上,使用stm32的USART2与ESP8266相连接。软件上,根据手册,封装AT命令,使用中断读取接收数据等。

引脚连接方式:

  • ESP8266_RXD连接stm32_USART2_TXD
  • ESP8266_TXD连接stm32_USART2_RXD
  • ESP8266_VCC连接3.3v
  • ESP8266_GND连接GND
  • ESP8266_RST悬空
  • ESP8266_I0_0悬空

PS:stm32与ESP8266要共地。

软件上,主要由下面几个文件来实现WiFi模块的驱动:

  • wifi_config.c 这个文件主要完成USART2的初始化,USART2的中断控制器配置
  • wifi_function.c 这个文件主要实现对wifi模块的AT指令操作,并完成STA TCP Client连接

这里不给出详细的代码,具体的代码可以看这里,这里重点讨论wifi_function.c这个文件,下面列出它的函数作解释,具体实现自己看看源文件:

//使能wifi模块
void ESP8266_Choose ( FunctionalState enumChoose );
//重启模块
void ESP8266_Rst( void );
//执行AT测试
void ESP8266_AT_Test( void );
//发送AT指令
//cmd:AT指令内容, reply1:期望的回应, reply2:期望的回应,waittime:等待时间
bool ESP8266_Cmd( char * cmd, char * reply1, char * reply2, u32 waittime );
//选择wifi模块的模式 AP, STA, AP+STA
bool ESP8266_Net_Mode_Choose( ENUM_Net_ModeTypeDef enumMode );
//开启多客户端连接
bool ESP8266_Enable_MultipleId( FunctionalState enumEnUnvarnishTx );
//连接到服务器(STA模式下需要使用到)
bool ESP8266_Link_Server( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id);
//开启透传模式
bool ESP8266_UnvarnishSend( void );
//发送数据
bool ESP8266_SendString( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId );
//接收数据
char *ESP8266_ReceiveString( FunctionalState enumEnUnvarnishTx );
//配置STA_TCP_Client连接模式
bool  ESP8266_STA_TCP_Client( void );
//从透传模式返回普通AT模式
bool ESP8266_Return_At( void );
//失能透传模式
bool ESP8266_Disable_UnvarnishSend( void );
//关闭TCP连接
bool ESP8266_Tcp_Close( void );
//按照配置,开启TCP连接
bool ESP8266_Connect_Tcp( void );

具体,是怎么往模块里面发送AT指令的,这里以其中一个为例子进行讲述:

//加入某个wifi热点的函数
//对应的AT指令是:AT+CWJAP=“ssid”,“passwor”
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord ){
    //声明一个存放命令的区域
    char cCmd [120];
   //通过sprintf函数,将参数传进来的ssid和password拼接到字符串后面,放入之前声明的区域
    sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
   //通过ESP8266_Cmd ()函数,往模块里面写入命令
    return ESP8266_Cmd ( cCmd, "OK", NULL, 7000 );  
}

下面,分析下如何配置TCP连接,并使能它的:

//配置TCP连接
//LCD是为了便于调试添加的,在液晶屏上显示程序的运行信息
bool ESP8266_STA_TCP_Client ( void ){
    bool statusCur = false;
    bool statusLst = true;
    // 开启sta连接模式
    LCD_DispStr(0,0,(uint8_t *)"begin to sta connection ...",BLUE); 
    ESP8266_AT_Test ();
    statusCur = ESP8266_Net_Mode_Choose ( STA );
    if (statusCur == true){
        LCD_DispStr(0,20,(uint8_t *)"sta mode success",0xffff);
        statusLst = true;
    }else{
        LCD_DispStr(0,20,(uint8_t *)"sta mode fail",0xffff);
        statusLst = false;
    }   
    //加入热点的SSID和PASSWORD
    LCD_DispStr(0,40,(uint8_t *)"begin to join ERIC_LAI ...",BLUE);
    //这里写死了热点的ssid和pw,需要根据各自的情况自行修改
    statusCur = ESP8266_JoinAP ( "ERIC_LAI", "lai686868" );
    if (statusCur == true && statusLst == true){
        LCD_DispStr(0,60,(uint8_t *)"join ERIC_LAI success",0xffff);    
        statusLst = true;
    } else{
        LCD_DispStr(0,60,(uint8_t *)"join ERIC_LAI success",0xffff);
        statusLst = false;
    }
}
//使能TCP连接
bool ESP8266_Connect_Tcp(void){
    bool status = false;
    // 连接到TCP服务器
    ESP8266_Enable_MultipleId ( ENABLE );
    LCD_DispStr(0,120,(uint8_t *)"begin to connect the server ...",BLUE);
    status = ESP8266_Link_Server ( enumTCP, serverIpAddress, "9998", Multiple_ID_0 );
    if (status == true){
        LCD_DispStr(0,140,(uint8_t *)"connect server success",0xffff);
    } else{
        LCD_DispStr(0,140,(uint8_t *)"connect server fail",0xffff);
    }
    return status;
}

这一步成功之后,就是接受和发送数据的事情了。因为是串口,所以本质上用的还是串口中断来接收数据的。在wifi_config.c里面,我们完成了串口的使用和中断的配置。但是,串口只能一位一位的发送数据,所以,我们需要写一些代码来实现字符串的接收。上面的注意事项,’\r\n‘是发送完成的标志。所以,我们一直接收数据,知道接收到回车换行符为止。接收到后,标志位置位,退出接收循环。详细代码如下:

//以下的代码在stm32f10x_it.c里面
void USART2_IRQHandler( void ){ 
    char ch;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
        ch  = USART_ReceiveData( USART2 );
        if( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) ){ //预留1个字节写结束符             
        strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ch;
        }
    } 
    if ( USART_GetITStatus( USART2, USART_IT_IDLE ) == SET ) {//数据帧接收完毕
        strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1; 
        ch = USART_ReceiveData( USART2 ); //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)    
  } 
}

以上,完成之后,通过上面给出的ESP8266_ReceiveString()函数就可以获取接收到的字符串,注意:这是一个堵塞的函数!一旦调用就会等待接收到回车换行符为止。

上面的代码,在发送数据和接收数据的情况,都没有使用透传模式。所以,发送数据的时候需要确定数据的长度(最长不超过1024),接收数据的时候会有报头(+IDP,*,*:)。所以,发送图片的时候需要将图片分割开来发送,接收的时候需要做数据截断,把报头去掉。关于图片分割,在图片传输的时候讲述,截断数据的方法在下面给出:

char* getRealRecv(char *pStr){
    char *pBuf, *ppStr, *pStrDelimiter[2];
    int uc = 0;
    char cStrInput [100];
    sprintf(cStrInput, "%s", pStr);
    pBuf = cStrInput;
        uc = 0;
        while ( ( ppStr = strtok ( pBuf, ":" ) ) != NULL ){
            pStrDelimiter [ uc ++ ] = ppStr;
            pBuf = NULL;
        } 
    return pStrDelimiter[1];
}

以上,是WiFi模块的完成过程。

你可能感兴趣的:([毕设记录] WiFi完成过程文档)