前言:以下内容基于 百问网 黄老师的 7天实战训练的个人总结
第6节主要学习了基于STM32F103C8T6的WIFI模块ESP8266的连接软件编写:
主要内容为UDP的连接,正常的通信流程如下:
//在头文件里进行声明
uint8_t ESP8266_SendCommand(char *cmd,char *reply,uint16_timeout);
//向ESP8266发送数据的函数
uint8_t ESP8266_SendCommand(char *cmd,char *reply,uint16_timeout)
{
//1.保存传入的指令
char buf[256] = {0};
strcat(buf,cmd);
//2.处理AT指令(如果buf内没有"\r\n",则添加)
if(strstr(buf,"\r\n")==0)
{
strcat(buf,"\r\n"); // 添加换行
}
//3.清理之前接收在BUF里面的数据
ClearBuf();
//4.发送数据((uint8_t *)buf为强制类型转换)
USART2_Transmit((uint8_t)buf,strlen(buf),500);
//5.接收数据
memset(buf,0,256); //数据清空
while(timeout !=0) //超时控制
{
if(USART2_Receive((uint8_t *)buf) //接收数据
{
if(strstr(buf,reply)) //检查结果
{
printf("%s Send ok ! \r\n",cmd) //发送成功打印信息,并加入换行。
return 0;
}
else
{
timeout--;
HAL_Delay(1);
}
}
}
printf("%s Send error !",cmd)//发送失败打印
return 1;
}
按UDP通信的顺序在main函数内增加指令:
ESP8266_SendCommand("AT+RST","OK","200"); //模块复位
HAL_Delay(800); //因为复位后信息较多,会对后续指令接收造成影响,所以增加延时
ESP8266_SendCommand("AT+CWMODE=1","OK","200");//模式设置
ESP8266_SendCommand("AT+CWJAP=\"NETGEAR\",\"100ask.cq\"","OK","3000");//WIFI连接
ESP8266_SendCommand("AT+CIPSTART=\"UDP\",\"192.168.50.230\",9999,9999,2","OK","500");//通讯连接
获取IP就不能用这个函数了,所以要单独建立一个IP获取函数:
//获取ESP8266的IP
uint8_t ESP8266_GetIP(void)
{
uint16_t timeout =500 ;
//1.准备发送的指令AT+CIFSR
char buf[256] = {0};
strcat(buf,"AT+CIFSR\r\n");
//2.清理之前接收在BUF里面的数据
ClearBuf();
//4.发送数据((uint8_t *)buf为强制类型转换)
USART2_Transmit((uint8_t)buf,strlen(buf),500);
//5.接收数据
memset(buf,0,256); //数据清空
while(timeout !=0) //超时控制
{
if(USART2_Receive((uint8_t *)buf) //接收数据
{
if(strstr(buf,"OK")) //检查结果
{
printf("%s ,buf) //发送成功打印信息,并加入换行。
return 0;
}
else
{
timeout--;
HAL_Delay(1);
}
}
}
printf("%Get IP Failed ! \r\n");//获取失败
return 1;
}
接下来配置下KEY的函数
static uint8_t key_flag = 0;
uint8_t key_GetFlag(void)
{
if(key_flag)
{
key_flag = 0;
return 1;
}
else
return 0;
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == KEY_Pin)
{
key_flag = 1;
}
}
增加发送数据函数
//ESP8266发送UDP数据
uint8_t ESP8266_Send_UDP(char *data)
{
//1.准备发送的指令 AT+CIPSEND = len
char buf[256] = {0};
uint8_t len =strlen(data);
sprintf(buf,"AT+CIPSEND=%d\r\n",len);//把格式化数据写入
if(ESP8266_SendConmmand(buf,"OK",500)==0) //发送指令
{
ESP8266_SendConmmand(data,"SEND OK",1000);//发送数据
return 0;
}
return 1;
}
在主函数主循环中增加功能调用,注意此发送格式为与微信小程序相匹配的,如果与其他设备对接需按其协议要求内容发送。
while(1)
{
if(Key_GetFlag())//如果按键被按下
{
ESP8266_Send_UDP("{\"data\":\"doorbell\",\"status\":\"1\"}");
}
}
以上发送数据部分就完成了,接下来增加接收数据的部分。
if(USART2_Receive(rx_data))
{
if(strstr((char *)rx_data,"\"dev\":\"led\",\"status\":\"0\""))//收到的指令状态为“0”
{
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET); // LED灯 灭
USART2_ClearBUF(); //清除串口缓存数据
memset(rx_data,0,200); //清除data缓存数据
}
else if(strstr((char *)rx_data,"\"dev\":\"led\",\"status\":\"1\""))//指令状态为“1”
{
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);// LED灯 亮
USART2_ClearBUF(); //清除串口缓存数据
memset(rx_data,0,200); //清除data缓存数据
}
}
所有代码编写完成,打开微信小程序。开发板按键发送IP地址,将小程序的IP和端口按要求设置好。点台灯按钮,开发板上LED随着小程序的状态亮灭。