我这里用的开发板上芯片是 IMX6ULL,但是,由于恩智浦提供的 IMX6ULL芯片的参考手册关于 RTC章节的不全面。所以,实际在开发时使用了 《IMX6UL参考手册》。
对参考手册的理解如下:
LPSRTCMR寄存器 与 LPSRTCLR寄存器是存时间的两个寄存器。即用两个寄存器来存时间。
读取SRTC的LPSRTCMR和LPSRTCLR获取时间值的时候,时间是错误的。
手册上写到:LPSRTCMR寄存器是 SRTC实时时钟的高15bit。LPSRTCLR寄存器是 SRTC的低32位,这样的话,RTC时钟的计数器就是47 bit (即 15+32)。
在 “I.MX6U参考资料 / I.MX6ULL SDK包” 目录下,有两个程序,分别是 Windows版本与Linux版本,其中 SDK_2.2_MCIM6ULL_RFP_Win.exe为 Windows版本。
(1) 安装 SDK_2.2_MCIM6ULL_RFP_Win.exe。
(2) SDK_2.2_MCIM6ULL_RFP_Win.exe安装完成后,打开 devices\MCIMX6Y2\drivers目录。
(3) devices\MCIMX6Y2\drivers目录下, fsl_snvs_hp.c文件是 针对 HP-RTC 时钟写的用例。
而根据《IMX6UL参考手册》,存储时钟的两个寄存器(即LPSRTCMR寄存器 与 LPSRTCLR寄存器)说明与 LP-RTC时钟是一样的。说明是:LPSRTCMR存储了高15位,LPSRTCLR存储了低32位。
fsl_snvs_hp.c文件中:
设置时间接口:SNVS_HP_RTC_SetDatetime()接口中,设置寄存器的时间值如下:
base->HPRTCMR = (uint32_t)(seconds >> 17U);
base->HPRTCLR = (uint32_t)(seconds << 15U);
获取时间接口:SNVS_HP_RTC_GetSeconds()接口中,获取时间,如下:
tmp = (base->HPRTCMR << 17U) | (base->HPRTCLR >> 15U);
可以得出这样的结论:
可以看出,LPSRTCMR寄存器存储时间值的高15位,LPSRTCLR寄存器存储时间值的低17位。
现在,根据 恩智浦提供的 HP-RTC 时钟代码用例,更改本实验的中 LP-RTC时钟实验代码。更改接口涉及:设置时间接口与获取时间接口。
更改如下:
/*设置时间的函数*/
void rtc_date_set(struct rtc_datetime* rtc_date)
{
uint64_t seconds = 0;
unsigned char rtc_state = 0;
rtc_state = SNVS->HPCR; //记录下RTC的开关状态
rtc_disable();
seconds = rtc_coverdate_to_seconds(rtc_date);
SNVS->LPSRTCMR = (unsigned int)(seconds >> 17); //高15位
SNVS->LPSRTCLR = (unsigned int)(seconds << 15); //低17位
if((rtc_state & 0X01) == 1) //之前已打开RTC
rtc_enable();
}
/*获取RTC时间函数*/
void rtc_get_datetime(struct rtc_datetime* rtc_date)
{
uint64_t seconds = 0;
seconds = (SNVS->LPSRTCMR << 17) | (SNVS->LPSRTCLR >> 15);
rtc_convertseconds_to_datetime(seconds, rtc_date);
}
编译程序后,烧录到SD卡中。在开发板上运行后,时间打印正确。
串口打印如下所示:
可以得出结论,LPSRTCMR寄存器作为SRTC计数器的高15位,但是,LPSRTCLR寄存器bit31:15作为SRTC计数器的低17位。相当于SRTC的计数器是个32位的!!!
而不是像《IMX6UL参考手册》中的说明那样:LPSRTCMR寄存器存储时间值的高15位,LPSRTCLR寄存器存储时间值的低32位!!!