2022.3.26

因为上班赶工没有多少时间观看视频,加上自己基础很差在串口那边讲得又比较快速,反复看了很久才发打卡第六天。

主要讲的内容是:程序框架和代码实现

在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;

}

 获取IP实验截图ESP8266发送数据代码段 

/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);

}

}

}

 编译下载到板子后功能就可以实现了。

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: