STM32+ESP8266获取时间和天气

ESP8266获取天气数据


文章目录

  • ESP8266获取天气数据
    • 通过HC05配置ESP01s将获取时间和天气显示到TFT1.3寸彩屏上
    • 必读
    • 心知天气注册
    • 串口AT调试
      • AT测试
      • 设置wifi模式
      • 重启模块
      • 连接WIFI
      • 建立TCP连接
      • 开启透传模式
      • 开始透传
      • 提出请求
    • 程序例程
      • 硬件连线
      • 软件设计
      • 代码
        • esp8266.h
        • esp8266.c
        • USART_LY.h
        • USART_LY.c
        • TFToled.h
        • TFToled.c
        • main.c
    • 工程演示
    • 感谢


通过HC05配置ESP01s将获取时间和天气显示到TFT1.3寸彩屏上

必读

在文章最后我会给出百度网盘链接,尽管如此还是希望大家认真观看文章,并琢磨程序代码逻辑在我的基础上可以改出属于自己特点的工程!

对于ESP8266 AT指令不熟悉的可以观看我的上一篇文章 认识 ESP8266—ESP-01S (含AT指令)

心知天气注册

登陆心知天气官网,注册

https://www.seniverse.com/

注册完成后点击“产品”,进入“天气数据”
STM32+ESP8266获取时间和天气_第1张图片

点击“立即免费试用”
STM32+ESP8266获取时间和天气_第2张图片

点击免费版的“免费申请”
STM32+ESP8266获取时间和天气_第3张图片

申请后可查看到自己的私钥(自行保存后面需要用到)
STM32+ESP8266获取时间和天气_第4张图片

重新点击“产品”—>“天气数据”,点击“查看API文档”
STM32+ESP8266获取时间和天气_第5张图片

点击"天气实况",打开对应的API接口文档
STM32+ESP8266获取时间和天气_第6张图片
查看天气实况的接口地址,以及返回的数据结果示例(自行保存后面需要用到)
STM32+ESP8266获取时间和天气_第7张图片

串口AT调试

指令关键字 指令作用 响应
AT 测试指令 OK
AT+RST 重启模块指令 OK
AT+GMR 查看版本信息 AT version,SDK version,company,date,OK
ATE 开关回显功能ATE关闭回显,ATE开启回显 OK
AT+RESTORE 恢复出厂设置 OK
AT+UART 设置串口配置 OK
AT+CWMODE=mode 设置WiFi应用模式 OK
AT+CWMODE? 响应返回当前模块的模式 +CWMODE:mode;OK
AT+CWLIF 查看已接入设备的IP 已连接所有设备的IP地址
AT+CIPMUX 启动多连接 OK
AT+CWJAP 加入AP OK
AT+CWQAP 退出与AP的连接 OK
AT+CWSMARTSTART 启动智能连接 OK或者ERROR
AT+CWSMARTSTOP 停止智能连接 OK或者ERROR

使用AT指令获取到天气情况,这里列出对应的AT指令
串口助手波特率设置位115200,其他设置默认即可

AT测试

发送 “AT” :正常启动就会响应“OK”

AT

在这里插入图片描述

设置wifi模式

  • Station模式 :ESP32连接到接入点
  • AP模式 :热点模式
  • Station+AP模式 :(两种模式共存)

使用串口发送指令AT+CWMODE=1设置模块Wi_Fi应用模式为Station模式

AT+CWMODE=1

在这里插入图片描述
STM32+ESP8266获取时间和天气_第8张图片

重启模块

发送指令AT+RST使模块重启,重启后等待一段时间

AT+RST

在这里插入图片描述

连接WIFI

发送指令AT+CWJAP=“ssid”,“pwd”,ssid就是你要连接WiFi的名字,pwd就是密码

AT+CWJAP="amh","12345678"

在这里插入图片描述
在这里插入图片描述

建立TCP连接

发送指令AT+CIPSTART=“TCP”,“api.seniverse.com”,80,和心知天气建立TCP连接

AT+CIPSTART="TCP","api.seniverse.com",80

在这里插入图片描述

开启透传模式

发送指令“AT+CIPMODE=1”设置成功则返回OK

AT+CIPMODE=1

STM32+ESP8266获取时间和天气_第9张图片

在这里插入图片描述

开始透传

发送指令“AT+CIPSEND” 开始透传

AT+CIPSEND

在这里插入图片描述

提出请求

发送“GET https://api.seniverse.com/v3/weather/now.json?key=私钥&location=城市拼音&language=zh-Hans&unit=c”向网址提出请求

GET https://api.seniverse.com/v3/weather/now.json?key=私钥&location=城市&language=zh-Hans&unit=c

STM32+ESP8266获取时间和天气_第10张图片

这里的location可以改为自己的城市,我的是西安(XiAn)
私钥为心知天气中获取到的私钥
语言language用的是中文(zh-Hans),这部分可以自行到心知天气官网的文档查看

注意:设置zh-Hans可能会乱码,建议改成en(返回英文)

程序例程

硬件连线

MCU ESP8266
3.3V VCC
GND GND
PB10 RXD
PB11 TXD
3.3V IO
3.3V RST
MCU USB转TTL
5V VCC
GND GND
PA9 RXD
PA10 TXD
MCU TFT1.3彩屏
5V VCC
GND GND
PA5 SCL
PA7 SDA
PB0 RES
PB1 DC
A4 BLK
MCU HC-05
5V VCC
GND GND
PA2 RXD
PA3 TXD

软件设计

  • 使用ESP-01s模块从心知天气获取天气数据数据,使用cJSON包解析数据包。
  • 使用的串口USART3给ESP-01s模块发送AT指令。
  • 使用串口USART1回显ESP-01s返回的数据,到上位机。
  • 使用HC-05模块通过手机APP给ESP-01s模块配置简单的AT指令。
  • 使用串口USART2接收HC-05模块传过来的AT命令,当做参数,给串口USART3,并且使用使用串口USART2回显ESP-01s模块返回的数据到手机APP中
  • 将显示回来的时间,使用定时器一秒加1,来维持时间的正确性(具有误差2-3秒)。
  • 使用TFT1.3寸彩屏,排版显示数据内容
  • 使用了独立看门狗来检测程序是否正常运行,2秒一次喂狗
  • 使用定时器每15分钟更新一次天气和时间

代码

这里只给了部分代码,在文章最后会给出百度网盘链接,尽管如此还是希望大家认真观看。

esp8266.h
#ifndef __ESP8266_H
#define __ESP8266_H
#include "sys.h"
#include "stdio.h"	
#include "oled.h"
#include  
//子对象1结构体--Location
typedef struct
{
	char id[32];
	char name[32];
	char country[32];
	char path[64];
	char timezone[32];
	char timezone_offset[32];
}Location;
 
//子对象2结构体--Now
typedef struct
{
	char text[32];
	char code[32];
	char temperature[32];
}Now;

typedef struct
{
	Location location;		//子对象1
	Now now;				//子对象2
	char last_update[64];	//子对象3
}Results;

typedef struct   //结构体。
{
    vu16  year;
    vu8   month;
    vu8   date;
    vu8   hour;
    vu8   min;
    vu8   sec;	 
}nt_calendar_obj;	 

//用户配置AT指令的函数

//检查WIFI模块是否在线
bool esp_wifi_on_line(char *at);
//设置工作模式 1:station模式   2:AP模式  3:兼容 AP+station模式
bool esp_work_pattern(char *at);
//esp重启
bool esp_restart(char *at);
//esp设置连接模式
bool esp_Connection_mode(char *at);
//esp连接wifi
bool esp_link_WIFI(char *at);

//函数

u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime);
u8* esp8266_send_data(u8 *cmd,u16 waittime);
u8* esp8266_check_cmd(u8 *str);
void esp8266_start_trans(void);
u8 esp8266_quit_trans(void);
u8 get_current_weather(void);
u8 cloes_weather(void);
u8 get_weather(void);
u8 esp8266_quit_trans(void);
int cJSON_WeatherParse(char *JSON, Results *results);


void atk_8266_get_wanip(u8* ipbuf);
u8 get_beijing_time(void);
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);
u8* atk_8266_check_cmd(u8 *str);
u8 Is_Leap_Year(u16 year);
#endif

esp8266.c
#include "esp8266.h"
#include "string.h"
#include "usart.h"
#include "usart3.h"
#include "stm32f10x.h"
#include "sys.h" 
#include "delay.h"
#include "led.h"
#include "stdlib.h"
#include "malloc.h"
#include "cJSON.h"
#include  
#include "USART_LY.h"
#include "bsp_systick.h"
nt_calendar_obj nwt;  //定义结构体变量


//const u8* wifista_ssid="59";							//路由器SSID号
//const u8* wifista_password="12345678"; 				//连接密码

#define WEATHER_PORTNUM 	"80"						//天气连接端口号:80	
#define WEATHER_SERVERIP 	"api.seniverse.com"			//天气服务器IP


#define TIME_PORTNUM			"80"					//时间端口号
#define TIME_SERVERIP			"www.beijing-time.org"	//时间服务器IP


//月份数据表											 
u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; 		//月修正数据表	  
//平年的月份日期表
const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};



u8 *p;
Results results[] = {{0}};
extern char USART2_RX_BUF[USART2_MAX_RECV_LEN];
extern vu16 USART2_RX_STA;
/*********************************************************************************
* Function Name    : esp8266_start_trans,ESP8266初始化设置
* Parameter		   : 
* Return Value     : 
* Function Explain : 连接wifi
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
void esp8266_start_trans(void)
{
	int i=0;
  while(esp_wifi_on_line(USART2_RX_BUF))
	{
			i++;
		  if(i==5)
			{
			LY_Printf("err");
			printf("\r\nAT指令输入有误,重新输入\r\n");
			USART2_RX_BUF[0]='\0';
			i=0;
			}
	}
	//设置工作模式 1:station模式   2:AP模式  3:兼容 AP+station模式
	i=0;
	while(esp_work_pattern(USART2_RX_BUF))
	{
	    i++;
		  if(i==5)
			{
			LY_Printf("err");
			printf("\r\nAT指令输入有误,重新输入\r\n");
			USART2_RX_BUF[0]='\0';
			i=0;
			}
	}
	//Wifi模块重启
	i=0;
  esp_restart(USART2_RX_BUF);

	//设置连接到的WIFI网络名称/加密方式/密码,这几个参数需要根据您自己的路由器设置进行修改!! 
	
	//esp设置连接模式
	i=0;
  while(esp_Connection_mode(USART2_RX_BUF))
	{
		  
			i++;
		
		  if(i==5)
			{
			LY_Printf("err");
			printf("\r\nAT指令输入有误,重新输入\r\n");
			USART2_RX_BUF[0]='\0';
			i=0;
			}
	}
	
	//连接目标路由器,并且获得IP
	i=0;
  while(esp_link_WIFI(USART2_RX_BUF))			
	{
			i++;
		  printf("\r\n%d\r\n",i);
		  if(i==5)
			{
			LY_Printf("err");
			printf("\r\nAT指令输入有误,重新输入\r\n");
			USART2_RX_BUF[0]='\0';
			i=0;
			}
	}		
}
//检查WIFI模块是否在线
bool esp_wifi_on_line(char *at)
{
	printf("检查WIFI模块是否在线\r\n");	
	while(USART2_RX_BUF[0]=='\0')
	{
	}	
  
	delay_ms(1000);
  return esp8266_send_cmd(at,"OK",20);		//检查WIFI模块是否在线	
	
}

//设置工作模式 1:station模式   2:AP模式  3:兼容 AP+station模式
bool esp_work_pattern(char *at)
{
	printf("\r\n设置工作模式\r\n");	
	while(USART2_RX_BUF[0]=='\0')
	{
	}	
	
	delay_ms(1000);
	return esp8266_send_cmd(at,"OK",50);;	
}
//esp重启
bool esp_restart(char *at)
{
	printf("\r\nesp重启\r\n");	
	while(USART2_RX_BUF[0]=='\0')
	{
	}
	esp8266_send_cmd(at,"OK",20);	//延时4S等待重启成功
	delay_ms(1000);	
	delay_ms(1000);	
	delay_ms(1000);	
	delay_ms(1000);	
	USART2_RX_BUF[0]='\0';
	//Wifi模块重启	
	LY_Printf("OK");
	return 1;
}
//esp设置连接模式
bool esp_Connection_mode(char *at)
{ 
	printf("\r\n设置连接模式\r\n");	
	while(USART2_RX_BUF[0]=='\0')
	{
	}	
	return esp8266_send_cmd(at,"OK",20);   		//0:单连接,1:多连接		;	
}
//esp连接wifi
bool esp_link_WIFI(char *at)
{ 
	printf("\r\nesp连接wifi\r\n");	
	while(USART2_RX_BUF[0]=='\0')
	{
	}
	return esp8266_send_cmd(at,"WIFI GOT IP",300);									//连接目标路由器,并且获得IP;
  delay_ms(1000);	
	
}


/*********************************************************************************
* Function Name    : esp8266_send_cmd,向ESP8266发送命令
* Parameter		   : cmd:发送的命令字符串;ack:期待的应答结果,如果为空,则表示不需要等待应答;waittime:等待时间(单位:10ms)
* Return Value     : 返回值:0,发送成功(得到了期待的应答结果);1,发送失败
* Function Explain : 
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
	u8 res=0; 
	USART3_RX_STA=0;
	delay_ms(1000);
	u3_printf("%s\r\n",cmd);	//发送命令
	printf("发送命令了-->%s\r\n",cmd);
	if(ack&&waittime)		//需要等待应答
	{
		while(--waittime)	//等待倒计时
		{
			delay_ms(10);
			if(USART3_RX_STA&0X8000)//接收到期待的应答结果
			{
			  u8 *a=	esp8266_check_cmd(ack);
				if(esp8266_check_cmd(ack))
				{
					printf("receive:%s\r\n",(u8*)ack);
					LY_Printf(ack);
					USART2_RX_BUF[0]='\0';
					break;//得到有效数据 
				}
					USART3_RX_STA=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
} 


/*********************************************************************************
* Function Name    : esp8266_check_cmd,ESP8266发送命令后,检测接收到的应答
* Parameter		   : str:期待的应答结果
* Return Value     : 返回值:0,没有得到期待的应答结果;其他,期待应答结果的位置(str的位置)
* Function Explain : 
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
u8* esp8266_check_cmd(u8 *str)
{
	char *strx=0;
	if(USART3_RX_STA&0X8000)		//接收到一次数据了
	{ 
		USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
		strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
	} 
	return (u8*)strx;
}


/*********************************************************************************
* Function Name    : esp8266_quit_trans,ATK-ESP8266退出透传模式
* Parameter		   : 
* Return Value     : 返回值:0,退出成功;1,退出失败
* Function Explain : 
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
u8 esp8266_quit_trans(void)
{
	while((USART3->SR&0X40)==0);	//等待发送空
	USART3->DR='+';      
	delay_ms(15);					//大于串口组帧时间(10ms)
	while((USART3->SR&0X40)==0);	//等待发送空
	USART3->DR='+';      
	delay_ms(15);					//大于串口组帧时间(10ms)
	while((USART3->SR&0X40)==0);	//等待发送空
	USART3->DR='+';      
	delay_ms(500);					//等待500ms
	printf("退出看透传模式\r\n");
	return esp8266_send_cmd("AT","OK",20);//退出透传判断.
}


/*********************************************************************************
* Function Name    : get_current_weather,获取一次实时天气
* Parameter		   : 
* Return Value     : 返回:0---获取成功,1---获取失败
* Function Explain : 
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
u8 get_current_weather(void)
{
	u8 res;

	p=mymalloc(SRAMIN,40);							//申请40字节内存
	
	
	sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",WEATHER_SERVERIP,WEATHER_PORTNUM);    //配置目标TCP服务器
//	printf("send:AT+CIPSTART=\"TCP\",\"%s\",%s\r\n",WEATHER_SERVERIP,WEATHER_PORTNUM);
	res = esp8266_send_cmd(p,"OK",200);//连接到目标TCP服务器

	delay_ms(300);
	
	printf("send:AT+CIPMODE=1\r\n");	
	esp8266_send_cmd("AT+CIPMODE=1","OK",100);      //传输模式为:透传	

	USART3_RX_STA=0;
	printf("send:AT+CIPSEND\r\n");	
	esp8266_send_cmd("AT+CIPSEND","OK",100);         //开始透传
	printf("start trans...\r\n");

	u3_printf("GET https://api.seniverse.com/v3/weather/now.json?key=SBE-txu7v25szUfOf&location=XiAn&language=en&unit=c\n\n");	
	delay_ms(20);//延时20ms返回的是指令发送成功的状态
	USART3_RX_STA=0;	//清零串口3数据
	delay_ms(1000);
	if(USART3_RX_STA&0X8000)		//此时再次接到一次数据,为天气的数据
	{ 
		USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
	} 
	printf("USART3_RX_BUF=%s\r\n",USART3_RX_BUF);
	
	cJSON_WeatherParse(USART3_RX_BUF, results);		//解析天气数据
	//打印结构体内内容
	printf("打印结构体内内容如下: \r\n");
	printf("%s \r\n",results[0].now.text);
	printf("%s \r\n",results[0].now.temperature);
	
	esp8266_quit_trans();//退出透传
		
	esp8266_send_cmd("AT+CIPCLOSE","OK",50);         //关闭连接
	myfree(SRAMIN,p);
	return 0;
}



/*********************************************************************************
* Function Name    : cJSON_WeatherParse,解析天气数据
* Parameter		   : JSON:天气数据包  results:保存解析后得到的有用的数据
* Return Value     : 0:成功 其他:错误
* Function Explain : 
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
int cJSON_WeatherParse(char *JSON, Results *results)
{
	cJSON *json,*arrayItem,*object,*subobject,*item;
	
	json = cJSON_Parse(JSON); //解析JSON数据包
	if(json == NULL)		  //检测JSON数据包是否存在语法上的错误,返回NULL表示数据包无效
	{
		printf("Error before: [%s] \r\n",cJSON_GetErrorPtr()); //打印数据包语法错误的位置
		return 1;
	}
	else
	{
		if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL) //匹配字符串"results",获取数组内容
		{
			int size = cJSON_GetArraySize(arrayItem);     //获取数组中对象个数
			printf("cJSON_GetArraySize: size=%d \r\n",size); 
			
			if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容
			{
				/* 匹配子对象1 */
				if((subobject = cJSON_GetObjectItem(object,"location")) != NULL)
				{
					printf("---------------------------------subobject1-------------------------------\r\n");
					if((item = cJSON_GetObjectItem(subobject,"id")) != NULL)   //匹配子对象1成员"id"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].location.id,item->valuestring,strlen(item->valuestring));
					}
					if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //匹配子对象1成员"name"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].location.name,item->valuestring,strlen(item->valuestring));
					}
					if((item = cJSON_GetObjectItem(subobject,"country")) != NULL)//匹配子对象1成员"country"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].location.country,item->valuestring,strlen(item->valuestring));
					}
					if((item = cJSON_GetObjectItem(subobject,"path")) != NULL)  //匹配子对象1成员"path"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].location.path,item->valuestring,strlen(item->valuestring));
					}
					if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL)//匹配子对象1成员"timezone"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].location.timezone,item->valuestring,strlen(item->valuestring));
					}
					if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL)//匹配子对象1成员"timezone_offset"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].location.timezone_offset,item->valuestring,strlen(item->valuestring));
					}
				}
				/* 匹配子对象2 */
				if((subobject = cJSON_GetObjectItem(object,"now")) != NULL)
				{
					printf("---------------------------------subobject2-------------------------------\r\n");
					if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)//匹配子对象2成员"text"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].now.text,item->valuestring,strlen(item->valuestring));
					}
					if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)//匹配子对象2成员"code"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].now.code,item->valuestring,strlen(item->valuestring));
					}
					if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //匹配子对象2成员"temperature"
					{
						printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
						memcpy(results[0].now.temperature,item->valuestring,strlen(item->valuestring));
					}
				}
				/* 匹配子对象3 */
				if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL)
				{
					printf("---------------------------------subobject3-------------------------------\r\n");
					printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",subobject->type,subobject->string,subobject->valuestring);
					memcpy(results[0].last_update,item->valuestring,strlen(subobject->valuestring));
				}
			} 
		}
	}
	
	cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间
	
	return 0;
}


/*********************************************************************************
* Function Name    : get_beijing_time,获取时间
* Parameter		   : 
* Return Value     : 返回:0---获取成功,1---获取失败
* Function Explain : 
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
u8 get_beijing_time(void)
{
	u8 *p;
	u8 res;
	
	u8 *resp;
	u8 *p_end;
	u8 ipbuf[16]; 	//IP缓存
	p=mymalloc(SRAMIN,40);							//申请40字节内存
	resp=mymalloc(SRAMIN,10);
	p_end=mymalloc(SRAMIN,40);
	
	sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",TIME_SERVERIP,TIME_PORTNUM);    //配置目标TCP服务器
	printf("%s",p);
	res = esp8266_send_cmd(p,"OK",200);//连接到目标TCP服务器

	delay_ms(300);
	esp8266_send_cmd("AT+CIPMODE=1","OK",100);      //传输模式为:透传	

	esp8266_send_cmd("AT+CIPSEND","OK",100);         //开始透传
	printf("start trans...\r\n");

	u3_printf("GET /time15.asp HTTP/1.1Host:www.beijing-time.org\n\n");

	delay_ms(20);//延时20ms返回的是指令发送成功的状态
	USART3_RX_STA=0;	//清零串口3数据
	delay_ms(1000);
	if(USART3_RX_STA&0X8000)		//此时再次接到一次数据,为天气的数据
	{ 
		USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
	} 
	
	printf("USART3_RX_BUF=%s\r\n",USART3_RX_BUF);	
	//USART3_RX_BUF 为时间信息
	if(USART3_RX_STA & 0x8000)
	{
			resp="Date";
			USART3_RX_BUF[USART3_RX_STA & 0x7ff] = 0;
			printf("get_tim_srt:%s\r\n",USART3_RX_BUF);
			if(strstr((char*)USART3_RX_BUF,(char*)resp)) 
			{       
				resp="GMT";
				p_end = (u8*)strstr((char*)USART3_RX_BUF,(char*)resp);
				p = p_end - 9; 
				printf("get_net_str %s\r\n",p);
				nwt.hour = ((*p - 0x30)*10 + (*(p+1) - 0x30) + 8) % 24;  //GMT0-->GMT8

				nwt.min = ((*(p+3) - 0x30)*10 + (*(p+4) - 0x30)) % 60;

				nwt.sec = ((*(p+6) - 0x30)*10 + (*(p+7) - 0x30)) % 60;

				nwt.year = ((*(p-5) - 0x30)*1000 + (*(p-4) - 0x30)*100+ (*(p-3) - 0x30)*10+ (*(p-2) - 0x30)); 

				nwt.date = ((*(p-12) - 0x30)*10 + (*(p-11) - 0x30)); 

				if        ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Jan")) nwt.month=1; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Feb")) nwt.month=2; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Mar")) nwt.month=3; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Apr")) nwt.month=4; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "May")) nwt.month=5; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Jun")) nwt.month=6; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Jul")) nwt.month=7; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Aug")) nwt.month=8; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Sep")) nwt.month=9; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Oct")) nwt.month=10; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Nov")) nwt.month=11; 
				else if   ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Dec")) nwt.month=12;


				printf("nwt.year = %d\r\n",nwt.year);
				printf("nwt.month = %d\r\n",nwt.month);
				printf("nwt.date = %d\r\n",nwt.date);  //获取data 28日

				printf("nwt.hour = %d\r\n",nwt.hour);
				printf("nwt.min = %d\r\n",nwt.min);
				printf("nwt.sec = %d\r\n",nwt.sec);

				USART3_RX_STA = 0;

				printf("uddate:nettime!!!");
		}
		USART3_RX_STA = 0;																
		myfree(SRAMIN,resp);
		myfree(SRAMIN,p_end);
																
						
    }               
	printf("\r\n\r\n");
	esp8266_quit_trans();//退出透传
	esp8266_send_cmd("AT+CIPCLOSE","OK",50);         //关闭连接
	printf("获取数据成功");
	myfree(SRAMIN,p);
	return 0;
}


/*********************************************************************************
* Function Name    : atk_8266_check_cmd,ATK-ESP8266发送命令后,检测接收到的应答
* Parameter		   : str:期待的应答结果
* Return Value     : 返回值:0,没有得到期待的应答结果,其他,期待应答结果的位置(str的位置)
* Function Explain : 
**********************************************************************************/
u8* atk_8266_check_cmd(u8 *str)
{
	
	char *strx=0;
	if(USART3_RX_STA&0X8000)		//接收到一次数据了
	{ 
		USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
		strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
	} 
	return (u8*)strx;
}


/*********************************************************************************
* Function Name    : atk_8266_send_cmd,向ATK-ESP8266发送命令
* Parameter		   : cmd:发送的命令字符串,ack:期待的应答结果,如果为空,则表示不需要等待应答,waittime:等待时间(单位:10ms)
* Return Value     : 返回值:0,发送成功(得到了期待的应答结果),1,发送失败
* Function Explain : 
**********************************************************************************/
u8 atk_8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
	u8 res=0; 
	USART3_RX_STA=0;
	u3_printf("%s\r\n",cmd);	//发送命令
	if(ack&&waittime)		//需要等待应答
	{
		while(--waittime)	//等待倒计时
		{
			delay_ms(10);
			if(USART3_RX_STA&0X8000)//接收到期待的应答结果
			{
				if(atk_8266_check_cmd(ack))
				{
					printf("%s ack:%s\r\n",cmd,(u8*)ack);
					break;//得到有效数据 
				}
					USART3_RX_STA=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
} 


/*********************************************************************************
* Function Name    : Is_Leap_Year,判断是否闰年
* Parameter		   : year年份
* Return Value     : 1,闰年,0,不是闰年
* Function Explain : 
* Create Date      : 2021/6/5 by zzh
**********************************************************************************/
u8 Is_Leap_Year(u16 year)
{			  
	if(year%4==0) //必须能被4整除
	{ 
		if(year%100==0) 
		{ 
			if(year%400==0)return 1;//如果以00结尾,还要能被400整除 	   
			else return 0;   
		}else return 1;   
	}else return 0;	
}	

USART_LY.h
#ifndef __USART_LY_H
#define __USART_LY_H

#include "stm32f10x.h"                  // Device header
#include 

#define DEBUG_USART2     1

#if DEBUG_USART2
#define USART2_MAX_RECV_LEN		200					//最大接收缓存字节数
#define USART2_MAX_SEND_LEN		200					//最大发送缓存字节数

#define USART2_RX_EN 			1					//0,不接收;1,接收.

// 串口2-USART2
#define  DEBUG_USARTx                   USART2
#define  DEBUG_USART_CLK                RCC_APB1Periph_USART2
#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           9600

// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd
    
#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_2
#define  DEBUG_USART_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_3

#define  DEBUG_USART_IRQ                USART2_IRQn
#define  DEBUG_USART_IRQHandler         USART2_IRQHandler

#endif

void USART2_HC05_Init(void);
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data);
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data);
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num);
void Usart_SendString(USART_TypeDef* pUSARTx, char *String);
void LY_Printf(char *format, ...);
#endif

USART_LY.c
#include "stm32f10x.h"  // Device header
#include "USART_LY.h"
#include "timer.h"	
#include "stdarg.h"	 	 
#include "stdio.h"	 	 
#include "string.h"	 
#include "delay.h"
#include "usart.h"
#include "usart3.h"
#include "string.h"
#include "esp8266.h"
static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}
//串口接收缓存区 	
char USART2_RX_BUF[USART2_MAX_RECV_LEN]; 				//接收缓冲,最大USART3_MAX_RECV_LEN个字节.
char  USART2_TX_BUF[USART2_MAX_SEND_LEN]; 			//发送缓冲,最大USART3_MAX_SEND_LEN字节
//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
vu16 USART2_RX_STA=0; 

void USART2_HC05_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
  //设置中断优先级
	NVIC_InitTypeDef NVIC_InitStructure;

	// 打开串口GPIO的时钟
	DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
	
	// 打开串口外设的时钟
	DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  // 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
	
	// 配置串口的工作参数
	// 配置波特率
	USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
	// 配置 8针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 配置校验位
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	// 配置硬件流控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 配置工作模式,收发一起
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	// 完成串口的初始化配置
	USART_Init(DEBUG_USARTx, &USART_InitStructure);
	
	// 串口中断优先级配置
	NVIC_Configuration();
	
	// 使能串口接收中断
	USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);	
	

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
	TIM2_Int_Init(1000-1,7200-1);		//10ms中断
	USART2_RX_STA=0;		//清零
	TIM_Cmd(TIM2,DISABLE);			//关闭定时器2
	
	// 使能串口
	USART_Cmd(DEBUG_USARTx, ENABLE);	
}

void USART2_IRQHandler() 
{
 if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生 
 {
  USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志
   
  USART2_RX_BUF[USART2_RX_STA] = USART_ReceiveData(USART2);     //接收串口2数据到buff缓冲区
  USART2_RX_STA++; 
  if(USART2_RX_BUF[USART2_RX_STA-1] == ';' || USART2_RX_STA == USART2_MAX_RECV_LEN)    //如果接收到尾标识是换行符(或者等于最大接受数就清空重新接收)
  {
		USART2_RX_BUF[USART2_RX_STA-1]=0;//清除  标志位 ;
    printf("这是蓝牙发给ESP的AT命令-->%s\r\n",USART2_RX_BUF);        //这里我做打印数据处理
    USART2_RX_STA=0;		
  }
 }
}

void LY_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	Usart_SendString(DEBUG_USARTx,String);
}

/* 发送一个字节 */
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
	USART_SendData(pUSARTx, data);
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送两个字节的数据 */
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)
{
	uint8_t temp_h,temp_l;
	
	temp_h = (data&0xff00) >> 8 ;
	temp_l = data&0xff;
	
	USART_SendData(pUSARTx, temp_h);
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
	
	USART_SendData(pUSARTx, temp_l);
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送8位数据的数组 */
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)
{
	uint8_t i;
	for( i=0; i<num; i++ )
  {
		Usart_SendByte(pUSARTx, array[i]);
	}
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}

/* 发送字符串 */
void Usart_SendString(USART_TypeDef* pUSARTx, char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i ++)
	{
		Usart_SendByte(pUSARTx,String[i]);
	}
}

TFToled.h
#ifndef __TFTOLED_H
#define __TFTOLED_H			  	 
#include "sys.h"
#include "stdlib.h"	   
#define TFT_W 240
#define TFT_H 240
#define	u8 unsigned char
#define	u16 unsigned int
#define	u32 unsigned long

//TFT模式设置
//0:4线串行模式
//1:并行8080模式
#define TFT_MODE 0
#define SIZE 16
#define XLevelL		0x00
#define XLevelH		0x10
#define Max_Column	128
#define Max_Row		64
#define	Brightness	0xFF 
#define X_WIDTH 	128
#define Y_WIDTH 	64	    						  
//-----------------TFT端口定义----------------  					   
#define TFT_SCLK_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_5)//CLK
#define TFT_SCLK_Set() GPIO_SetBits(GPIOA,GPIO_Pin_5)

#define TFT_SDIN_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_7)//DIN
#define TFT_SDIN_Set() GPIO_SetBits(GPIOA,GPIO_Pin_7)

#define TFT_RST_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_0)//RES
#define TFT_RST_Set() GPIO_SetBits(GPIOB,GPIO_Pin_0)

#define TFT_DC_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_1)//DC
#define TFT_DC_Set() GPIO_SetBits(GPIOB,GPIO_Pin_1)
 		     
#define TFT_BLK_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_4)//CS
#define TFT_BLK_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_4)

#define TFT_CMD  0	//写命令
#define TFT_DATA 1	//写数据

extern  u16 BACK_COLOR, POINT_COLOR;   //背景色,画笔色

void TFT_Init(void); 
void TFT_Clear(u16 Color);
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2);
void TFT_WR_DATA8(char da); //发送数据-8位参数
void TFT_WR_DATA(int da);
void TFT_WR_REG(char da);

void TFT_DrawPoint(u16 x,u16 y);//画点
void TFT_DrawPoint_big(u16 x,u16 y);//画一个大点
u16  TFT_ReadPoint(u16 x,u16 y); //读点
void Draw_Circle(u16 x0,u16 y0,u8 r);
void TFT_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);
void TFT_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2);		   
void TFT_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);
void TFT_ShowChar(u16 x,u16 y,u8 num,u8 mode);//显示一个字符
void TFT_ShowNum(u16 x,u16 y,u32 num,u8 len);//显示数字
void TFT_Show2Num(u16 x,u16 y,u16 num,u8 len);//显示2个数字
void TFT_ShowString(u16 x,u16 y,const u8 *p);		 //显示一个字符串,16字体
 
void showhanzi(unsigned int x,unsigned int y,unsigned char index);



//画笔颜色
#define WHITE         	 0xFFFF
#define BLACK         	 0x0000	  
#define BLUE         	 0x001F  
#define BRED             0XF81F
#define GRED 			 0XFFE0
#define GBLUE			 0X07FF
#define RED           	 0xF800
#define MAGENTA       	 0xF81F
#define GREEN         	 0x07E0
#define CYAN          	 0x7FFF
#define YELLOW        	 0xFFE0
#define BROWN 			 0XBC40 //棕色
#define BRRED 			 0XFC07 //棕红色
#define GRAY  			 0X8430 //灰色
//GUI颜色

#define DARKBLUE      	 0X01CF	//深蓝色
#define LIGHTBLUE      	 0X7D7C	//浅蓝色  
#define GRAYBLUE       	 0X5458 //灰蓝色
//以上三色为PANEL的颜色 
 
#define LIGHTGREEN     	 0X841F //浅绿色
#define LGRAY 			 0XC618 //浅灰色(PANNEL),窗体背景色

#define LGRAYBLUE        0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           0X2B12 //浅棕蓝色(选择条目的反色)
					  		 
#endif  

TFToled.c
#include "stm32f10x.h"                  // Device header
#include "TFToled.h"
#include "stdlib.h"
#include "TFToledfont.h"  	 
#include "delay.h"


u16 BACK_COLOR, POINT_COLOR;   //背景色,画笔色
void TFT_Writ_Bus(char dat)   //串行数据写入
{	
	u8 i;			  

	for(i=0;i<8;i++)
	{			  
		TFT_SCLK_Clr();
		if(dat&0x80)
		   TFT_SDIN_Set();
		else 
		   TFT_SDIN_Clr();
		TFT_SCLK_Set();
		dat<<=1;   
	}			
}

void TFT_WR_DATA8(char da) //发送数据-8位参数
{	
    TFT_DC_Set();
	TFT_Writ_Bus(da);  
	
}  
 void TFT_WR_DATA(int da)
{
    TFT_DC_Set();
	TFT_Writ_Bus(da>>8);
    TFT_Writ_Bus(da);
	
}	  
void TFT_WR_REG(char da)	 
{	
    TFT_DC_Clr();
	TFT_Writ_Bus(da);
	
}
 void TFT_WR_REG_DATA(int reg,int da)
{	
    TFT_WR_REG(reg);
	TFT_WR_DATA(da);
	
}

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{ 
	TFT_WR_REG(0x2a);
   TFT_WR_DATA8(x1>>8);
   TFT_WR_DATA8(x1);
   TFT_WR_DATA8(x2>>8);
   TFT_WR_DATA8(x2);
  
   TFT_WR_REG(0x2b);
   TFT_WR_DATA8(y1>>8);
   TFT_WR_DATA8(y1);
   TFT_WR_DATA8(y2>>8);
   TFT_WR_DATA8(y2);

   TFT_WR_REG(0x2C);					 						 
}

void TFT_Init(void)
{
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能A端口时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOA, &GPIO_InitStructure);	  //初始化GPIOD3,6
 	GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_4);	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能A端口时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8|GPIO_Pin_10;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOD3,6
 	GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_1);	


	//TFT_CS_Clr();  //打开片选使能
	 TFT_RST_Clr();
	delay_ms(20);
	TFT_RST_Set();
	delay_ms(20);
	TFT_BLK_Set();
	
//************* Start Initial Sequence **********// 
TFT_WR_REG(0x36); 
TFT_WR_DATA8(0x00);

TFT_WR_REG(0x3A); 
TFT_WR_DATA8(0x05);

TFT_WR_REG(0xB2);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x00);
TFT_WR_DATA8(0x33);
TFT_WR_DATA8(0x33);

TFT_WR_REG(0xB7); 
TFT_WR_DATA8(0x35);  

TFT_WR_REG(0xBB);
TFT_WR_DATA8(0x19);

TFT_WR_REG(0xC0);
TFT_WR_DATA8(0x2C);

TFT_WR_REG(0xC2);
TFT_WR_DATA8(0x01);

TFT_WR_REG(0xC3);
TFT_WR_DATA8(0x12);   

TFT_WR_REG(0xC4);
TFT_WR_DATA8(0x20);  

TFT_WR_REG(0xC6); 
TFT_WR_DATA8(0x0F);    

TFT_WR_REG(0xD0); 
TFT_WR_DATA8(0xA4);
TFT_WR_DATA8(0xA1);

TFT_WR_REG(0xE0);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2B);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x54);
TFT_WR_DATA8(0x4C);
TFT_WR_DATA8(0x18);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x0B);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x23);

TFT_WR_REG(0xE1);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2C);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x44);
TFT_WR_DATA8(0x51);
TFT_WR_DATA8(0x2F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x20);
TFT_WR_DATA8(0x23);

TFT_WR_REG(0x21); 

TFT_WR_REG(0x11); 
//Delay (120); 

TFT_WR_REG(0x29); 
 
} 

//清屏函数
//Color:要清屏的填充色
void TFT_Clear(u16 Color)
{
	u16 i,j;  	
	Address_set(0,0,TFT_W-1,TFT_H-1);
    for(i=0;i<TFT_W;i++)
	 {
	  for (j=0;j<TFT_H;j++)
	   	{
        	TFT_WR_DATA(Color);	 			 
	    }

	  }
}



//在指定位置显示一个汉字(32*33大小)
//dcolor为内容颜色,gbcolor为背静颜色
void showhanzi(unsigned int x,unsigned int y,unsigned char index)	
{  
	unsigned char i,j;
	unsigned char *temp=hanzi;    
    Address_set(x,y,x+31,y+31); //设置区域      
	temp+=index*128;	
	for(j=0;j<128;j++)
	{
		for(i=0;i<8;i++)
		{ 		     
		 	if((*temp&(1<<i))!=0)
			{
				TFT_WR_DATA(POINT_COLOR);
			} 
			else
			{
				TFT_WR_DATA(BACK_COLOR);
			}   
		}
		temp++;
	 }
}
//画点
//POINT_COLOR:此点的颜色
void TFT_DrawPoint(u16 x,u16 y)
{
	Address_set(x,y,x,y);//设置光标位置 
	TFT_WR_DATA(POINT_COLOR); 	    
} 	 
//画一个大点
//POINT_COLOR:此点的颜色
void TFT_DrawPoint_big(u16 x,u16 y)
{
	TFT_Fill(x-1,y-1,x+1,y+1,POINT_COLOR);
} 
//在指定区域内填充指定颜色
//区域大小:
//  (xend-xsta)*(yend-ysta)
void TFT_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{          
	u16 i,j; 
	Address_set(xsta,ysta,xend,yend);      //设置光标位置 
	for(i=ysta;i<=yend;i++)
	{													   	 	
		for(j=xsta;j<=xend;j++)TFT_WR_DATA(color);//设置光标位置 	    
	} 					  	    
}  
//画线
//x1,y1:起点坐标
//x2,y2:终点坐标  
void TFT_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
{
	u16 t; 
	int xerr=0,yerr=0,delta_x,delta_y,distance; 
	int incx,incy,uRow,uCol; 

	delta_x=x2-x1; //计算坐标增量 
	delta_y=y2-y1; 
	uRow=x1; 
	uCol=y1; 
	if(delta_x>0)incx=1; //设置单步方向 
	else if(delta_x==0)incx=0;//垂直线 
	else {incx=-1;delta_x=-delta_x;} 
	if(delta_y>0)incy=1; 
	else if(delta_y==0)incy=0;//水平线 
	else{incy=-1;delta_y=-delta_y;} 
	if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 
	else distance=delta_y; 
	for(t=0;t<=distance+1;t++ )//画线输出 
	{  
		TFT_DrawPoint(uRow,uCol);//画点 
		xerr+=delta_x ; 
		yerr+=delta_y ; 
		if(xerr>distance) 
		{ 
			xerr-=distance; 
			uRow+=incx; 
		} 
		if(yerr>distance) 
		{ 
			yerr-=distance; 
			uCol+=incy; 
		} 
	}  
}    
//画矩形
void TFT_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2)
{
	TFT_DrawLine(x1,y1,x2,y1);
	TFT_DrawLine(x1,y1,x1,y2);
	TFT_DrawLine(x1,y2,x2,y2);
	TFT_DrawLine(x2,y1,x2,y2);
}
//在指定位置画一个指定大小的圆
//(x,y):中心点
//r    :半径
void Draw_Circle(u16 x0,u16 y0,u8 r)
{
	int a,b;
	int di;
	a=0;b=r;	  
	di=3-(r<<1);             //判断下个点位置的标志
	while(a<=b)
	{
		TFT_DrawPoint(x0-b,y0-a);             //3           
		TFT_DrawPoint(x0+b,y0-a);             //0           
		TFT_DrawPoint(x0-a,y0+b);             //1       
		TFT_DrawPoint(x0-b,y0-a);             //7           
		TFT_DrawPoint(x0-a,y0-b);             //2             
		TFT_DrawPoint(x0+b,y0+a);             //4               
		TFT_DrawPoint(x0+a,y0-b);             //5
		TFT_DrawPoint(x0+a,y0+b);             //6 
		TFT_DrawPoint(x0-b,y0+a);             
		a++;
		//使用Bresenham算法画圆     
		if(di<0)di +=4*a+6;	  
		else
		{
			di+=10+4*(a-b);   
			b--;
		} 
		TFT_DrawPoint(x0+a,y0+b);
	}
} 
//在指定位置显示一个字符

//num:要显示的字符:" "--->"~"
//mode:叠加方式(1)还是非叠加方式(0)
//在指定位置显示一个字符

//num:要显示的字符:" "--->"~"

//mode:叠加方式(1)还是非叠加方式(0)
void TFT_ShowChar(u16 x,u16 y,u8 num,u8 mode)
{
    u8 temp;
    u8 pos,t;
	u16 x0=x;
	u16 colortemp=POINT_COLOR;      
    if(x>TFT_W-16||y>TFT_H-16)return;	    
	//设置窗口		   
	num=num-' ';//得到偏移后的值
	Address_set(x,y,x+8-1,y+16-1);      //设置光标位置 
	if(!mode) //非叠加方式
	{
		for(pos=0;pos<16;pos++)
		{ 
			temp=asc2_1608[(u16)num*16+pos];		 //调用1608字体
			for(t=0;t<8;t++)
		    {                 
		        if(temp&0x01)POINT_COLOR=colortemp;
				else POINT_COLOR=BACK_COLOR;
				TFT_WR_DATA(POINT_COLOR);	
				temp>>=1; 
				x++;
		    }
			x=x0;
			y++;
		}	
	}else//叠加方式
	{
		for(pos=0;pos<16;pos++)
		{
		    temp=asc2_1608[(u16)num*16+pos];		 //调用1608字体
			for(t=0;t<8;t++)
		    {                 
		        if(temp&0x01)TFT_DrawPoint(x+t,y+pos);//画一个点     
		        temp>>=1; 
		    }
		}
	}
	POINT_COLOR=colortemp;	    	   	 	  
}   
//m^n函数
u32 mypow(u8 m,u8 n)
{
	u32 result=1;	 
	while(n--)result*=m;    
	return result;
}			 
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//color:颜色
//num:数值(0~4294967295);	
void TFT_ShowNum(u16 x,u16 y,u32 num,u8 len)
{         	
	u8 t,temp;
	u8 enshow=0;
	num=(u16)num;
	for(t=0;t<len;t++)
	{
		temp=(num/mypow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				TFT_ShowChar(x+8*t,y,' ',0);
				continue;
			}else enshow=1; 
		 	 
		}
	 	TFT_ShowChar(x+8*t,y,temp+48,0); 
	}
} 
//显示2个数字
//x,y:起点坐标
//num:数值(0~99);	 
void TFT_Show2Num(u16 x,u16 y,u16 num,u8 len)
{         	
	u8 t,temp;						   
	for(t=0;t<len;t++)
	{
		temp=(num/mypow(10,len-t-1))%10;
	 	TFT_ShowChar(x+8*t,y,temp+'0',0); 
	}
} 
//显示字符串
//x,y:起点坐标  
//*p:字符串起始地址
//用16字体
void TFT_ShowString(u16 x,u16 y,const u8 *p)
{         
    while(*p!='\0')
    {       
        if(x>TFT_W-16){x=0;y+=16;}
        if(y>TFT_H-16){y=x=0;TFT_Clear(RED);}
        TFT_ShowChar(x,y,*p,0);
        x+=8;
        p++;
    }  
}

main.c
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "usart3.h"
#include "esp8266.h"
#include "string.h"
#include "timer.h"
#include "led.h"
#include "exti.h"
#include "oled.h"
#include "USART_LY.h"
#include "dog.h"
#include "dog.h"
#include "TFToled.h"
#include "TFTbmp.h"

/*
项目的主要内容:STM32配合ESP8266模块与服务器数据交互

MCU     ESP8266
3.3V	   VCC
GND	     GND
PB10	   RXD
PB11	   TXD
3.3V	   IO
3.3V	   RST
--------------------------------
MCU     USB转TTL
5V			 VCC
GND			 GND
PA9			 RXD
PA10		 TXD
----------------------------------------------------------------
MCU     TFT1.3
GND     电源地
VCC     接5V或3.3v电源
CLK     接PA5(SCL)
MOSI    接PA7(SDA)
RES     接PB0
DC      接PB1
BLK     接A4 可以悬空
MISO    可以不接
*/

u8 flag = 0;
char t;
extern Results results[];
extern nt_calendar_obj nwt;								//定义结构体变量
int 		year,month,date,hour,min,sec;										//时间变量



//TFT
u8 ref=0;//刷新显示
u16 vx=15542,vy=11165;  //比例因子,此值除以1000之后表示多少个AD值代表一个像素点
u16 chx=140,chy=146;//默认像素点坐标为0时的AD起始值

void xianshi1()//显示信息
{
    BACK_COLOR=WHITE;
    POINT_COLOR=RED;
    showhanzi(15,0,0);  //网
    showhanzi(50,0,1);  //络
    showhanzi(85,0,2);  //天
    showhanzi(120,0,3);  //气
	  showhanzi(155,0,4);  //时
	  showhanzi(190,0,5);  //钟
	
	  POINT_COLOR=BLACK;
	  TFT_ShowString(40,90,"WIFI");  //wife
    showhanzi(75,80,21);  //初
    showhanzi(110,80,22);  //始
    showhanzi(145,80,23);  //化
	  showhanzi(180,80,24);  //中
}
void xianshi2()//显示信息
{
    BACK_COLOR=WHITE;
    POINT_COLOR=RED;
    showhanzi(15,0,0);  //网
    showhanzi(50,0,1);  //络
    showhanzi(85,0,2);  //天
    showhanzi(120,0,3);  //气
	  showhanzi(155,0,4);  //时
	  showhanzi(190,0,5);  //钟
	
	  POINT_COLOR=BLACK;
    showhanzi(40,80,21);  //初
    showhanzi(75,80,22);  //始
	  showhanzi(110,80,23);  //化
    showhanzi(145,80,25);  //成
	  showhanzi(180,80,26);  //功
}
void xianshi3()//显示信息
{
     BACK_COLOR=WHITE;
    POINT_COLOR=RED;
    showhanzi(15,0,0);  //网
    showhanzi(50,0,1);  //络
    showhanzi(85,0,2);  //天
    showhanzi(120,0,3);  //气
	  showhanzi(155,0,4);  //时
	  showhanzi(190,0,5);  //钟
	
	  POINT_COLOR=BLACK;
    showhanzi(40,80,27);  //获
    showhanzi(75,80,28);  //取
	  showhanzi(110,80,29);  //数
    showhanzi(145,80,30);  //据
	  showhanzi(180,80,24);  //中
}
void xianshi4()//显示信息
{
    BACK_COLOR=WHITE;
    POINT_COLOR=RED;
    showhanzi(15,0,0);  //网
    showhanzi(50,0,1);  //络
    showhanzi(85,0,2);  //天
    showhanzi(120,0,3);  //气
	  showhanzi(155,0,4);  //时
	  showhanzi(190,0,5);  //钟
	
	  POINT_COLOR=BLACK;
    showhanzi(40,80,27);  //获
    showhanzi(75,80,28);  //取
	  showhanzi(110,80,25);  //成
    showhanzi(145,80,26);  //功

}

void showimage40() //显示40*40图片
{
    int i;  //数组一半长度
    int	j; //显示几列 [0~6]
    int k; //图片显示第几行 

    for(k=1; k<2; k++)
    {
        for(j=4; j<5; j++)
        {
            Address_set(40*j,40*k,40*j+39,40*k+39);		//坐标设置
            for(i=0; i<1600; i++)
            {

                TFT_WR_DATA8(image_top[i*2+1]);
                TFT_WR_DATA8(image_top[i*2]);
            }
        }
    }
    ref=0;
}
int Change(int year, int month, int day)  //根据日期判断出星期几
{
    if(month == 1 || month == 2)
    {
        month += 12;
        year--;
    }
    int c = year / 100;
    int y = year % 100;
    int m = month;
    int d = day;
    int W = c / 4 - 2 * c + y + y / 4 + 26 * (m + 1) / 10 + d - 1;
 
    int ans;
 
    if(W < 0)
        ans = (W + (-W / 7 + 1) * 7) % 7;
    else
        ans = W % 7;
    if(ans == 0)  //星期7而不是星期0
        return ans + 7;
    return ans;
}



int main(void)
{
	
	delay_init();	    	 							//延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		// 设置中断优先级分组2
	TFT_Init();			//初始化TFT
	EXTIX_Init();										//外部中断初始化
	uart_init(115200);	 								//串口初始化为115200
	usart3_init(115200);	 							//串口初始化为115200  esp
	USART2_HC05_Init();                 //串口初始化为9600     hc05
	OLED_Init();										//OLED初始化
	TIM3_Int_Init(9999,7199);							//10Khz的计数频率,计数到10000为1s  
	TIM4_Init();                     //15min更新天气
	
  TFT_Clear(WHITE); //清屏
	xianshi1();
	LY_Printf("开始");
  esp8266_start_trans(); //初始化
  
	
  
	
  TFT_Clear(WHITE); //清屏
	xianshi2();

	
	delay_ms(1000);
  TFT_Clear(WHITE); //清屏
	xianshi3();


	get_current_weather(); 								//获取天气
	delay_ms(200);
	get_beijing_time();									//获取时间	
	sec = nwt.sec;
	TIM_Cmd(TIM3, ENABLE);  //使能TIM3外设		
	year = nwt.year;
	month = nwt.month;
	date = nwt.date;
	hour = nwt.hour;
	min = nwt.min;
	
	
	
	TFT_Clear(WHITE); //清屏
	xianshi4();


	delay_ms(1000);
  Iwdg_Init();//设置看门狗重装载值,确定溢出时间:4s
	LY_Printf("\n\r获取完成");
  
  TFT_Clear(WHITE); //清屏

  
	while (1)
	{
		if(sec >= 60)
		{
			sec = 0;
			min ++;
		}
		if(min >= 60)
		{
			min = 0;
			hour ++;
		}	
		if(hour >= 24)
		{
			hour = 0;
			date=date+1;
		}

	/*******************************************
	时间计数判断,其中秒的自加在中断3实现。	
	******************************************/
		
	BACK_COLOR=WHITE;
  POINT_COLOR=RED;
  showhanzi(15,0,34);  //西
  showhanzi(50,0,35);  //安
  showhanzi(85,0,2);  //天
  showhanzi(120,0,3);  //气
  showhanzi(155,0,4);  //时
  showhanzi(190,0,5);  //钟
	
	//显示头像图片
	showimage40();
		
	showhanzi(40,50,9);            //星
  showhanzi(80,50,10);            //期
	if(Change(year,month,date)==1)
	{
		showhanzi(120,50,11);   //一
	}else if(Change(year,month,date)==2)
	{
		showhanzi(120,50,12);   //二
	}else if(Change(year,month,date)==3)
	{
		showhanzi(120,50,13);   //三
	}else if(Change(year,month,date)==4)
	{
		showhanzi(120,50,14);   //四
	}else if(Change(year,month,date)==5)
	{
		showhanzi(120,50,15);   //五
	}else if(Change(year,month,date)==6)
	{
		showhanzi(120,50,16);   //六
	}else if(Change(year,month,date)==7)
	{
		showhanzi(120,50,17);   //日
	}
		
	POINT_COLOR=BLACK;
  TFT_ShowNum(145,135,sec,3);       //显示秒  
  showhanzi(170,125,20);
		
  TFT_ShowNum(95,135,min,3);       //显示分钟 
  showhanzi(120,125,19);

  TFT_ShowNum(35,135,hour,3);      //显示小时
  showhanzi(70,125,18);
	
	POINT_COLOR=BLACK;
  TFT_ShowNum(30,100,year,4);                //显示年份
  showhanzi(70,90,6);
  TFT_ShowNum(95,100,month,3);                //显示月份
  showhanzi(120,90,7);
  TFT_ShowNum(145,100,date,3);               //显示日 
  showhanzi(170,90,8);
  
  showhanzi(50,165,2);            //天
  showhanzi(90,165,3);            //气
  TFT_ShowString(120,175,":");
  TFT_ShowString(145,175,(u8*)results[0].now.text); //采集到的天气
  
  showhanzi(50,205,31);            //温
  showhanzi(90,205,32);            //度
  TFT_ShowString(120,215,":");
  TFT_ShowString(145,215,(u8*)results[0].now.temperature); //采集到的温度
  showhanzi(175,205,33);            //℃
		
	//喂狗
//	IWDG_Feed();	
//	delay_ms(1000);//一秒
//	delay_ms(1000);//1秒
		
	/*******************************************
	按键中断触发,改变LED状态以及flag的值,
	当按键按下时,flag = 1,开始更新数据。	
	******************************************/
		if (flag == 1)
		{
			get_current_weather(); 						//获取天气
			delay_ms(200);
			get_beijing_time();							//获取时间				
			flag = 0;
			year = nwt.year;
			month = nwt.month;
			date = nwt.date;
			hour = nwt.hour;
			min = nwt.min;
			sec = nwt.sec;
		}

	}
}

工程演示

STM32+ESP8266获取时间和天气_第11张图片

工程演示

关注收藏不迷路

感谢

注:本文,参考绵绵呀的博客-CSDN博客,感谢这位博主。

所以我学习博主的精神,在文章最后我会给出百度网盘链接,尽管如此还是希望大家认真观看文章,并琢磨程序代码逻辑在我的基础上可以改出属于自己特点的工程!


给那些看完的朋友,奖励一个 赤赤博客-后端+前端,觉得不错的话可以推荐给身边的朋友哟!
在这里插入图片描述

你可能感兴趣的:(STM32,stm32,单片机,arm,嵌入式硬件)