RTC的初始化程序

RTC_First_Config:这个函数负责首次配置RTC,包括启用PWR和BKP外设时钟,解除后备域写保护,启用和配置外部32.768kHz晶振,配置RTC预分频器以生成1Hz时钟。如果需要,还可以启用秒中断。

void RTC_First_Config(void) {
    // 启用PWR和BKP外设时钟(来自APB1)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    // 解除对后备域的写保护
    PWR_BackupAccessCmd(ENABLE);
    // 重置后备寄存器模块/备份寄存器模块复位
    BKP_DeInit();
    // 启用外部32.768KHZ晶振
    RCC_LSEConfig(RCC_LSE_ON);
    // 等待LSE稳定
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
    // 配置RTC时钟源为LSE(外部低速晶振32.768KHZ)
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    // 启用RTC时钟
    RCC_RTCCLKCmd(ENABLE);
    // 等待APB1时钟与RTC时钟同步,这样才能读写寄存器
    RTC_WaitForSynchro();
    // 在写入寄存器前,必须确保前一个操作已完成
    RTC_WaitForLastTask();
    // 设置RTC预分频器,使RTC时钟为1Hz
    RTC_SetPrescaler(32767); // RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
    // 等待寄存器写入完成
    RTC_WaitForLastTask();

    // 如果不使用RTC秒中断,可以忽略以下两行
//    RTC_ITConfig(RTC_IT_SEC, ENABLE); // 启用秒中断
//    RTC_WaitForLastTask(); // 等待写入完成
}

RTC_Config:这个函数检查后备寄存器的数据,如果数据丢失(即表示这是第一次配置或者后备电池掉电后重启),它会调用RTC_First_Config重新配置RTC,并向后备寄存器写入一个特殊标记以指示RTC已配置。如果后备寄存器的数据没有丢失(即RTC已配置),它会简单地启用RTC时钟并等待时钟同步。

void RTC_Config(void) {
    // 在后备寄存器1中存储了一个特殊字符0xA5A5
    // 第一次上电或后备电池掉电后,该寄存器数据丢失,表示RTC数据丢失,需要重新配置
    if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) { // 判断寄存器数据是否丢失
        RTC_First_Config(); // 重新配置RTC
        BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); // 配置完成后,向后备寄存器写入特殊字符0xA5A5
    } else {
        // 如果后备寄存器没有掉电,则无需重新配置RTC
        // 这里我们可以利用RCC_GetFlagStatus()函数查看本次复位类型
        if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) {
            // 这是上电复位
        } else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) {
            // 这是外部RST引脚复位
        }
        // 清除RCC中的复位标志
        RCC_ClearFlag();

        // 虽然RTC模块无需重新配置,并且掉电后在后备电池供电下继续运行
        // 但是每次上电后,仍需要启用RTCCLK
        RCC_RTCCLKCmd(ENABLE); // 启用RTCCLK
        RTC_WaitForSynchro(); // 等待RTC时钟与APB1时钟同步

        // 如果不使用RTC秒中断,可以忽略以下两行
//        RTC_ITConfig(RTC_IT_SEC, ENABLE); // 启用秒中断
//        RTC_WaitForLastTask(); // 等待操作完成
    }
}

逻辑总结

  1. 启用必要的外设时钟:PWR和BKP时钟。
  2. 解除后备域的写保护:允许访问和配置后备域。
  3. 重置后备寄存器:确保寄存器处于初始状态。
  4. 配置LSE并等待其稳定:设置LSE作为RTC的时钟源。
  5. 配置RTC时钟源并启用RTC:确保RTC使用正确的时钟源。
  6. 等待时钟同步:确保RTC与系统时钟同步。
  7. 设置预分频器:使RTC计时精确到秒。
  8. 检查并初始化RTC:根据备份寄存器的状态决定是否初次配置RTC。
  9. (可选)启用RTC中断:根据需要启用中断功能。

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个关于STM32L431的RTC初始化库函数,程序主频80MHZ,采用24小时制,使用LSI作为RTC的时钟源: rtc.h 文件: ```c #ifndef __RTC_H #define __RTC_H #include "stm32l431xx.h" void RTC_Init(void); #endif /* __RTC_H */ ``` rtc.c 文件: ```c #include "rtc.h" void RTC_Init(void) { // 使能PWR和RTC时钟 RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN; RCC->APB1ENR1 |= RCC_APB1ENR1_RTCAPBEN; // 使能LSI时钟并等待其稳定 RCC->CSR |= RCC_CSR_LSION; while(!(RCC->CSR & RCC_CSR_LSIRDY)); // 关闭RTC写保护 RTC->WPR = 0xCA; RTC->WPR = 0x53; RTC->ISR |= RTC_ISR_INIT; while(!(RTC->ISR & RTC_ISR_INITF)); // 初始化RTC寄存器 RTC->PRER = (uint32_t)(((uint32_t)799 << 16) | (uint32_t)1249); // LSI时钟预分频器 RTC->TR = (uint32_t)(((uint32_t)0 << RTC_TR_SU_Pos) | ((uint32_t)0 << RTC_TR_ST_Pos) | ((uint32_t)0 << RTC_TR_MNU_Pos) | ((uint32_t)0 << RTC_TR_MNT_Pos) | ((uint32_t)0 << RTC_TR_HU_Pos) | ((uint32_t)0 << RTC_TR_HT_Pos)); // 时间寄存器 RTC->DR = (uint32_t)(((uint32_t)1 << RTC_DR_WDU_Pos) | ((uint32_t)1 << RTC_DR_YU_Pos) | ((uint32_t)2 << RTC_DR_YT_Pos) | ((uint32_t)0 << RTC_DR_MU_Pos) | ((uint32_t)1 << RTC_DR_MT_Pos) | ((uint32_t)2 << RTC_DR_DU_Pos) | ((uint32_t)8 << RTC_DR_DT_Pos)); // 日期寄存器 RTC->CR &= ~RTC_CR_FMT; // 24小时制 RTC->ISR &= ~RTC_ISR_INIT; // 启用RTC RTC->CR |= RTC_CR_BYPSHAD; // 关闭后备寄存器 RTC->CR |= RTC_CR_WUTE; // 使能Wakeup定时器 RTC->CR |= RTC_CR_RSF; // 使能时间和日期的同步 RTC->ISR &= ~RTC_ISR_INITS; // 等待RTC同步完成 while(!(RTC->ISR & RTC_ISR_RSF)); } ``` 你可以在主程序中包含 rtc.h 头文件,并在初始化部分调用 RTC_Init() 函数来初始化RTC

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值