基于STM32F的ESP8266天气时钟(4)--------MCU获取时间及显示(完结)

前言:完结撒花~本篇内容在原有的项目基础上添加了获取北京时间的功能,并对OLED显示屏的显示内容进行完善修改。
想实现的功能大部分已经完成了,虽然这个实验比较简单,不能独立支撑起一个项目,不过未来会将其作为一个小功能嵌入到其他的应用开发中。加油加油!!!

1、摘要

本章节要实现的功能为:
将ESP8266获取到的天气、时间数据进行处理然后通过OLED显示。
与获取天气的方法类似,获取时间也是通过访问API得到时间数据,得到数据后,通过定时器计时,实现时钟功能。

2、硬件准备

硬件设备由单片机最小系统板,OLED屏幕以及ESP8266wifi模块组成。

2.1、商品链接

最小系统板:购买链接
USB转TTL(种类有点多,随便选一个就行,我用的是CH340这个芯片的):购买链接
ESP8266:购买链接
OLED(我用的是0.96寸4针,I2C接口):购买链接
ST-Link V2下载线:购买链接

3、软件准备

Keil编译器
VSCode编译器
XCOM串口调试助手

4、硬件连线

MCUESP8266
3.3VVCC
GNDGND
PB10RXD
PB11TXD
3.3VIO
3.3VRST
MCUUSB转TTL
5VVCC
GNDGND
PA9RXD
PA10TXD
MCUOLED
5VVCC
GNDGND
PB15SDA
PB13SCL

5、代码解析

5.1、获取实时时间程序

本程序与获取天气数据程序类似。
本代码发送的AT指令有:

指令回复功能
AT+CIPSTART=“TCP”,"“www.beijing-time.org”",80OK建立TCP连接
AT+CIPMODE=1OK开启通透模式
AT+CIPSENDOK开始透传
GET /time15.asp HTTP/1.1Host:www.beijing-time.org\n\n时间数据提出请求
+++退出透传
/*********************************************************************************
* 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服务器
	if(res==1)
	{
		myfree(SRAMIN,p);
		return 1;
	}
	delay_ms(300);
	esp8266_send_cmd("AT+CIPMODE=1","OK",100);      //传输模式为:透传	
//	atk_8266_get_wanip(ipbuf);//获取WAN IP
	
//	sprintf((char*)p,"IP地址:%s 端口:%s",ipbuf,(u8*)TIME_PORTNUM);
//	
//	//Show_Str(30,65,200,12,p,12,0);				//显示IP地址和端口	
//	 printf("设备 %s\r\n",p);
//	
//	USART3_RX_STA=0;
	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!!!");
//				RTC_Set(nwt.year,nwt.month ,nwt.date ,nwt.hour ,nwt.min,nwt.sec);
		}
		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);         //关闭连接
	myfree(SRAMIN,p);
	return 0;
}

5.3、项目代码逻辑

基本的代码已经介绍完了,其他的操作就是调用这些函数实现功能而已,这边就不全部列出来了,感觉没什么意义。我把我的代码的逻辑分享一下吧,具体代码我会附在文末,大家可以详细看看。
初始化函数->OLED显示状态->通过ESP8266获取数据->OLED状态更新
按键按下触发中断->通过ESP8266获取数据->OLED状态更新
定时器触发->sec秒数自增

6、运行结果

设备上电后,等待ESP8266初始化,获取数据后进行解析,将状态显示到OLED屏幕上。当按下按键后,会重新获取,更新天气数据。
在这里插入图片描述

7、源程序

7.1、百度网盘

链接:https://pan.baidu.com/s/1m16EzF6AS_jB2YBGIOxtNQ
提取码:w7i2

7.2、Github地址

Github地址

传送门:
基于STM32的ESP8266天气时钟(1)---------AT指令获取天气数据
基于STM32的ESP8266天气时钟(2)--------MCU获取天气数据
基于STM32的ESP8266天气时钟(3)--------MCU数据处理及显示
基于STM32F的ESP8266天气时钟(4)--------MCU获取时间及显示(完结)

  • 28
    点赞
  • 140
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值