本帖最后由 caizhiwei 于 2021-2-13 12:32 编辑
用于片内集成RTC外设,可以用起来做时钟或者日历,今天它来了!
RTC简介
实时时钟是一个独立的定时器。 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟
日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC 模块和时钟配置系统( RCC_BDC 寄存器)处于后备区域,即在系统复位或从待机模式唤醒后, RTC
的设置和时间维持不变。
系统复位后,对后备寄存器和 RTC 的访问被禁止,这是为了防止对后备区域(BRKP)的意外写操作。
执行以下操作将使能对后备寄存器和 RTC 的访问:
● 设置 寄存器RCC_APB1EN的PWREN和BKPEN位, 使能电源和后 备接口时 钟
● 设置 寄存器PWR_CTRL的DBP位, 使能对后备寄 存器和RTC的 访问。
主要特性
● 可编程的预分频系数:分频系数最高为2^20。
● 32位的可编程计数器,可用于较长时间段的测量。
● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟( RTC时钟的频率必须小于PCLK1时
钟频率的四分之一以上)。
● 可以选择以下三种RTC的时钟源:
HSE时钟除以128
LSE振荡器时钟
LSI振荡器时钟( 详见3.2.8节RTC时钟)
● 2个独立的复位类型:
APB1接口由系统复位;
RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位(详见 3.1.3节)。
● 3个专门的可屏蔽中断:
闹钟中断,用来产生一个软件可编程的闹钟中断。
秒中断,用来产生一个可编程的周期性中断信号(最长可达 1秒)。
溢出中断,指示内部可编程计数器溢出并回转为0的状态。
1. 初始化RTC,这里需要注意的是:通过读备份域寄存器来判断是否需要写入时间初始值,如果RTC电池没有断电,则跳过此。
初始化函数如下:
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] RTC Init.
* @param None
* @retval None
*/
void BSP_RTC_Init(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_PWR | RCC_APB1PERIPH_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCtrl(ENABLE);
/* Check Backup data registers is correct*/
if (BKP_ReadBackupReg(BKP_DT1) != 0x5051)
{
/* Reset Backup Domain */
BKP_Reset();
/* Enable the LSI OSC */
RCC_LSEConfig(RCC_LSE_ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSESTBL) == RESET);
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSelection_LSE);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetDIV(32767);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set the RTC time */
BSP_RTC_Set(2020, 8, 8, 8, 8, 0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Writes data to Backup Register */
BKP_WriteBackupReg(BKP_DT1, 0x5051);
}
else
{
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Clear RTC pending flag */
RTC_ClearFlag(RTC_FLAG_PACE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
2. 通过不断查询的方式,就可以获取时间了!
void BSP_RTC_Time_Printf(void)
{
if(RTC_GetFlagStatus(RTC_FLAG_PACE) != RESET)
{
/* Update current time */
BSP_RTC_Get();
/* print the current time */
printf("\r\n");
printf("%d/%d/%d ", calendar.w_year, calendar.w_month, calendar.w_date);
printf("%02d:%02d:%02d %s", calendar.hour, calendar.min, calendar.sec, weekday_table[calendar.week]);
/* Clear the RTC Second flag */
RTC_ClearFlag(RTC_FLAG_PACE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
最后效果图如下:
代码附件:
BSP.zip
(2.75 KB)
|