目录
首先学习一个标准的rtc,首先应该看其用户手册:
stm用户手册描述rtc的主要特性:
两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时(12 或 24 小时制)、星 期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值 ( rtc时间格式)
系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。并且还可以进行夏令时 补偿。(不需要我们进行额外的处理)
使用数字校准功能对晶振精度的偏差进行补偿 (调高rtc的精度)
上电复位后,所有 RTC 寄存器都会受到保护,以防止可能的非正常写访问。(这里这样说明肯定存在寄存器写保护.也就是如果不将写保护关闭,无法操作rtc的寄存器)
无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC 便不会停止工作 (RTC稳定性很强)
设置异步分频和同步分频:
使用两个预分频器时,推荐将异步预分频器配置为较高的值,以最大程度降低功耗。
要使用频率为 32.768 kHz 的 LSE 获得频率为 1 Hz 的内部时钟 (ck_spre),需要将异步预分 频系数设置为 128,并将同步预分频系数设置为 256。
备份寄存器:
通过该寄存器,掉电不丢失,可以判断是不是第一次初始化RTC,方便计时
具体实现:
u8 RTC_Init(void)
{
RTC_InitTypeDef RTC_InitStructure; // 时钟结构体
RTC_TimeTypeDef RTC_TimeTypeInitStructure; // 时间结构体
RTC_DateTypeDef RTC_DateTypeInitStructure; // 日期结构体
u16 retry = 0X1FFF;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x5050) //是否第一次配置?
{
//LSE 内部时钟 保证外部时钟出现错误的时候 内部时钟仍然正常
RCC_LSEConfig(RCC_LSE_ON);
//检查指定的RCC标志位设置与否,等待低速晶振就绪
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
retry++;
delay_ms(10);
}
if (retry==0)
{
return 1; //LSE 开启失败.
}
//设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
RTC_InitStructure.RTC_AsynchPrediv = 127; //RTC异步分频系数(1~0X7F)
RTC_InitStructure.RTC_SynchPrediv = 0xFF; //RTC同步分频系数(0~7FFF)
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;//RTC设置为,24小时
RTC_Init(&RTC_InitStructure);
// 设置时间
RTC_TimeTypeInitStructure.RTC_Hours = hour;
RTC_TimeTypeInitStructure.RTC_Minutes = min;
RTC_TimeTypeInitStructure.RTC_Seconds = sec;
RTC_TimeTypeInitStructure.RTC_H12 = ampm;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeTypeInitStructure);
// 设置日期
RTC_DateTypeInitStructure.RTC_Date = date;
RTC_DateTypeInitStructure.RTC_Month = month;
RTC_DateTypeInitStructure.RTC_WeekDay = week;
RTC_DateTypeInitStructure.RTC_Year = year;
RTC_SetDate(RTC_Format_BIN, &RTC_DateTypeInitStructure);
RTC_WriteBackupRegister(RTC_BKP_DR0, 0x5050); //标记已经初始化过了
}
return 0;
}