我参照rtc例程,上电读取BKP_DATA_0若不是0xA5A5,则初始化并校准时钟,引脚vbat接电池。则板子断电时间也会更新保存。
现在我通过tcp连接服务器,定期对比服务器时间与板子rtc,若差别很大需要校准rtc时间。但是当我在tcp接收任务中调用time_adjust,通过rtc_counter_set给rtc数据寄存一个新数值时候。发现更新数值后的rtc_lwoff_wait一直卡住了,导致rtc更新失败,tcp接收任务也卡死。
void time_adjust( uint32_t cnt )
{
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
/* change the current time */
//rtc_counter_set(time_regulate());
if( cnt > 0)
rtc_counter_set( cnt );
else
rtc_counter_set( 1549759070 );
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
}
后来测试在初始化程序中直接在初始化后执行校准time_adjust(1548813145);
依然是在第二个rtc_lwoff_wait();卡死。
请问这是什么问题。初始化的校准是好用的,一旦rtc配置过后,就不能再次校准了。通过tcp通讯,校准rtc与服务器时间是很常用的,应该怎么校准呢?
谢谢
int main(void)
{
/* COM1 configure */
gd_eval_com_init(EVAL_COM1);
/* NVIC configure */
nvic_configuration();
printf( "\r\n This is a RTC demo...... \r\n" );
if (bkp_read_data(BKP_DATA_0) != 0xA5A5){
/* backup data register value is not correct or not yet programmed
(when the first time the program is executed) */
printf("\r\nThis is a RTC demo!\r\n");
printf("\r\n\n RTC not yet configured....");
/* RTC configuration */
rtc_configuration();
printf("\r\n RTC configured....");
/* adjust time by values entred by the user on the hyperterminal */
time_adjust();
bkp_write_data(BKP_DATA_0, 0xA5A5);
}else{
/* check if the power on reset flag is set */
if (rcu_flag_get(RCU_FLAG_PORRST) != RESET){
printf("\r\n\n Power On Reset occurred....");
}else if (rcu_flag_get(RCU_FLAG_SWRST) != RESET){
/* check if the pin reset flag is set */
printf("\r\n\n External Reset occurred....");
}
printf("\r\n No need to configure RTC....");
/* wait for RTC registers synchronization */
rtc_register_sync_wait();
/* enable the RTC second */
rtc_interrupt_enable(RTC_INT_SECOND);
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
}
#ifdef RTCCLOCKOUTPUT_ENABLE
/* enable PMU and BKPI clocks */
rcu_periph_clock_enable(RCU_BKPI);
rcu_periph_clock_enable(RCU_PMU);
/* allow access to BKP domain */
pmu_backup_write_enable();
/* disable the tamper pin */
bkp_tamper_detection_disable();
/* enable RTC clock output on tamper Pin */
bkp_rtc_calibration_output_enable();
#endif
/* clear reset flags */
rcu_all_reset_flag_clear();
time_adjust(1548813145);
/* display time in infinite loop */
time_show();
while (1){
}
}
查看手册校准函数没有问题,也是例程带的。
20.3.4. RTC 配置
RTC 内核中的 RTC_PLR、 RTC_CNT 和 RTC_ALRMR 寄存器都是可写的。只有在外设进入
配置模式后,这些寄存器的值才能进行设置。通过查询 RTC_CTLR 寄存器的 CMF 位,可以
检测配置模式的状态。只有在外设退出配置模式后,之前对这些寄存器的写操作才能生效,且
至少需要三个 RTCCLK 周期才能完成。当写操作完成后, RTC_CTLR 寄存器中的 LWOFF 位
的值变为‘1’。下一个写操作必须等待上次写操作完成之后才能进行。
配置过程如下:
1. 等待 RTC_CTLR 寄存器中的 LWOFF 位的值变为 1;
2. 通过将 RTC_CTLR 寄存器中的 CMF 置位来进入配置模式;
3. 对 RTC 寄存器进行写操作;
4. 通过将 RTC_CTLR 寄存器中的 CMF 清零来退出配置模式;
5. 等待 RTC_CTLR 寄存器中的 LWOFF 位的值变为 1。 |