• STM32-RTC 配置笔记


    转自:http://www.amobbs.com/thread-5523800-1-1.html

    本人也是STM32初学者,也买了野火M3实验板学习,学到STM32-RTC时感觉RTC涉及的体系比较杂乱,所以做了相应的笔记,现分享给和我一样的初学者们,也当为大家提供点小力吧!大神们就勿喷了。


    STM32 的RTC 时钟配置 因为涉及了许多的寄存器,如:BKP、PWR、RTC ,弄得很杂乱,现在由我来做个RTC配置的总结。
    RTC简介:RTC是一个实时时钟是一个独立的定时器,RTC模块拥有一组连续计数的计数器,在相应软件配置下,可以提供时钟、日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
    配置RTC前需知:

    BKP:
    RTC模块和时钟配置系统的寄存器是在后备区域的(即BKP),通过BKP后备区域来存储RTC配置的数据可以让在系统复位或待机模式下唤醒后 RTC里面配置的数据维持不变。

    PWR:
    PWR为电源的寄存器,我们需要用到的是电源控制寄存器(PWR_CR),通过使能PWR_CR的DBP位来取消后备区域BKP的写保护。

    RTC :
    由一组可编程计数器组成,分成两个主要模块。第一个模块是RTC的预分频
    模块,它可编程产生最长为1 秒的RTC时间基准TR_CLK 。RTC的预分频模块包含了一个20位的
    可编程分频器(RTC 预分频器) 。如果在RTC_CR寄存器中设置了相应的允许位,则在每个实时时钟(RTC)TR_CLK 周期中RTC产生一个中断( 秒中断) 。第二个模块是一个32位的可编程计数器,可被初始
    化为当前的系统时间。系统时间按TR_CLK 周期累加并与存储在RTC_ALR寄存器中的可编程时间相比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。 



    需知部分告一段落,如果想更详细的了解可以打开你的stm32使用手册查看。

    下面讲解下配置整体过程:

    第一步: 通过设置寄存器RCC_APB1ENR的PWREN 和BKPEN位来打开电源和后备接口的时钟 
    调用库函数:
    RCC_APB1PeriphClockCmd (RCC_APB1Periph_PWR | RCC_APB1Periph_BKP,ENABLE );

    第二步:电源控制寄存器(PWR_CR) 的DBP位来使能对后备寄存器和RTC的访问
    调用库函数:
    PWR_BackupAccessCmd(ENABLE ); 


    第三步:初始化复位BKP寄存器

    调用库函数:

    BKP_DeInit ();

    第四步:设置RTCCLK,如下图:



    我们需要将RTCCLK 设置为 LSE OSC  这个32.768KHZ的晶振。

    调用的库函数:

    RCC_LSEConfig (RCC_LSE_ON);

    While(!RCC_GetFlagStatus (RCC_FLAG_HSERDY));//设置后需要等待启动

    第五步:将RTC输入时钟 选择为LSE时钟 输入并使能RTC,等待RTC和APB时钟同步

    调用库函数:

    RCC_RTCCLKConfig (RCC_RTCCLKSource_LSE);//选择LSE为RTC设备 的 时钟
    RCC_RTCCLKCmd (ENABLE );//使能RTC
    RTC_WaitForSynchro();//等待同步

    第六步:配置RTC 时钟 参数。

    1.   查询RTOFF位,直到RTOFF的值变为’1’ 
    2.   置CNF值为1 ,进入配置模式 
    3.   对一个或多个RTC寄存器进行写操作 
    4.   清除CNF标志位,退出配置模式 
    5.   查询RTOFF,直至RTOFF位变为’1’ 以确认写操作已经完成。 
    仅当CNF标志位被清除时,写操作才能进行,这个过程至少需要3个RTCCLK 周期。

    好!就按照上述步骤 用 库函数来配置:

    /* 1.   查询RTOFF位,直到RTOFF的值变为1 */
    RTC_WaitForLastTask();//大家可以打开函数库看看这个函数内部的代码,就是查询RTOFF的值

    /*
      2.   置CNF值为1 ,进入配置模式 
      3.   对一个或多个RTC寄存器进行写操作
      4.   清除CNF标志位,退出配置模式 
    */
    RTC_SetPrescaler(32767);   // 这里配置了预分频值,大家可以打开函数库看看这个函数的内部的代码,里面就有包含了2、3、4讲述的操作。
      补充:根据以下公式,这些位用来定义计数器的时钟频率: 
        fTR_CLK = fRTCCLK/(PRL[19:0]+1) ,我们LSE是32.768KHZ = 32768Hz,由上述公式就可以知道最终f TR_CLK = 1Hz  那么刚刚刚好就是1秒
      
    记住了每完成一个操作 一般都要查询RTOFF来判断是否RTC正在更新数据,如果是则等待他完成!!!

    TC_WaitForLastTask();//等待更新结束


    RTC_ITConfig(RTC_IT_SEC, ENABLE);//配置秒中断

    RTC_WaitForLastTask();//等待更新结束


    好了,整个RTC的配置 也就是按照这个步骤配置下来,大家好好理解下吧,多多打开你的STM32使用手册 和 STM32官方库说明书,看多几遍几个寄存器几个函数内部代码更有助于理解!

    整体配置RTC代码:

    void RTC_Configuration(void)
    {
            /* Enable PWR and BKP clocks */
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
            
            /* Allow access to BKP Domain */
            PWR_BackupAccessCmd(ENABLE);
            
            /* Reset Backup Domain */
            BKP_DeInit();
            
            /* Enable LSE */
            RCC_LSEConfig(RCC_LSE_ON);

            /* Wait till LSE is ready */
            while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
            {}
            
            /* Select LSE as RTC Clock Source */
            RCC_RTCCLKConfig(RCC_RTCCLKSource_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_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)*/
      
      
            /* Wait until last write operation on RTC registers has finished */
            RTC_WaitForLastTask();
            

            /* Enable the RTC Second */
            RTC_ITConfig(RTC_IT_SEC, ENABLE);

            /* Wait until last write operation on RTC registers has finished */
            RTC_WaitForLastTask();

    如果有不正确的地方也请各位多多指教,本人及时纠正;欢迎大家来和我相互交流学习,谢谢大家。

  • 相关阅读:
    【转载】利用一个堆溢出漏洞实现 VMware 虚拟机逃逸
    metasploit(MSF)终端命令大全
    Linux怎么开启ssh
    Day5_模块与包(import)(form......import....)
    Day5_递归_二分法
    Day5_协程函数_面向过程
    Day4_生成器_三元表达式_列表解析_生成器表达式
    Day4_迭代器
    openssh升级的坑爹之路
    Day4_装饰器
  • 原文地址:https://www.cnblogs.com/ct1104/p/4011922.html
Copyright © 2020-2023  润新知