延时函数初始化,单片机指令执行速度过快,向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--){ //等待超时时间到0
Delay_Ms(100); //延时100ms
if(strstr(WiFi_RX_BUF,"OK")) //如果接收到OK表示指令成功
break; //主动跳出while循环
u1_printf("%d ",timeout); //串口输出现在的超时时间
}
u1_printf("\r\n"); //串口输出信息
if(timeout<=0)return 1; //如果timeout<=0,说明超时时间到了,也没能收到OK,返回1
else 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}; //缓冲区,存放ID
char 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)); //冒号后的数据,复制到data
WiFi_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); //延时10ms
if(strstr(WiFi_RX_BUF,">")) //如果接收到>表示成功
break; //主动跳出while循环
u1_printf("%d ",timeout); //串口输出现在的超时时间
}
if(timeout<=0)return 1; //超时错误,返回1
else{ //没超时,正确
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); //延时10ms
if(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; //超时错误,返回3
else 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;
}