百问网7天物联网智能家居 学习心得 打卡第六天

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

百问网7天物联网智能家居 学习心得 打卡第六天_第1张图片

 获取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实验截图百问网7天物联网智能家居 学习心得 打卡第六天_第2张图片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);			 
		 }
	 }
	  
  }

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

你可能感兴趣的:(物联网,stm32,单片机)