PCF8563实时时钟模块计时误差的校正(修正)

2 篇文章 0 订阅
1 篇文章 0 订阅

一、前言,为什么要对PCF8563时钟模块进行校时操作

根据PCF8563实时时钟模块的说明资料:由于模块电路外围器件的性能参数的偏差,该模块的计时误差平均为5分钟/年。在实际使用中,经测试发现,该模块的计时误差约为每天慢3.6秒,全年累计要慢21.9分钟,相比说明书介绍,偏差要大得多。
由于项目对于计时的精确度要求较高,加之,难以对电路中的器件进行更换或调整,所以,考虑用程序进行软件自动修正校时。

电路应用如下:

在这里插入图片描述

二、校正时间的思路

首先要找出PCF8563走时误差到底是多少,比如每天误差多少。做法如下:

1)为调试的电脑设置一个精确的时间。
首先,为电脑设置一个精确的时间。事先,要保证电脑连接internet。打开电脑“设置”的“日期和时间”的“自动设置时间”选项,如下图绿圈处。
在这里插入图片描述

2)为调试的ESP32模块RTC设置一个精确的时间
设置Thonny“选项”的“解释器”的"同步设备的实时时钟"为真,如下图划绿线部分。启用这个功能,在用Thonny调试程序,Thonny会用电脑的时间来设置ESP32模块上的RTC时间。
在这里插入图片描述

3)为PCF8563模块设定时间
编写一个功能函数,用ESP32上RTC来设定PCF8563模块的时间。找张纸,记下此刻PCF8563模块的日期和时间。由于PCF8563模块上有备用电池,即使外供电掉电,PCF8563模块还能够正常运行、走时。
设定或读取PCF8563时间,此过程可参考本人另一篇https://blog.csdn.net/weixin_42419608/article/details/134900922?spm=1001.2014.3001.5502

4)计算PCF8563模块的误差时间,确定走时误差修正值
经过几天,编写一个功能函数读取PCF8563模块的时间,对比电脑上的时间,可以看到两个时间已经出现偏差。再对比此前纸上记下的日期时间,可以计算出经过几天后,PCF8563模块每天快了(或慢了)多少秒的时间误差,从而可以计算出每天的修正值,或是其他比例修正值。

此时,编写一个记录校时的文件,保存进ESP32里,如:cal8563.txt,保存校时信息的文件,格式例如#B13.6#B21766410308#B32024,4,11,13,41,42,6,105
其中#B13.6#B2表示修正值为+3.6秒,#B21766410308#B3表示校时时的流逝累计秒,#B32024,4,11,13,41,42,6,105表示校时时的日期时间(另一种格式表达而已,方面阅读、理解),备用

5)以后,在程序中循环调用功能函数,每隔一段时间,条件达到,按误差修正值,对PCF8563进行校时修正。

三、实现过程(几个关键点)

1)读取或设置ESP32模块RTC时间
用下面语句就能读取ESP32模块RTC时间

   import time
   a= time.localtime()
   print("RTC time: ",a)

#localtime格式(year, month, mday, hour, minute, second, weekday, yearday) ,运行后,结果如下:

RTC time:  (2024, 6, 10, 17, 38, 30, 0, 162)

重点说明:time.localtime([secs]) 这是本文中校时的一个重要功能函数,方便进行时间格式变换
如果未提供secs或 None,则使用来自 RTC 的当前时间。
如果提供secs秒(以秒表示的时间),则转换为2000年1月1日以来的一个 8 元组(year, month, mday, hour, minute, second, weekday, yearday),包含:
• year年份包括世纪(例如 2014)。
• month月份是 1-12
• mday 是 1-31
• hour小时是 0-23
• minute分钟是 0-59
• second秒是 0-59
• weekday周一至周日的工作日是 0-6
• yearday是一年中第几天是 1-366

另一个重要功能函数 time.time(), 此函数的返回值方便了校时修正的计算过程
函数说明:获取当前cpu时间戳,2000年1月1日以来的流逝时间,单位:秒。
示例:

>>> time.time()
771357344
>>> 

用这两个功能函数相互配合就可以很方便地进行校时操作,否则,仅仅是闰年闰月的判断,就会把人搞疯。

Thonny调试运行结果见下:
在这里插入图片描述
2)校时功能函数工作流程

[在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e10fc92e28d74a6eac019bd823beff9e.png)*

3)代码*

#函数功能:对PCF8563校时--------------------------
#参数1:Cals修正值(秒),参数2:每隔CalPerTimes秒修正一次,如1天=86400秒
#返回:当前年份
#状态:可用,调试于2024-4-15        
def Calib_PCF8563(Cals,CalPerTimes):
    #cal8563.txt保存信息的文件,格式例如#B13.6#B21766410308#B32024,4,11,13,41,42,6,105
    #  #B13.6#B2修正值3.6秒,#B21766410308#B3流逝的累计秒,#B32024,4,11,13,41,42,6,105修正时的日期时间
    WrRd_PCF8563(False)                 #自编函数,取PCF8563时间来设置RTC
    CurrSeconds = int(time.time())       #获得当前时间(流逝秒)
    #print("CurrTime: ",CurrSeconds)    
    
    #以下提取之前校时的时间记录
    f = open ('cal8563.txt', 'r',encoding= 'UTF-8') 
    file_c = f.read()
    f.close()    
    i = file_c.find('#B2')                       #提取特定标志信息 
    if i != -1:
        j=file_c.find('#B3')
        PastTimes = int(file_c[i+3:j:])          #获得上次修正时的流逝秒                 
        #print("PastTimes:",PastTimes)
        
    #如果当前时间比上次修正时间超过一次需要校正的时间CalPerTimes秒,如CalPerTimes=86400秒=1天,则进行校时修正操作    
    if CurrSeconds > (PastTimes+CalPerTimes):
        #当前流逝秒 +((当前-过去)的流逝秒数除以每CalPerTimes秒后取整,乘以修正值)
        #计算出经过了CalPerTimes后的修正值,即修正的流逝秒
        CalsTime = CurrSeconds + int((CurrSeconds-PastTimes)//CalPerTimes * Cals)
        #print ("CalSeconds: ",CalsTime)
        
        #按修正的流逝秒来设置RTC
        c = time.localtime(CalsTime)        #用带参数的time.localtime()来变换时间
        rtc = RTC()                         #准备来设置RTC时间值
        rtc.datetime((c[0],c[1],c[2],c[6],c[3],c[4],c[5],0))  #用变换出来的数据设置RTC
        #print("AfterCal:",time.time())
        WrRd_PCF8563(True)       #自编函数,取RTC时间来设置PCF8563,也就是对PCF8563校时
        #把校正时间时的时间信息形成格式化信息保存下来,以备下一次使用
        toFile = '#B1'+ str(Cals) + '#B2'+str(time.time())+'#B3'+str(time.localtime())
        #print("tofile: ",toFile)
        with open('cal8563.txt', "wt",encoding= 'UTF-8') as f:
            f.write(toFile)
            f.close
            
    nowT=time.localtime()
    return nowT[0]       #返回年份值

4)实现软件校时
程序中循环调用以上功能函数,间隔时间条件满足时,就会进行校时操作,从而实现软件校时。

其他:关于设置和读取PCF8653时间,可参考本人另一篇https://blog.csdn.net/weixin_42419608/article/details/134900922?spm=1001.2014.3001.5502

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值