在按照GD32F350官方demo板提供的历程做RTC时,发现外部低速时钟不能用,用内部低速时钟不设置时间时,大多数时间都不正常,现象表现为时、分、秒走得很快,几秒种日期能加一天。如果设置了时间,RTC马上就死掉,直接停了。找FAE,也没找出问题,最后FAE发来一个能用的例程,经过对比,原来是开发板提供的例程有误,我估计做资料的人也没亲自测试,只是简单的复制粘贴。
下面来看库代码:
-
oid rtc_pre_config(void)
-
{
-
/* enable access to RTC registers in backup domain */
-
rcu_periph_clock_enable(RCU_PMU);
-
pmu_backup_write_enable();
-
-
#if defined (RTC_CLOCK_SOURCE_IRC40K)
-
/* 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);
-
-
prescaler_s = 0x18F;
-
prescaler_a = 0x63;
-
#elif defined (RTC_CLOCK_SOURCE_LXTAL)
-
/* enable the IRC40K oscillator */
-
rcu_osci_on(RCU_LXTAL);
-
/* wait till IRC40K is ready */
-
rcu_osci_stab_wait(RCU_LXTAL);
-
/* select the RTC clock source */
-
rcu_rtc_clock_config(RCU_LXTAL);
-
-
prescaler_s = 0xFF;
-
prescaler_a = 0x7F;
-
#else
-
#error RTC clock source should be defined.
-
#endif /* RTC_CLOCK_SOURCE_IRC40K */
-
-
rcu_periph_clock_enable(RCU_RTC);
-
rtc_register_sync_wait();
-
}
例程是通过
RTC_CLOCK_SOURCE_IRC40K和
RTC_CLOCK_SOURCE_LXTAL这两个宏来切换时钟的,另外初始化了 prescaler_s = 0x18F;prescaler_a = 0x63; 这两个变量,我一开始就发现这两个变量没在任何地方应用,觉得很奇怪。例程默认使用内部低速时钟,第23行 rcu_rtc_clock_config(RCU_LXTAL);中的RCU_LXTAL这个参数是错的,应该使用RCU_RTCSRC_LXTAL。最重要的一点是prescaler_s和prescaler_a应该是设置时间时配置预分频寄存器 (RTC_PSC)的。设置时间时先填充一个rtc_parameter_struct型的结构体,然后调用ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)函数,填入初始化后的结构体就可以了。下面是一个时间设置函数:
-
void set_time(u8 year,u8 month,u8 day,u8 week,u8 hour,u8 minute,u8 second)
-
{
-
rtc_parameter_struct time;
-
-
-
time.rtc_factor_asyn = prescaler_a;
-
time.rtc_factor_syn = prescaler_s;
-
-
//将十进制转化为BCD码?
-
time.rtc_year=((year/10)<<4)+(year%10); //: 0x0 - 0x99(BCD format)
-
time.rtc_month=((month/10)<<4)+(month%10);//: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
-
time.rtc_date=((day/10)<<4)+(day%10); //: 0x1 - 0x31(BCD format)
-
time.rtc_day_of_week=week; //: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
-
time.rtc_hour=((hour/10)<<4)+(hour%10);//: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
-
time.rtc_minute=((minute/10)<<4)+(minute%10); //: 0x0 - 0x59(BCD format)
-
time.rtc_second=((second/10)<<4)+(second%10); //: 0x0 - 0x59(BCD format)
-
time.rtc_display_format=RTC_24HOUR;//: RTC_24HOUR, RTC_12HOUR
-
time.rtc_am_pm=RTC_PM;
-
if(ERROR==rtc_init(&time))
-
{
-
PrintStr("rtc set fail!\r\n");
-
-
}
-
-
}
阅读(3927) | 评论(0) | 转发(0) |