延时函数初始化,单片机指令执行速度过快,向8266发送AT指令时需要延时等待。
串口1使用PA9、PA10,串口1向电脑的串口助手发送信息,来反映AT指令的响应.
串口2使用PA2、PA3,向8266发送AT指令,用来控制8266。
WiFi_ResetIO_Init(); //初始化WiFi的复位IO
WiFi复位引脚为PA4,低电平WiFi复位
8266接收数据变量定义

串口2通过中断来接收数据,将其存放到char Usart2_RxBuff[USART2_RXBUFF_SIZE] 数组中
控制8266,依靠字符串的搜素和比较
wifi初始化大循环
wifi.c
WiFi_Reset()函数
if(strstr(WiFi_RX_BUF,”ready”)) //如果接收到ready表示复位成功
WiFi_RX_BUF是串口2的Usart2_RxBuff(接收数据缓存区)
单片机通过串口1向8266发送AT指令,82266与串口2相连,8266收到指令的响应存放在串口2的Usart2_RxBuff中。
char WiFi_InitServer_AP(void)
{
char temp[50];
u1_printf(“准备复位模块\r\n”); //串口提示数据
if(WiFi_Reset(50)){ //复位,100ms超时单位,总计5s超时时间
u1_printf(“复位失败,准备重启\r\n”); //返回非0值,进入if,串口提示数据
return 1; //返回1
}else u1_printf(“复位成功\r\n”); //串口提示数据
main.c 
while(WiFi_InitServer_AP()){ //循环,初始化,建立服务器,直到成功
Delay_Ms(200); //延时
}
上面的循环嵌套在主函数循环中
/*-------------------------------------------------*//*函数名:建立服务器初始化 *//*参 数:无 *//*返回值:0:正确 其他:错误 *//*-------------------------------------------------*/char WiFi_InitServer_AP(void){char temp[50];u1_printf("准备复位模块\r\n"); //串口提示数据if(WiFi_Reset(50)){ //复位,100ms超时单位,总计5s超时时间u1_printf("复位失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 1; //返回1}else u1_printf("复位成功\r\n"); //串口提示数据u1_printf("准备设置AP模式\r\n"); //串口提示数据if(WiFi_SendCmd("AT+CWMODE=2",50)){ //设置AP模式,100ms超时单位,总计5s超时时间u1_printf("设置AP模式失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 2; //返回2}else u1_printf("设置AP模式成功\r\n"); //串口提示数据u1_printf("准备设置AP参数\r\n"); //串口提示数据u1_printf("SSID:%s\r\n",SSID); //串口提示数据u1_printf("密码:%s\r\n",PASS); //串口提示数据u1_printf("AP热点IP:%s\r\n",AP_IP); //串口提示数据u1_printf("加密方式:WPA_WPA2_PSK\r\n"); //串口提示数据u1_printf("准备设置AP热点IP\r\n"); //串口提示数据memset(temp,0,50); //清除临时缓冲区sprintf(temp,"AT+CIPAP=\"%s\"",AP_IP); //构建命令if(WiFi_SendCmd(temp,50)){ //设置AP热点IP,100ms超时单位,总计5s超时时间u1_printf("设置AP热点IP失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 3; //返回3}else u1_printf("设置AP热点IP成功\r\n"); //串口提示数据u1_printf("准备设置AP参数\r\n"); //串口提示数据if(WiFi_SET_AP(SSID,PASS,WPA_WPA2_PSK,50)){ //设置AP参数,100ms超时单位,总计5s超时时间u1_printf("设置AP参数失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 4; //返回4}else u1_printf("设置AP参数成功\r\n"); //串口提示数据u1_printf("准备关闭透传\r\n"); //串口提示数据if(WiFi_SendCmd("AT+CIPMODE=0",50)){ //关闭透传,100ms超时单位,总计5s超时时间u1_printf("关闭透传失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 5; //返回5}else u1_printf("关闭透传成功\r\n"); //串口提示数据u1_printf("准备开启多路连接\r\n"); //串口提示数据if(WiFi_SendCmd("AT+CIPMUX=1",50)){ //开启多路连接,100ms超时单位,总计5s超时时间u1_printf("开启多路连接失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 6; //返回6}else u1_printf("开启多路连接成功\r\n"); //串口提示数据u1_printf("准备开启多路连接\r\n"); //串口提示数据if(WiFi_SendCmd("AT+CIPMUX=1",50)){ //开启多路连接,100ms超时单位,总计5s超时时间u1_printf("开启多路连接失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 7; //返回7}else u1_printf("开启多路连接成功\r\n"); //串口提示数据u1_printf("准备开启服务器\r\n"); //串口提示数据if(WiFi_SendCmd("AT+CIPSERVER=1,5050",50)){ //准备开启服务器,端口号5050,100ms超时单位,总计5s超时时间u1_printf("开启服务器失败,准备重启\r\n"); //返回非0值,进入if,串口提示数据return 8; //返回8}else u1_printf("开启服务器成功,端口号5050\r\n"); //串口提示数据return 0; //正确返回0}
AT指令发送函数
wifi.c文件中
WiFi_SendCmd()函数
/*-------------------------------------------------*//*函数名:WiFi发送设置指令 *//*参 数:cmd:指令 *//*参 数:timeout:超时时间(100ms的倍数) *//*返回值:0:正确 其他:错误 *//*-------------------------------------------------*/char WiFi_SendCmd(char *cmd, int timeout){WiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区WiFi_printf("%s\r\n",cmd); //发送指令while(timeout--){ //等待超时时间到0Delay_Ms(100); //延时100msif(strstr(WiFi_RX_BUF,"OK")) //如果接收到OK表示指令成功break; //主动跳出while循环u1_printf("%d ",timeout); //串口输出现在的超时时间}u1_printf("\r\n"); //串口输出信息if(timeout<=0)return 1; //如果timeout<=0,说明超时时间到了,也没能收到OK,返回1else return 0; //反之,表示正确,说明收到OK,通过break主动跳出while}
WiFi_RxCounter=0; //WiFi接收数据量变量清零
memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区
WiFi_printf(“%s\r\n”,cmd); //发送指令
发送指令前必须清空串口2接收缓存区,
memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区 ,
否则上一条指令的响应会影响后面的判断条件
AT指令
传输模式(是否透传)
建立TCP服务器
数据收发(主函数)
main.c
while(1) //主循环{WiFi_Get_LinkSta(); //检测有无客户端连接或是断开if(WiFi_Get_Data(Data_buff,Data_len,Data_id)){ //接收数据u1_printf("连接id:%s有%s字节数据到来\r\n",Data_id,Data_len); //串口显示信息u1_printf("数据:%s\r\n",Data_buff); //串口显示信息WiFi_SendData(Char_to_Hex(Data_id,strlen(Data_id)),Data_buff,strlen(Data_buff),500);//5s的发送超时时间,发送数据}
获取sta连接状态函数
/*-------------------------------------------------*//*函数名:获取连接状态 *//*参 数:无 *//*返回值:连接状态 *//* 0:无状态 *//* 1:有客户端接入 *//* 2:有客户端断开 *//*-------------------------------------------------*/char WiFi_Get_LinkSta(void){char id_temp[10]={0}; //缓冲区,存放IDchar sta_temp[10]={0}; //缓冲区,存放状态if(strstr(WiFi_RX_BUF,"CONNECT")){ //如果接受到CONNECT表示有客户端连接sscanf(WiFi_RX_BUF,"%[^,],%[^,]",id_temp,sta_temp);u1_printf("有客户端接入,ID=%s\r\n",id_temp); //串口显示信息WiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区return 1; //有客户端接入}else if(strstr(WiFi_RX_BUF,"CLOSED")){ //如果接受到CLOSED表示有链接断开sscanf(WiFi_RX_BUF,"%[^,],%[^,]",id_temp,sta_temp);u1_printf("有客户端断开,ID=%s\r\n",id_temp); //串口显示信息WiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区return 2; //有客户端断开}else return 0; //无状态改变}


当客户端连接到服务器时,响应为CONNECT。
sscanf(WiFi_RX_BUF,”%[^,],%[^,]”,id_temp,sta_temp);
通过sscanf函数,把响应分别存放到,id_temp,sta_temp中,并向串口2打印端口号
获取sta数据函数
/*-------------------------------------------------*//*函数名:获取客户端数据 *//* 两组回车换行符\r\n\r\n作为数据的结束符 *//*参 数:data:数据缓冲区 *//*参 数:len: 数据量 *//*参 数:id: 发来数据的客户端的连接ID *//*返回值:数据状态 *//* 0:无数据 *//* 1:有数据 *//*-------------------------------------------------*/char WiFi_Get_Data(char *data, char *len, char *id){char temp[10]={0}; //缓冲区char *presult;if(strstr(WiFi_RX_BUF,"+IPD")){Delay_Ms(10); //延时sscanf(WiFi_RX_BUF,"%[^,],%[^,],%[^:]",temp,id,len);//截取各段数据,主要是id和数据长度presult = strstr(WiFi_RX_BUF,":"); //查找冒号。冒号后的是数据if( presult != NULL ) //找到冒号sprintf((char *)data,"%s",(presult+1)); //冒号后的数据,复制到dataWiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区return 1; //有数据到来} else return 0; //无数据到来}

ESP8266 接收到网络数据时向串口发送 +IPD 和数据。
格式为: +IPD,0,3:456(接收到的数据为456)
sscanf(WiFi_RX_BUF,”%[^,],%[^,],%[^:]”,temp,id,len);//截取各段数据,主要是id和数据长度
presult = strstr(WiFi_RX_BUF,”:”); //查找冒号。冒号后的是数据
if( presult != NULL ) //找到冒号
sprintf((char )data,”%s”,(presult+1)); //冒号后的数据,复制到data
*main.c
获取数据并串口2打印
收到数据后发送
/*-------------------------------------------------*//*函数名:服务器发送数据 *//*参 数:databuff:数据缓冲区<2048 *//*参 数:data_len:数据长度 *//*参 数:id: 客户端的连接ID *//*参 数:timeout: 超时时间(10ms的倍数) *//*返回值:错误值 *//* 0:无错误 *//* 1:等待发送数据超时 *//* 2:连接断开了 *//* 3:发送数据超时 *//*-------------------------------------------------*/char WiFi_SendData(char id, char *databuff, int data_len, int timeout){int i;WiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区WiFi_printf("AT+CIPSEND=%d,%d\r\n",id,data_len); //发送指令while(timeout--){ //等待超时与否Delay_Ms(10); //延时10msif(strstr(WiFi_RX_BUF,">")) //如果接收到>表示成功break; //主动跳出while循环u1_printf("%d ",timeout); //串口输出现在的超时时间}if(timeout<=0)return 1; //超时错误,返回1else{ //没超时,正确WiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区for(i=0;i<data_len;i++)WiFi_printf("%c",databuff[i]); //发送数据while(timeout--){ //等待超时与否Delay_Ms(10); //延时10msif(strstr(WiFi_RX_BUF,"SEND OK")){ //如果接受SEND OK,表示发送成功WiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区break; //跳出while循环}if(strstr(WiFi_RX_BUF,"link is not valid")){ //如果接受link is not valid,表示连接断开WiFi_RxCounter=0; //WiFi接收数据量变量清零memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区return 2; //返回2}}if(timeout<=0)return 3; //超时错误,返回3else return 0; //正确,返回0}}


WiFi_printf(“AT+CIPSEND=%d,%d\r\n”,id,data_len); //发送指令
字符0和数字0
数据格式
字符串、十进制、十六进制
数字0代表0,字符串0是一个编码,代表0x30.
wifi.c
/*-------------------------------------------------*//*函数名:字符型数字转换成数字,0-9999 *//*参 数:char_data:字符型数字 *//*参 数:len: 位数 *//*返回值:转换后的数字 *//*-------------------------------------------------*/int Char_to_Hex(char *char_data, int len){int temp;switch(len){case 1 : temp=(char_data[0]-0x30)*1;break;case 2 : temp=(char_data[0]-0x30)*10;temp+=(char_data[1]-0x30)*1;break;case 3 : temp=(char_data[0]-0x30)*100;temp+=(char_data[2]-0x30)*10;temp+=(char_data[3]-0x30)*1;break;case 4 : temp=(char_data[0]-0x30)*1000;temp+=(char_data[1]-0x30)*100;temp+=(char_data[2]-0x30)*10;temp+=(char_data[3]-0x30)*1;break;}return temp;}







