Arduino 配置PKE8720DF-C13-F10开发板 —— RTC 每秒打印时间信息

目录

1. RTC 简介

2. Arduino添加 “RTC每秒打印时间信息” Sketch code 

3.代码解析 

(1)setup函数:

(2)loop 函数:

4.电路连接

(1)材料准备

(2)电路连接

(3)端口设置与烧录

5.实验结果

 


关于PKE8720DF-C13-F10开发板 的具体介绍请参考:Arduino 配置PKE8720DF-C13-F10开发板——“Blink” 周期性点亮LED灯_zoey_O_o__的博客-CSDN博客

1. RTC 简介

RTC(Real Time Clock)是一个独立的二进码十进制格式(BCD码)定时器/计数器。其中一个32位寄存器包括BCD格式表示的seconds、minutes、hours(12或24小时制),另一个32位寄存器包括二进制格式表示的days。BCD码是用4位二进制数来表示1位十进制数中的0~9这10个数码。另外可以自动将月份的天数计为28、29(闰年)、30、31天以及夏令时补偿。

只要工作电压维持在运行范围,不管在运行模式、低功耗模式还是重置情况下,RTC都不会停止。

2. Arduino添加 “RTC每秒打印时间信息” Sketch code 

由于Arduino 基于board“ AMB25/AMB26 (RTL8720DF) ”没有直接可用的RTC Examples,这里我们需要自己新建一个sketch:

  具体code 如下:

#include "rtc_api.h"
#include "wait_api.h"

void setup() {
  // put your setup code here, to run once:
    rtc_init();
    rtc_write(1256729737);  // Set RTC time to Wed, 28 Oct 2009 11:35:37
}

void loop() {
  // put your main code here, to run repeatedly:
    time_t seconds;
    struct tm *timeinfo;

    while(1) {
        seconds = rtc_read();
        timeinfo = localtime(&seconds);

        DiagPrintf("Time as seconds since January 1, 1970 = %d\n", seconds);

        DiagPrintf("Time as a basic string = %s", ctime(&seconds));

        DiagPrintf("Time as a custom formatted string = %d-%d-%d %d:%d:%d\n", 
            timeinfo->tm_year+1900, timeinfo->tm_mon+1, timeinfo->tm_mday, timeinfo->tm_hour,
            timeinfo->tm_min,timeinfo->tm_sec);

        wait(1.0);
    }
}

3.代码解析 

包含的2个头文件 "rtc_api.h"和 "wait_api.h" 为了调用实现RTC 功能的函数,可以在源码中查询GitHub - ambiot/ambd_arduino: AmebaD Arduino third-party package SDK

(1)setup函数:

rtc_init:初始化RTC 设备,包括时钟,RTC寄存器和功能函数,具体代码如下:

void rtc_init(void)
{
	RTC_InitTypeDef RTC_InitStruct;

	RCC_PeriphClockSource_RTC(0);

	RTC_StructInit(&RTC_InitStruct);
	RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24;
	
	RTC_Init(&RTC_InitStruct);

	RTC_BypassShadowCmd(ENABLE);

	/* 32760 need add need add 15 cycles (256Hz) every 4 min*/
	//RTC_SmoothCalibConfig(RTC_CalibSign_Positive, 15,
	//	RTC_CalibPeriod_4MIN, RTC_Calib_Enable);

	rtc_en = 1;
}

rtc_write(seconds):从1970.1.1 00:00:00到要设置的指定数据和时间的秒数,具体代码如下:

void rtc_write(time_t t)
{	
	/* Convert the time in to a tm*/
	struct tm *timeinfo = localtime(&t);

	RTC_TimeTypeDef RTC_TimeStruct;
	
	/*set time in RTC */
	RTC_TimeStruct.RTC_H12_PMAM = RTC_H12_AM;
	RTC_TimeStruct.RTC_Days = timeinfo->tm_yday;
	RTC_TimeStruct.RTC_Hours = timeinfo->tm_hour;
	RTC_TimeStruct.RTC_Minutes = timeinfo->tm_min;
	RTC_TimeStruct.RTC_Seconds = timeinfo->tm_sec;
	RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);

	/* Set rtc_timeinfo*/
	_memcpy((void*)&rtc_timeinfo, (void*)timeinfo, sizeof(struct tm));
}

rtc_write(1256729737);  // Set RTC time to Wed, 28 Oct 2009 11:35:37 

 1256729737就是从1970.1.1 00:00:00 到 2009.10.28 11:35:37 经过的秒数,如果要切换到其他时间点,则直接在rtc_write(/*填所需要的秒数*/)。

(2)loop 函数:

先定义两个时间变量:  time_t seconds; struct tm *timeinfo;

赋值:seconds = rtc_read();  从RTC获取以秒为单位的当前时间戳。RTC当前时间戳是以1970.1.1 00:00:00.开始计算的。

具体为什么是这个时间点:看到有这样解释:很多编程语言起源于UNIX系统,而UNIX系统认为1970年1月1日0点是时间起点,所以我们常说的UNIX时间戳是以1970年1月1日0点为计时起点时间的;还有的是:最早出现的UNIX操作系统考虑到计算机产生的年代和应用的时限综合取了1970年1月1日作为UNIX TIME的开始时间。

rtc_read函数代码具体如下:

time_t rtc_read(void)
{
	time_t t;
	struct tm tm_temp;
	RTC_TimeTypeDef RTC_TimeStruct;
	u32 delta_days = 0;
	RRAM_TypeDef* RRAM = ((RRAM_TypeDef *) RRAM_BASE);

	if((0x80000000&(RRAM->RTC_YEAR)) !=0){
		rtc_restore_timeinfo();
		RRAM->RTC_YEAR&=(~0x80000000);
	}

	_memcpy((void*)&tm_temp, (void*)&rtc_timeinfo, sizeof(struct tm));

	/*hour, min, sec get from RTC*/
	RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct);
	tm_temp.tm_sec = RTC_TimeStruct.RTC_Seconds;
	tm_temp.tm_min = RTC_TimeStruct.RTC_Minutes;
	tm_temp.tm_hour = RTC_TimeStruct.RTC_Hours;

	/* calculate how many days later from last time update rtc_timeinfo */
	delta_days = RTC_TimeStruct.RTC_Days - tm_temp.tm_yday;

	/* calculate  wday, mday, yday, mon, year*/
	tm_temp.tm_wday += delta_days;
	if(tm_temp.tm_wday >= 7){
		tm_temp.tm_wday = tm_temp.tm_wday % 7;
	}
	
	tm_temp.tm_yday += delta_days;
	tm_temp.tm_mday += delta_days;
	
	while(tm_temp.tm_mday > days_in_month(tm_temp.tm_mon, tm_temp.tm_year)){
		tm_temp.tm_mday -= days_in_month(tm_temp.tm_mon, tm_temp.tm_year);
		tm_temp.tm_mon++;

		if(tm_temp.tm_mon >= 12){
			tm_temp.tm_mon -= 12;
			tm_temp.tm_yday -= is_leap_year(tm_temp.tm_year) ? 366 : 365;
			tm_temp.tm_year ++;

			/* over one year, update days in RTC_TR */
			RTC_TimeStruct.RTC_Days = tm_temp.tm_yday;
			RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);

			/* update rtc_timeinfo */
			_memcpy((void*)&rtc_timeinfo, (void*)&tm_temp, sizeof(struct tm));
		}
	}
	
	/* Convert to timestamp(seconds from 1970.1.1 00:00:00)*/
	t = mktime(&tm_temp);

	return t;
}

赋值:timeinfo = localtime(&seconds); 将seconds 从unsigned long 转换为 struct tm (年月日时分秒)的格式。

DiagPrintf("Time as seconds since January 1, 1970 = %d\n", seconds);

第一条打印seconds的值,这里即1256729737;

 DiagPrintf("Time as a basic string = %s", ctime(&seconds));

第二条打印ctime 格式的字符串;

DiagPrintf("Time as a custom formatted string = %d-%d-%d %d:%d:%d\n",

            timeinfo->tm_year+1900, timeinfo->tm_mon+1, timeinfo->tm_mday, timeinfo->tm_hour,

            timeinfo->tm_min,timeinfo->tm_sec);

第三条打印习惯格式(年月日用“-”分割,时分秒用“:”分割)。

之后每秒打印一次。

4.电路连接

(1)材料准备

  • 1 块 PKE8720DF-C13-F10开发板
  • 1 根 USB转type-C数据线

(2)电路连接

将typc-c连接开发板,USB连接电脑。

(3)端口设置与烧录

请参考上一篇文章:Arduino 配置PKE8720DF-C13-F10开发板 —— UART回送用户输入的单个字符_zoey_O_o__的博客-CSDN博客

5.实验结果

 打开串口调试工具,进行如下setting:

 按板子上的RESET按键,这时候可以看到tool开始打印时间相关的信息,三条打印信息为一组,每秒打印一组,如果给板子一直供电,时间相关的信息会一直打印。

 实验结果符合预期。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值