stm32 rtc 实时时钟

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\n", 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); //LSE振荡器作为RTC时钟
        RCC_RTCCLKCmd(ENABLE); //RTC时钟开启
        RTC_WaitForLastTask(); //RTC操作关闭(上一次对RTC寄存器的写操作已经完成)
        RTC_WaitForSynchro(); //寄存器同步标志(寄存器已经被同步)

        RTC_ITConfig(RTC_IT_SEC, ENABLE); //屏蔽中断请求(允许秒中断)
        RTC_WaitForLastTask();

        RTC_EnterConfigMode(); //配置标志(进入配置模式)

        RTC_SetPrescaler(prescaler); //预分频装载值
        RTC_WaitForLastTask();

        RTC_SetCounter(0xf73f); //设置计数器值(17:34:55)
        RTC_WaitForLastTask();

        RTC_ExitConfigMode(); //退出配置模式(开始更新RTC寄存器)

        BKP_WriteBackupRegister(BKP_DR1, bkp_data); //写备份数据
    }
    else
    {
        RTC_WaitForSynchro();
        RTC_ITConfig(RTC_IT_SEC, ENABLE);
        RTC_WaitForLastTask();
    }

    NVIC_Init(&nvic);   

    RTC_get();
}
posted @ 2017-08-15 23:23  thomas_blog  阅读(222)  评论(0编辑  收藏  举报