nrf51822实现日历

NORDIC 带有两个RTC ,但是都只是简单的计数器而已,并没有用作日历的寄存器。但是很多项目都需要国际标准标准时间(UTC)用作日历信息。在不加外部RTC新片的前提下,我们有两种方法实现。



         1.利用RTC的 counter 寄存器。设置一个开始时间,每次需要日历信息的时候,都去读一次 counter 寄存器中的值,并换算成时间,加上开始时间,就可知道当前的时间了。

          优点: 不需要中断,可以在CPU完全休眠的状态下,保持RTC的运行,等需要用到时间信息的时候,才需要去RTC counter 寄存器中读一次数据,再换算即可。

         缺点: RTC的counter 寄存器的位数有限,假定我们将RTC设置为1秒加一次。那么对于32位RTC 从0x00000000~ 0xFFFFFFFF, 理论上可以计136年 RTC才会溢出。(当然RTC跑那么长时间,误差肯定会很大)。对于24位RTC ,0x000000~0xFFFFFF 理论上可以计194天。



         2. 利用RTC 中断,设置每秒产生一次中断,每次中断让一个自定义的变量 加 1,每次需要时间的时候,把这个变量转换成时间。

          优点: 定时时间会比较准,RTC可以用来做其他的事情。

          缺点:每次都要响应RTC中断,CPU被频繁唤醒,耗电量会增加。



【正文】



       Nordic51822 自带了两个RTC,但是如果使能 SolfDevice,  RTC0是被占用的,用户不可操作。RTC1是一个24位计数器,如果利用方法1,将只能计数194天。而且RTC1还用作了app_timer 的实现,我们最好不要直接去操作其寄存器。于是我选择了方法2.

并且利用nordic官方的app_timer模块,来实现定时。





下面是实现步骤:

(Note: 以下日历的实现算法,并非原创,借鉴于TI CC2540 官方文档,  我修复了一个它会出现4月0号的BUG,经验证其他没有问题)



      1. 新建一个app_timer .(包括  TIMER_ID , TIEMR_INTERVAL, timeout_handler  )

      2.自定义一个变量TimeSeconds ,用来保存秒信息。

      3.创建一个函数  UTCTime   ConvertUTCSecs( UTCTimeStruct tm ) ,用来把上位机的日历信息,转换成秒.(默认的开始时间为 2000年01月01日00时00分00秒) 

      4.创建一个函数void ConvertUTCTime( UTCTimeStruct
tm, UTCTime secTime ),用来把秒转换成UTC时间。

      5.启动定时器                     err_code = app_timer_start(m_calender_timer_id, CALENDER_TIEMR_INTERVAL , NULL);

            APP_ERROR_CHECK(err_code);

      6.当接收到上位机日历信息后,调用 ConvertUTCSecs ();

      7.在每次日历定时器定时时间到后,TimeSeconds +1

      8. 当需要读取当前时间时,  调用  ConvertUTCTime ()  ,将TimeSeconds  转换成 UTC 时间。

sitemap