ESP8266的RTC时间和系统时间测试对比
官方有关时间的API主要有两个
system_get_time
功能:
查询系统时间,单位:微秒
函数定义:
uint32 system_get_time(void)
参数:
⽆无
返回:
系统时间,单位:微秒。
system_get_rtc_time
功能:
查询 RTC 时间,单位:RTC 时钟周期
⽰示例:
例如 system_get_rtc_time 返回 10 (表⽰示 10 个 RTC 周期),
system_rtc_clock_cali_proc 返回 5.75 (表⽰示 1 个 RTC 周期为 5.75 微秒),
则实际时间为 10 x 5.75 = 57.5 微秒。
注意:
system_restart 时,系统时间归零,但是 RTC 时间仍然继续。但是如果外部硬件通过 EXT_RST
脚或者 CHIP_EN 脚,将芯⽚片复位后(包括 deep-sleep 定时唤醒的情况),RTC 时钟会复位。具
体如下:
• 外部复位(EXT_RST): RTC memory 不变,RTC timer 寄存器从零计数
• watchdog reset : RTC memory 不变,RTC timer 寄存器不变
• system_restart : RTC memory 不变,RTC timer 寄存器不变
• 电源上电 : RTC memory 随机值,RTC timer 寄存器从零计数
• CHIP_EN 复位 : RTC memory 随机值,RTC timer 寄存器从零计数
函数定义:
uint32 system_get_rtc_time(void)
参数:
⽆无
返回:
RTC 时间
system_rtc_clock_cali_proc
功能:
查询 RTC 时钟周期.
注意:
RTC 时钟周期含有⼩小数部分。
RTC 时钟周期会随温度或电源电压变化发⽣生偏移,因此 RTC 时钟适⽤用于在精度可接受的范围内进⾏行计
时,建议最多每分钟调⽤用⼀一次即可。
函数定义:
uint32 system_rtc_clock_cali_proc(void)
参数:
⽆无
返回:
RTC 时钟周期,单位:微秒,bit11 bit0 为⼩小数部分
⽰示例:
os_printf(“clk cal : %d \r\n”,system_rtc_clock_cali_proc()>>12);
上面两个都可以实现计算时间的功能,主要区别是system_get_time(void)时间只要出现系统重启就会重新计时,但是system_get_rtc_time 只有不掉电就不会出现计时丢失,所以如果我们需要实现一个时钟功能,肯定是选择system_get_rtc_time函数来实现。对于这两个函数的区别可以看下图片就一目了然:
从上面图片我们看出来系统时间计时和RTC计时都差不多,相差不大,system_rtc_clock_cali_proc也确实如官方API所说的RTC 时钟周期会随温度或电源电压变化发⽣生偏移,所以也仅仅只有用做不是精确计时,如果需要精确计时还是需要外部RTC芯片。还有电源重启后之前RTC的数值是会丢失的
和API所说的电源上电 : RTC memory 随机值,RTC timer 寄存器从零计数是一致的,有关ESP8266的时间函数测试分析就此结束。
如上图是实现获取的网络时间保存在RTC中,每一分钟打印一次数据和电脑本地时间对比,时间吻合,没有问题,设计思想主要是通过RTC时间计算系统运行时间,再将运行时间加到SNTP获得时间上,最后调用SNTPAPI输出结果,我一分钟打印一次,关键代码如下:
void ICACHE_FLASH_ATTR sntp_cb()
{
uint32 current_stamp;
#if 1//for sntp test
/*
需要判断该函数sntp_get_current_timestamp返回值
如果该返回值为非0的数表示已经接收到服务器的数据了
*/
current_stamp = sntp_get_current_timestamp();
os_printf("###sntp: %d, %s \n",current_stamp, sntp_get_real_time(current_stamp));
if(current_stamp)
{
os_printf("###sntp:timezone=%d\n",sntp_get_timezone());
os_timer_disarm(&sntp_timer);
os_timer_disarm(&rtc_test_t);
os_timer_setfn(&rtc_test_t,rtc_count,current_stamp);
os_timer_arm(&rtc_test_t,60000,1);
}
#endif
}
void ICACHE_FLASH_ATTR rtc_count(uint32_t time)
{
RTC_TIMER_DEMO rtc_time;
uint32 rtc_t1;
uint32 cal1;
system_rtc_mem_read(64, &rtc_time, sizeof(rtc_time));
if(rtc_time.magic!=RTC_MAGIC)
{
rtc_time.magic = RTC_MAGIC;
rtc_time.time_acc= 0;
rtc_time.time_base = system_get_rtc_time();
os_printf("time base : %d \r\n",rtc_time.time_base);
}
rtc_t1 = system_get_rtc_time();
cal1 = system_rtc_clock_cali_proc();
os_printf("cal 1 : %d.%d \r\n", ((cal1*1000)>>12)/1000,((cal1*1000)>>12)%1000 );
rtc_time.time_acc += ( ((uint64)(rtc_t1 - rtc_time.time_base)) *( (uint64)((cal1*1000)>>12)) ) ;
os_printf("rtc time acc : %lld \r\n",rtc_time.time_acc);
os_printf("power on time : %lld.%02lld S \r\n", (rtc_time.time_acc/10000000)/100, (rtc_time.time_acc/10000000)%100);
os_printf("time: %s \n", sntp_get_real_time(time+((rtc_time.time_acc/10000000)/100)));
rtc_time.time_base = rtc_t1;
system_rtc_mem_write(64, &rtc_time, sizeof(rtc_time));
}
沙发
挺快,其实这个帖子还没写完,最终是需要实现一个本地时钟,需要将网络同步时间保存在RTC中
这个在IOT领域应用很广泛
那必须的,因为有用,我才分享,没有我就不写了
為何在rtc_count的函式中,需要呼叫兩次system_get_rtc_time,這是有什麼特殊的用意?
為何base = rtc1 - rtc 的 system_get_rtc_time ?
请教一下:大神
这里的 os_printf("time: %s \n", sntp_get_real_time(time+((rtc_time.time_acc/10000000)/100)));
time是代表?
这里的 os_printf("time: %s \n", sntp_get_real_time(time+((rtc_time.time_acc/10000000)/100)));
time是代表?
这里的 os_printf("time: %s \n", sntp_get_real_time(time+((rtc_time.time_acc/10000000)/100)));
time是代表?
兄弟:
这里的 os_printf("time: %s \n", sntp_get_real_time(time+((rtc_time.time_acc/10000000)/100)));
time是代表?
兄弟:
这里的 os_printf("time: %s \n", sntp_get_real_time(time+((rtc_time.time_acc/10000000)/100)));
time是代表?