STM32操作寄存器配置RTC初始化日历的方法
备份寄存器
- 备份寄存器用来存储用户应用程序数据,备份域中的数据在任何内部外部复位中都不会受到影响,掉电时由VBAT供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位。但是可由备份域控制寄存器软件复位,并且复位后对备份寄存器和RTC的访问被禁止。
备份域控制寄存器(RCC_BDCR)
- RCC_BDCR寄存器中的 LSEON、LSEBYP、RTCSEL 和 RTCEN 位处于备份域。因此,这些位在复位后处于写保护状态,这些位只能由备份域复位清除,任何内部或外部复位都不会影响这些位。
RTC配置
- 首先,RTC模块和RCC_BDCR寄存器处于后备区域,在使用RCC模块之前要先设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟。
SET_BIT( RCC->APB1ENR, RCC_APB1ENR_BKPEN ); //备份接口时钟使能,允许访问备份区域
SET_BIT( RCC->APB1ENR, RCC_APB1ENR_PWREN ); //电源接口时钟使能
- 其次,在系统复位后,对后备寄存器和RTC的访问是被禁止的,对备份域进行写操作时需要将电源控制寄存器的DBP位置1,所以还要设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。
SET_BIT( PWR->CR, PWR_CR_DBP ); //允许写入RTC和后备寄存器
- 上面是首先需要配置的两步,接下来就是配置主体部分,把配置内容放入判断语句中,如果RTC已经配置过了就跳过,不然每次日期在重新上电后都会初始化:
if ( !READ_BIT( RCC->BDCR, RCC_BDCR_RTCEN )) //判断RTC时钟是否使能
{
......
}
- 关于RCC的配置:
CLEAR_BIT(RCC->BDCR,RCC_BDCR_LSEBYP); //LSE不被旁路
SET_BIT(RCC->BDCR,RCC_BDCR_LSEON); //开启32kHz时钟的振荡器
while ( ! READ_BIT( RCC->BDCR, RCC_BDCR_LSERDY )){} //等待外部32kHz时钟振荡器就绪
SET_BIT( RCC->BDCR, RCC_BDCR_RTCSEL_LSE ); //LSE振荡器作为RTC时钟
SET_BIT( RCC->BDCR, RCC_BDCR_RTCEN ); //使能RTC时钟
- 以下就是关于RTC的配置了:
- RTC寄存器同步标志位——RTC_CRL_RSF由硬件置1,软件清0。在任何读操作之前必须等待此位被置1,确保寄存器已经被同步;
- RTC操作关闭位——RTC_CRL_RTOFF为只读位,若此位为0,则无法对RTC寄存器进行写操作。
/* Wait for RTC registers synchronization */
CLEAR_BIT( RTC->CRL, RTC_CRL_RSF ); //软件清零
while ( ! READ_BIT( RTC->CRL, RTC_CRL_RSF )){} //等待硬件置1,确保同步。
while ( ! READ_BIT( RTC->CRL, RTC_CRL_RTOFF )){} //等待上一次对RTC寄存器的写操作完成
RTC->CRH = 0u; //上一步写完成后写入CRH,禁止RTC产生中断
- 向RTC_CNT、RTC_ALR或RTC_PRL寄存器写入数据必须先进入配置模式:
/* Wait until last write operation on RTC registers has finished */
while ( ! READ_BIT( RTC->CRL, RTC_CRL_RTOFF )){} //等待上次操作完成,准备向RTC寄存器写入
SET_BIT( RTC->CRL, RTC_CRL_CNF ); //进入配置模式
- RCC预分频装载计数器来定义计数器时钟频率,输入时钟频率是32.768kHz,低位寄存器中写入7FFF可获得周期为1秒的信号(计数器时钟频率 = 输入时钟频率 / PRL[19:0]+1):
/* Set RTC prescaler: set RTC period to 1sec */
RTC->PRLH = 0x0000u;
RTC->PRLL = 0x7FFFu;
- 使用Unix时间戳转换工具设置时间元年为2012年1月1日:
/* 时钟计数器初始化为 GMT: Sun, 1 Jan 2012 00:00:00 UTC */
RTC->CNTH = (uint16_t)( 1325376000u >> 16 );
RTC->CNTL = (uint16_t)( 1325376000u ); //计数器寄存器
CLEAR_BIT( RTC->CRL, RTC_CRL_CNF ); //退出配置模式
while ( ! READ_BIT( RTC->CRL, RTC_CRL_RTOFF )){} //等待写入数据完成
这样大概就是RTC整个配置的步骤吧,其中还是有些地方不太懂,之后会慢慢学习完善补充。能帮到大家最好,不足之处还请大家多多指正!