class="markdown_views prism-github-gist">
STM32的实时时钟是一个独立的定时器
通常会在后备区域供电端加一个纽扣电池,当主电源没有电的时,RTC不会停止工作
若VDD电源有效,RTC可以触发秒中断、溢出中断和闹钟中断
备份寄存器BKP
备份寄存器是42个16位的寄存器,他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电。当系统在待机模式下被唤醒或系统复位或电源复位时,他们也不会被复位
RTC配置步骤
1.使能电源时钟和后备区域时钟
2.取消后备区域的写保护,DBP
3.复位备份区域
4.外部低速振荡器使能,LSE
5.RTC时钟源选择,LSE
6.RTC时钟使能
7.进入配置模式
8.设置RTC预分频装载值
9.设置RTC计数器值
10.退出配置模式
11.初始化NVIC外设,设置RTC中断优先级
12.编写RTC中断处理函数
举例
typedef struct
{
u32 hour;
u32 min;
u32 sec;
}time_t;
time_t g_time;
void RTC_get()
{
u32 counter;
counter = RTC_GetCounter();
g_time.hour = counter / 3600;
g_time.min = (counter % 3600) / 60 ;
g_time.sec = counter % 60 ;
}
void RTC_IRQHandler()
{
if(RTC_GetFlagStatus(RTC_FLAG_SEC) == SET)
{
RTC_get();
printf("time %02d:%02d:%02d
", g_time.hour, g_time.min, g_time.sec);
}
RTC_ClearFlag(RTC_FLAG_SEC);
}
void RTC_init()
{
u16 bkp_data = 0xa5a5;
u16 prescaler = 32768 - 1;
NVIC_InitTypeDef nvic =
{
RTC_IRQn,
2,
2,
ENABLE
};
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
if(BKP_ReadBackupRegister(BKP_DR1) != bkp_data)
{
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET)
{
delay_ms(10);
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask();
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
RTC_EnterConfigMode();
RTC_SetPrescaler(prescaler);
RTC_WaitForLastTask();
RTC_SetCounter(0xf73f);
RTC_WaitForLastTask();
RTC_ExitConfigMode();
BKP_WriteBackupRegister(BKP_DR1, bkp_data);
}
else
{
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
}
NVIC_Init(&nvic);
RTC_get();
}