与常见的秒计数器不同,GD32E231的RTC模块提供了一个包含日期(年/月/日)和时间(时/分/秒/亚秒)的日历功能,无需用户自己实现日历算法。
通过读取寄存器可以直接得到时间和日历的值:
RTC的时钟源有三个:内部40K时钟,外部32.768K,内部高速时钟32分频
通常采用内部40K最为方便,因为通常外部的32.768K时钟兼顾低功耗功能,起振比较困难。
上图还可以看到这里有两个分频器:异步7位分频器FACTOR_A,产生时钟ck_apre;同步15位分频器FACTOR_S,产生时钟ck_spre。
最终的时钟频率要做到同步分频器出来刚好是1Hz。他们的计算公式:
数据手册提到,异步分频器对功耗控制更加严格,应该尽量加大异步分频器的数值,因此这里设置异步分频器为100-1,同步分频器则为400-1.
初始化代码:
/* enable access to RTC registers in backup domain */
rcu_periph_clock_enable(RCU_PMU);
pmu_backup_write_enable();
/* enable the IRC40K oscillator */
rcu_osci_on(RCU_IRC40K);
/* wait till IRC40K is ready */
rcu_osci_stab_wait(RCU_IRC40K);
/* select the RTC clock source */
rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
rcu_periph_clock_enable(RCU_RTC);
rtc_register_sync_wait();
rtc_init(&rtc_initpara);
其中rtc_initpara是RTC里面最重要的结构体,我们可以在固件库手册里面找到它:
rtc_parameter_struct rtc_initpara=
{0x18,RTC_DEC,0x01,RTC_SATURDAY,
0x10,0x0,0x0,
0x63,0x18F,
RTC_AM,RTC_24HOUR};
其中asyn、syn就是上述的分频器设置参数(手册的异步打错字了)
RTC是可以实现低功耗的,其低功耗供电通过VDD(即JP8排阵第三个针脚)供电,但由于目前没有额外设置低功耗,因此没有采用电池低功耗供电,因此上电需要校准。为此额外外挂了一个DS3231。
可能使用了DS3231再使用RTC有点多次一举。但实际上RTC是芯片内部总线访问,比通过IIC外部总线访问快得多。
ReadTimeDS3231();
rtc_initpara.rtc_second = HEX2BCD(m_Timestrct.sec);
rtc_initpara.rtc_minute = HEX2BCD(m_Timestrct.min);
rtc_initpara.rtc_hour = HEX2BCD(m_Timestrct.hour);
rtc_initpara.rtc_date = HEX2BCD(m_Timestrct.data);
rtc_pre_config();
使用1602显示时间:
rtc_current_time_get(&rtc_initpara);
sprintf(t_strReportTemp, "%2x:%2x:%2x-%2x", rtc_initpara.rtc_hour, rtc_initpara.rtc_minute, rtc_initpara.rtc_second, rtc_initpara.rtc_date);
ShowString(2,1, (unsigned char *)t_strReportTemp);
效果: