前言

采用stm32f103vet6作为主控芯片,使用stm32的RTC外设获取时间,控制esp8266获取天气数据,然后使用0.96寸oled进行显示。

一、原理图

 

stm32 ESP8266连接心知天气 esp8266与stm32连接原理图_c语言

1、esp8266通过串口发送和接收消息,这里我接的是stm32的USART3;其中esp8266的RST引脚和EN引脚可以直接接3.3V高电平,因为我使用的野火指南者板子的esp8266是板载的,所以需要单独配置引脚;

2、我使用的是0.96寸I2C接口的oled显示屏,连接stm32的I2C1引脚,使用硬件I2C控制oled。

二、代码编写步骤

1.配置串口:

使用CubeMX软件初始化stm32的USART1和USART3串口(使用默认配置就行),并使能串口中断;编写串口的中断回调函数,代码如下:

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
	if(huart == &huart1)
	{
		g_uart1_rx.buf[g_uart1_rx.size++] = aRxBuffer_rx1;   									//接收数据转存
		if((g_uart1_rx.buf[g_uart1_rx.size-1] == 0x0A)&&(g_uart1_rx.buf[g_uart1_rx.size-2] == 0x0D))	//判断结束位
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart1_rx.buf, g_uart1_rx.size,0xFFFF);	//将收到的信息发送出去
					while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);			//检测UART发送结束
			g_uart1_rx.size = 0;
			memset(g_uart1_rx.buf,0x00,sizeof(g_uart1_rx.buf));									//清空数组
		}
		HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer_rx1, 1);						//再开启接收中断
	}
	if(huart == &huart3)
	{
		g_uart3_rx.buf[g_uart3_rx.size++] = aRxBuffer_rx3;   									//接收数据转存
	
		if((g_uart3_rx.buf[g_uart3_rx.size-1] == 'K')&&(g_uart3_rx.buf[g_uart3_rx.size-2] == 'O'))	
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart3_rx.buf, g_uart3_rx.size,0xFFFF);	//将收到的信息发送出去
				while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);			//检测UART发送结束
			g_uart3_rx.size = 0;
			memset(g_uart3_rx.buf,0x00,sizeof(g_uart3_rx.buf));									//清空数组
		}
		else if((g_uart3_rx.buf[g_uart3_rx.size-2] == ']')&&(g_uart3_rx.buf[g_uart3_rx.size-1] == '}')
			&&(g_uart3_rx.buf[g_uart3_rx.size-3] == '}'))
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart3_rx.buf, g_uart3_rx.size,0xFFFF);	//将收到的信息发送出去
			while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);			//检测UART发送结束				
			strcpy(Data_buff,(char *)g_uart3_rx.buf);
			temp = 1;
			g_uart3_rx.size = 0;				
			memset(g_uart3_rx.buf,0x00,sizeof(g_uart3_rx.buf));									//清空数组

		}
		HAL_UART_Receive_IT(&huart3, (uint8_t *)&aRxBuffer_rx3, 1);						//再开启接收中断
	}
	
}

代码实现的主要功能:能将usart1接收到的信息重新发送出去,判断串口usart3接收到的消息(这里主要是esp8266回传的信息)通过串口1发送给电脑的串口助手,用来调试查看信息是否正确。

2.配置RTC外设

这里我就直接跳过了,网上很多教程;

3.EPS8266配置和数据处理

通过串口3发送AT指令控制eps8266连接心知天气;

首先需要注册心知天气账号(https://www.seniverse.com/),获取自己的密钥,替换心知天气api中的Key;具体的配置我就不详细说明了,网上有很多。

发送AT指令的代码如下:

void SendATCmd(char *cmd, int waitms) 
{ // 发送AT指令给串口3
	if (NULL != cmd)
	{
		HAL_UART_Transmit(&huart3, (uint8_t *)cmd, strlen(cmd), 0xFFFF);	
		if (waitms > 0)
			HAL_Delay(waitms);  // 延时等待ESP01模块应答时间
	}
}

基本的AT指令配置如下:

void esp8266_config(void)
{
		char str[200];
		sprintf(str, "AT+CWJAP=\"%s\",\"%s\"\r\n", WIFI_NAME, WIFI_PSW);
//		SendATCmd("+++", 500);				// 退出透传模式
		SendATCmd("AT\r\n", 2000);			// 测试ESP01模块是否存在
//		SendATCmd("AT+GMR\r\n",3000);	// 查看模块版本信息
		SendATCmd("AT+CWMODE=1\r\n", 2000);	// 开启STA+AP模式 ==================		
		SendATCmd("AT+RST\r\n", 3000);	
		SendATCmd(str, 10000);	// 连接无线路由器或者手机热点,等待10秒 ============
		SendATCmd("AT+CIPMUX=0\r\n", 2000);	// 关闭多连接
		SendATCmd("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n", 2000);	// 连接心知天气TCP服务器
		SendATCmd("AT+CIPMODE=1\r\n", 500);	// 开启透传模式
		SendATCmd("AT+CIPSEND\r\n", 500);		// 开始透传
}

开始透传之后就可以发送get请求,这时串口3就会接收到天气信息,我们就可以将天气信息进行保存和处理。

stm32 ESP8266连接心知天气 esp8266与stm32连接原理图_单片机_02

信息处理代码如下:

char *p;
			p =	strstr(Data_buff,"text_day");				//查找天气			
			sscanf(p+11,"%[^\"]",weather);	
			OLED_ShowString(40,0,(uint8_t*)weather,16);			
			p = strstr(Data_buff,"high");								//查找气温
			temperature[0]=atoi(p+7);
			p = strstr(Data_buff,"low");
			temperature[1]=atoi(p+6);

将接收到的天气信息存储到Data_buff字符串,采用strstr(),sscanf(),atoi()等字符串处理函数,将天气情况和最高气温和最低气温从字符串中取出来;

1、首先使用strstr()函数,找到子字符串“text_day”的位置,使用指针变量p存储子字符串出现的首地址;

2、接着使用sscanf()函数取出“text_day”后面代表天气的字符串并保存;

3、继续使用strstr()函数找到“high”和“low”代表天气温度的字符串,再使用atoi()强制转换函数,将两个代表天气字符串后面跟着的数字转换成整型数,最后保存在数组中。

三、显示效果

能实时显示时间,约半分钟刷新天气和气温信息

stm32 ESP8266连接心知天气 esp8266与stm32连接原理图_物联网_03

 

总结

上面的就随便写写,具体的还是看我附的源码;我觉得最有收获的就是对数据的处理,c语言虽然学过字符串处理函数,但是很少用到实际的代码中,看来还是要好好学习c语言。