因为上班赶工没有多少时间观看视频,加上自己基础很差在串口那边讲得又比较快速,反复看了很久才发打卡第六天。
主要讲的内容是:程序框架和代码实现
在usart.c 创建函数ESP8266_SendCommand//向ESP8266发送数据
uint8_t ESP8266_SendCommand(char *cmd, char *reply, uint16_t timeout)
cmd 是发送的指令
reply是返回值,返回的结果是否是OK
timeout是操作的时间,在规定时间内返回结果,如果没有在规定时间内返回结果 判定为失败。
char buf[256] = {0}; 是保存传入的指令
strcat(buf, cmd); 将两个char类型连接。将buf,cmd拼接起来
if (strstr(buf, "\r\n") == 0)
{
strcat(buf, "\r\n");
}
判断buf内是否有换行字符,有的画跳出if判断,没有的话加上换行字符
strcat查找字符串内有没有换行符
查找到有\r\n返回真值1,1不等于0跳出判断
strcat如果没有换行符将换行拼接进字符串中
在发送数据前线清理前面接收到的buf
然后马上发送数据再接收数据
接收到数据后判断是否有我们想要的reply 是否是OK
有的话 我们将我们发送的数据cmd打印出来返回值是0跳过if判断
反之timeout--操作时间-1
如果操作时间到了打印一个操作失败
返回一个1
//向ESP8266发送数据
uint8_t ESP8266_SendCommand(char *cmd, char *reply, uint16_t timeout)
{
//1.保存传入的指令
char buf[256] = {0};
strcat(buf, cmd); //strcpy
//2.处理AT指令(添加换行)
if (strstr(buf, "\r\n") == 0)
{
strcat(buf, "\r\n");
}
//3.清理前面接收的buf
USART2_ClearBuf();
//4.发送数据
USART2_Transmit((uint8_t *)buf, strlen(buf), 500);
//5.接收数据
memset(buf, 0, 256); //buf清空
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!\r\n", cmd);//发送失败
return 1;
}
将程序下载后测试 ,返回Ok
获取ESP8266IP函数
准备发送指令AT+CIFSR
定义buf数组
将AT+CIFSR拼接进buf中
轻触前面接收到的buf
然后发送数据
再将buf清空
while循环超时控制 timeout!=0,跳出循环
if判断是否接接收到数据
判断结果是否有ok
有的话将buf打印出来
否则延时-1.
延时过后未收到ok 则打印发送失败。
//获取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
USART2_ClearBuf();
//4.发送数据
USART2_Transmit((uint8_t *)buf, strlen(buf), 500);
//5.接收数据
memset(buf, 0, 256); //buf清空
while(timeout != 0) //超时控制
{
if (USART2_Receive((uint8_t *)buf)) //接收数据
{
//检查结果
if (strstr(buf, "OK"))
{
printf("%s", buf); //打印IP
return 0;
}
else
{
timeout--;
HAL_Delay(1);
}
}
}
printf("Get IP Failed! \r\n"); //获取失败
return 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_SendCommand(buf, "OK", 500) == 0) //发送指令
{
ESP8266_SendCommand(data, "SEND OK", 1000); //发送数据
return 0;
}
return 1;
}
按键代码段,按下按键,发送UDP数据
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;
}
}
主函数代码段,按下按键后发送UDP数据,之后判断是否接收到UDP数据。控制LED灯的亮灭。
if (Key_GetFlag())
{
ESP8266_Send_UDP("{\"data\":\"doorbell\",\"status\":\"1\"}");
}
//收到UDP数据
if (USART2_Receive(rx_data))
{
//printf("%s\r\n", rx_data);
if (strstr((char *)rx_data, "\"dev\":\"led\",\"status\":\"0\""))
{
printf("led off\r\n");
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
USART2_ClearBuf();
memset(rx_data, 0, 200);
}
else if (strstr((char *)rx_data, "\"dev\":\"led\",\"status\":\"1\""))
{
printf("led on\r\n");
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
USART2_ClearBuf();
memset(rx_data, 0, 200);
}
}
}
编译下载到板子后功能就可以实现了。