【RT-Thread Nano】作业6:通过ESP8266获取NTP服务器上的时间

实验任务

本实验为RT-Thread Nano 入门线上培训作业题目6:
实现RTC驱动,将NTP服务器中获取的网络时间更新至RTC。

实验目的

熟悉如何获取NTP服务器上的数据。

实验环境

1、硬件环境:野火STM32霸道开发板
2、软件环境:RT-Thread Nano 3.1.3,MDK 5.25

实验步骤

1、编写ESP8266驱动和RTC驱动,这部分的工作,开发板的固件库例程和扩展模块例程已经有了,因此直接拿来用就行。
2、编写获取NTP服务器时间的应用程序。

#include "config.h"
#include "ntp_example.h"

#define NTP_TIMESTAMP_DELTA 		2208988800ull 												/* number of seconds between 1900 and 1970,1900-1970的时间差 */
#define SEC_TIME_ZONE         		+ (8*60*60)  												/* Beijing,GMT+8, 时区差 */
															
#define TIME_SERVERIP				"cn.ntp.org.cn"												/* NTP服务器 */
#define TIME_PORTNUM				"123"														/* NTP服务器端口号,固定为123 */

int GetNtp(void)
{
  	uint8_t PosInNtpPacket;
	uint8_t buf[48];																			/* 存储NTP服务器返回的数据 */
	uint32_t local_timestamp;
 	ntp_packet packet ;
  	struct tm * Net_time; 
  	uint8_t NTP_Data[48]; 																		/* 48字节的报文 */																												
	u8 count = 4;
	u8 id;
	
	NTP_Data[0]=0xa3; 																			/* NTP查询报文赋初值 */
	for(PosInNtpPacket=1;PosInNtpPacket<48;PosInNtpPacket++) 
		NTP_Data[PosInNtpPacket]=0;																/* 剩余的47字节为0 */
	
	rt_kprintf ( "\r\nConfig ESP8266 ......\r\n" );
	ESP8266_Link_Server ( enumUDP, TIME_SERVERIP, TIME_PORTNUM, Single_ID_0 );					/* 连接NTP服务器 */
	ESP8266_UnvarnishSend ();																	/* 开启透传 */
	rt_kprintf ( "\r\nConfig ESP8266 Over\r\n" );
	
	strEsp8266_Fram_Record .InfBit .FramLength = 0;
	rt_memset(strEsp8266_Fram_Record.Data_RX_BUF,0,RX_BUF_MAX_LEN);								/* 清除接收缓存 */
	
	for(PosInNtpPacket=0;PosInNtpPacket<48;PosInNtpPacket++) 									/* 发送NTP查询包 */
	{
		USART_SendData(USART3, (uint8_t)NTP_Data[PosInNtpPacket]);
		while(USART_GetFlagStatus(USART3, USART_FLAG_TC)== RESET);	
	}
	
	rt_thread_mdelay(1000);
	
	rt_memcpy(buf,strEsp8266_Fram_Record.Data_RX_BUF,48);										/* 拷贝数据包 */
	
	printf("/*******************************/\r\n");											/* 接收包原始数据打印 */
	printf("Receive NTP Packet (Hex):");
	for(PosInNtpPacket=0;PosInNtpPacket<48;PosInNtpPacket++)
	{	
		if(PosInNtpPacket%16==0)
		{
			printf("\r\n");
			printf("%02X ",buf[PosInNtpPacket]);
		}
		else
			printf("%02X ",buf[PosInNtpPacket]);
	}
	printf("\r\n/*******************************/\r\n");

	
	ESP8266_ExitUnvarnishSend ( );																/* 退出透传 */
 	ESP8266_Close_Link (  );																	/* 关闭TCP或UDP连接 */
	
	if( packet.txTm_s == 0 )
		return 0;
	
	/* 由于本演示时间精度要求不高,故直接用服务器返回的时间作为对时的时间,并未用公式:时间差offset=((T2-T1)+(T3-T4))/2。而是用T3作为对时基准时间。*/		
	id = 40;
	packet.txTm_s = buf[id+0]<<24 | buf[id+1]<<16 | buf[id+2]<<8 | buf[id+3];
	
	local_timestamp = packet.txTm_s - NTP_TIMESTAMP_DELTA;										/* 减去1970和1900的差值 */
  	local_timestamp +=SEC_TIME_ZONE; 															/* 加上北京的时间差,GMT+8 */ 
  	Net_time = localtime(&local_timestamp); 													/* 秒数转换位标准时间 */
	
	printf("NTP Time:%04d-%02d-%02d %02d:%02d:%02d\r\n",										/* 打印出时间 */
				(Net_time->tm_year)+1900, (Net_time->tm_mon)+1, 
				 Net_time->tm_mday, Net_time->tm_hour,
				 Net_time->tm_min, Net_time->tm_sec); 

	
	Set_Time(local_timestamp);
	
	while(count--)
	{
		local_timestamp = Get_Time();
		Net_time = localtime(&local_timestamp);
		printf("NTP Time:%04d-%02d-%02d %02d:%02d:%02d\r\n",									/* 打印出时间 */
				(Net_time->tm_year)+1900, (Net_time->tm_mon)+1, 
				 Net_time->tm_mday, Net_time->tm_hour,
				 Net_time->tm_min, Net_time->tm_sec);
		rt_thread_mdelay(1000);
	}
	
	return 0;
}
MSH_CMD_EXPORT(GetNtp, Get BeiJing Time.);

3、编写设置RTC时间戳的函数和获取RTC时间戳的函数,这其实是bsp_rtc.c的内容。

void Set_Time(u32 timestamp)
{
	/* 等待确保上一次操作完成 */
	RTC_WaitForLastTask();
	
	/* 将时间戳并写入到RTC计数寄存器 */
	RTC_SetCounter(timestamp);
	
	/* 等待确保上一次操作完成 */
	RTC_WaitForLastTask();
}

u32 Get_Time(void)
{
	return RTC_GetCounter();
}

4、编写通过msh获取RTC时间的应用程序。

int GetRTCTime(void)
{
	uint32_t local_timestamp; 
  	struct tm * Net_time;														/* 48字节的报文 */																												
	u8 count = 4;
	
	while(count--)
	{
		local_timestamp = Get_Time();
		Net_time = localtime(&local_timestamp);
		printf("NTP Time:%04d-%02d-%02d %02d:%02d:%02d\r\n",					/* 打印出时间 */
				(Net_time->tm_year)+1900, (Net_time->tm_mon)+1, 
				 Net_time->tm_mday, Net_time->tm_hour,
				 Net_time->tm_min, Net_time->tm_sec);
		rt_thread_mdelay(1000);
	}
	
	return 0;
}
MSH_CMD_EXPORT(GetRTCTime, Get RTC Time.);

实验结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值