打印
[活动专区]

【AT-START-F407测评】04 RTC驱动

[复制链接]
511|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 caizhiwei 于 2021-2-13 12:32 编辑

     用于片内集成RTC外设,可以用起来做时钟或者日历,今天它来了!

RTC简介
实时时钟是一个独立的定时器。 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟
日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC 模块和时钟配置系统( RCC_BDC 寄存器)处于后备区域,即在系统复位或从待机模式唤醒后, RTC
的设置和时间维持不变。
系统复位后,对后备寄存器和
RTC 的访问被禁止,这是为了防止对后备区域(BRKP)的意外写操作。
执行以下操作将使能对后备寄存器和
RTC 的访问:
● 设置 寄存器
RCC_APB1ENPWRENBKPEN位, 使能电源和后 备接口时 钟
● 设置 寄存器
PWR_CTRLDBP位, 使能对后备寄 存器和RTC的 访问。


主要特性
可编程的预分频系数:分频系数最高为2^20。
32位的可编程计数器,可用于较长时间段的测量。
2个分离的时钟:用于APB1接口的PCLK1和RTC时钟( RTC时钟的频率必须小于PCLK1时
钟频率的四分之一以上)。
可以选择以下三种RTC的时钟源:
 HSE时钟除以128
 LSE振荡器时钟
 LSI振荡器时钟( 详见3.2.8RTC时钟
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)


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

857

帖子

14

粉丝