纠结的STM32 RTC时钟源LSE

发布者:PeacefulOasis最新更新时间:2017-02-17 来源: eefocus关键字:STM32  RTC  时钟源  LSE 手机看文章 扫描二维码
随时随地手机看文章

一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题。直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题。

这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻,手册上要求使用6pf,这个规格的晶振市场上太少,鱼龙混杂,中招的高手菜鸟不在少数。我们自己的板也是如此,几经波折,反反复复尝试使用不同的规格的晶振,替换外部的电容,电阻都没有能让这个32.768K的LSE起振。但是又需要有RTC来提供时间,考虑的方法主要有2种,第一采用外部RTC时钟芯片,如DS1302。第二是使用内部其它的时钟源来提供RTC时钟。毫无疑问,目前板已经制好,添加时钟芯片肯定造成板上布局更改,还得重新打板,这里采用了第二种方法。

查看STM32的手册上时钟树,如下:


除去不能起振的外部低速LSE外,可供使用的只有LSI和HSE的128分频,LSI这个是内部的40KHz RC振荡器,频率在30~60KHz浮动,自然这个不能用于RTC计时,误差太大。

我们的板上配的是STM32F107这款芯片,外部高速晶振是25MHz的。128分频后频率为 25000000 / 128 = 195312.5 Hz,很显然这里也不能做到很精确,有小许误差。

然后设置RTC_PRL寄存器,写入195312这个分频值,便可以得到1Hz的频率。使用HSE作为RTC时钟,缺点就是无法在断开电源后使用后备电池进行供电,维持RTC的正常。下次需要上位机重新去设置时间。


代码大致如下:

void RTC_Configuration(void)  

{  

    u8 i = 0;  

    /* Enable PWR and BKP clocks */  

    /* PWR时钟(电源控制)与BKP时钟(RTC后备寄存器)使能 */  

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);  

  

    /* Allow access to BKP Domain */  

    /*使能RTC和后备寄存器访问 */  

    PWR_BackupAccessCmd(ENABLE);  

  

    /* Reset Backup Domain */  

    /* 将外设BKP的全部寄存器重设为缺省值 */  

    BKP_DeInit();  

  

    /* Enable LSE */  

    /* 使能LSE(外部32.768KHz低速晶振)*/  

    RCC_LSEConfig(RCC_LSE_ON);  

    

    /* Wait till LSE is ready */  

    /* 等待外部晶振震荡稳定输出 */  

    TIM5_Init_Query(CALC_TYPE_MS); //ms 级别  

    for (i = 0;i < 10;i++) //10次检测,如果LSE仍然没有起振,证明这玩意有问题,跳出循环  

    {  

        if (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != RESET)  

            break;  

        TIM5_MS_CALC(1); //1ms延时  

    }  

    //while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}  

    if (i == 10)  

    {  

        //RCC->CSR |= 0x1; //开启内部低速晶振  

        //while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);  

        //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //使用LSI提供RTC时钟  

        //使用外部高速晶振 128分频  

        RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);   

    }else  

    {  

        /* Select LSE as RTC Clock Source */  

        /*使用外部32.768KHz晶振作为RTC时钟 */                           

        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  

    }  

  

    /* Enable RTC Clock */  

    /* 使能 RTC 的时钟供给 */  

    RCC_RTCCLKCmd(ENABLE);  

  

    /* Wait for RTC registers synchronization */  

    /*等待RTC寄存器同步 */  

    RTC_WaitForSynchro();  

  

    /* Wait until last write operation on RTC registers has finished */  

    /* 等待上一次对RTC寄存器的写操作完成 */  

    RTC_WaitForLastTask();  

  

    /* Enable the RTC Second */  

    /* 使能RTC的秒中断 */  

    RTC_ITConfig(RTC_IT_SEC, ENABLE);  

  

    /* Wait until last write operation on RTC registers has finished */  

    /* 等待上一次对RTC寄存器的写操作完成 */  

    RTC_WaitForLastTask();  

    

    /* Set RTC prescaler: set RTC period to 1sec */  

    /* 32.768KHz晶振预分频值是32767,如果对精度要求很高可以修改此分频值来校准晶振 */  

    if (i != 10) //LSE不能正常  

        RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */  

    else  

        RTC_SetPrescaler(195312); //25000000 / 128 = 195312.5,如果是8M / 128 = 62500,则这里应该填为62499  

  

    /* Wait until last write operation on RTC registers has finished */  

    /* 等待上一次对RTC寄存器的写操作完成 */  

    RTC_WaitForLastTask();  

}  

  

void Init_RTC(void)  

{  

    /* 以下if...else.... if判断系统时间是否已经设置,判断RTC后备寄存器1的值 

     是否为事先写入的0XA5A5,如果不是,则说明RTC是第一次上电,需要配置RTC, 

     提示用户通过串口更改系统时间,把实际时间转化为RTC计数值写入RTC寄存器, 

     并修改后备寄存器1的值为0XA5A5。 

     else表示已经设置了系统时间,打印上次系统复位的原因,并使能RTC秒中断 

    */  

    if (BKP_ReadBackupRegister(BKP_DR1) != RTC_SEQ_ID)  

    {  

        /* Backup data register value is not correct or not yet programmed (when 

           the first time the program is executed) */  

      

        /* RTC Configuration */  

        RTC_Configuration();  

  

   

        /* Adjust time by values entred by the user on the hyperterminal */  

        RTC_SetCounter(Time_Regulate(YEAR_BASE,01,01,0,0,0)); //2008-1-1 0:0:0  

        /* 修改后备寄存器1的值为0XA5A5 */  

        BKP_WriteBackupRegister(BKP_DR1, RTC_SEQ_ID);  

    }else  

    {  

        /* Check if the Power On Reset flag is set */  

        //RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET  

        //  printf("\r\n\n Power On Reset occurred....");  

          

        /* Check if the Pin Reset flag is set */  

        //else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)  

        //  printf("\r\n\n External Reset occurred....");  

        if (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)  

        {  

            //RCC->CSR |= 0x1; //开启内部低速晶振  

            //while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);  

            //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //使用LSI提供RTC时钟  

            //RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);  

            RTC_Configuration();  

        }  

        //printf("\r\n No need to configure RTC....");  

        /* Wait for RTC registers synchronization */  

        RTC_WaitForSynchro();  

  

        /* Enable the RTC Second */  

        RTC_ITConfig(RTC_IT_SEC, ENABLE);  

      

        /* Wait until last write operation on RTC registers has finished */  

        RTC_WaitForLastTask();  

    }  

  

#ifdef RTCClockOutput_Enable  

  /* Enable PWR and BKP clocks */  

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);  

        

  /* Allow access to BKP Domain */  

  PWR_BackupAccessCmd(ENABLE);  

  

  /* Disable the Tamper Pin */  

  BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper 

                                 functionality must be disabled */  

  

  /* Enable RTC Clock Output on Tamper Pin */  

  BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);  

#endif  

  

  /* Clear reset flags */  

  RCC_ClearFlag();  

}  

实际测试,RTC效果还行,然后配合上位机隔一定的时间后同步时间基本上能够满足要求。

万恶的LSE晶振,这东西简直不能忍受......


关键字:STM32  RTC  时钟源  LSE 引用地址:纠结的STM32 RTC时钟源LSE

上一篇:STM8S 与 STM32F IO口输出速率测试
下一篇:STM32 使用通用计时器实现微秒延时

推荐阅读最新更新时间:2024-03-16 15:33

STM32的启动过程分析
对于stm32的启动过程一直心存疑惑。今天找了很多资料,进行了一个大致的分析。 1.cortex M3的复位过程(来自官方资料) 上述开机启动流程比较详细,内容较为全面,但部分步骤可以省略(红字可省略标出),因为对于某些初始化,我们可能会在main函数中重新配置。 2.复位程序的详细跟踪分析(重点) 此次分析基于单步跟踪stm32从复位到main()函数的汇编代码。 1.stm32复位程序 ; Reset handler Reset_Handler PROC EXPORT Reset_Handler IMPORT __main IMPORT SystemInit
[单片机]
<font color='red'>STM32</font>的启动过程分析
STM32 ST-LINK Utility解决错误提示
硬件及环境: 1.操作系统:win7旗舰版 2.stm32f030开发板 3.ST-LINK V2下载器 4.15cm长度杜邦线4根 硬件连接方式 1.stm32f030开发板通过SWD下载口连接到ST-LINK V2,连线是VCC3.3 SWCLK GND SWDIO四线 2.ST-LINK V2直接连接到电脑USB口 问题现象及解决过程: 1.首先安装keil5.11开发环境,ST-LINK Utility以及ST-LINK V2的驱动。说明:ST-LINK V2的驱动中未包含ST-LINK Utility,需要自行下载 2.在keil5.11中能够找到ST-LINK,说明ST-LINIK V2的驱动没有问题。
[单片机]
<font color='red'>STM32</font> ST-LINK Utility解决错误提示
STM32 IO 口操作
STM32 IO 口操作STM32 的0x2000_0000 到 0x200F_FFFF 单元的SRAM 被定义成 Bit Band Region,共1MB字节,与之相对应的是 0x2200_0000 到 0x23FF_FFFF单元32MB。 (一) 开启时钟 在初始化IO的时候,首先要初始化IO的时钟。 APB1ENR APB2ENR 两个从字面上看都是 Advanced Periphery Bus Enable,不同之处一个是1 ,一个是2。区别在哪里?IO初始化的应该根据需要开启哪个时钟总线? APB1外设时钟使能寄存器(RCC_APB1ENR) 低速APB使能,最大允许频率36MHz APB2外设时钟使能寄存
[单片机]
STM32F030C8T6 STM32F030R8T6 STM32F030 STOP低功耗模式配置 11uA
1、进入睡眠的关键语句 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); 2、进入低功耗需要的配置,GPIO配置原则:不回路,不悬空输入。下面是将所有IO输出为0 //输出 GPIOA- MODER = 0x55555555; GPIOB- MODER = 0x55555555; GPIOC- MODER = 0x55555555; GPIOD- MODER = 0x55555555; GPIOF- MODER = 0x55555555;
[单片机]
STM32F030C8T6 STM32F030R8T6 STM32F030 STOP低功耗模式配置 11uA
STM32定时器自学笔记
看STM32定时器一个多星期,真是乱啊。各种模式的说。这也主要是我们对定时器的各种模式的应用不是很了解。而我们对定时器的基础部分则是上手很快。就是定时器定时完成后的更新事件中断。捕获,比较这些还说得过去,再后来的从模式、触发、霍尔传感器和编码器等直接就乱了,更不用说高级定时器中的刹车、死区、互补等。 而我看定时器则是看了通用定时器,主要是刹车,编码器等这些对于我来说应用得少,即使哪天用到了也忘了。看了通用定时器不少于4次。总算能够理理清楚了。以下慢慢说。 通用定时器有以下一些模式: 计数模式(向上计数,向下计数,中央对齐计数) 捕获比较模式: (捕获)1、输入捕获模式 2、PWM输入模式 (比较)1、强制输出模式 2、比较输出模式
[单片机]
<font color='red'>STM32</font>定时器自学笔记
基于WiFi的网络授时时钟(带实时天气更新)STM32程序设计
本方案采用的是MCU+AT指令的形式开发,MCU是大家比较熟悉的意法半导体公司STM32F103C8T6,WiFi模块使用的是安信可ESP-12F,本方案是一个Demo设计,比较简单,仅实现了功能,算是一个抛砖引玉吧! 先上视频演示: https://v.youku.com/v_show/id_XN ... m=a2hzp.8244740.0.0 WiFi模块资料链接:wiki点ai-thinker点com/esp8266 STM32F103C8芯片资料链接: https://www.stmicroelectronics.c ... 103c8.html#overview 硬件部分,由时钟电路+WiFi模块+MCU最小系统+O
[单片机]
基于WiFi的网络授时时钟(带实时天气更新)<font color='red'>STM32</font>程序设计
STM32L中的系统时间——硬件RTC的使用
鼓捣了将近一天。。。因为之前用过STM32F103芯片,而这次是 STM32L151 ,这个L系列和F系列的RTC使用方式不同。废话少说,上代码: RTC初始化: //硬件RTC时钟初始化 void RTC_Configuration() { /* Allow access to the RTC */ PWR_RTCAccessCmd(ENABLE); /* Reset RTC Backup Domain */ RCC_RTCResetCmd(ENABLE); RCC_RTCResetCmd(DISABLE); /* LSE Enable */ RCC_LSECo
[单片机]
STM32 FSMC操作SRAM的步骤简析
本次操作的SRAM的型号是IS62WV51216,是高速,8M位静态SRAM。它采用ISSI(Intergrated Silicon Solution, Inc)公司的高性能CMOS技术,按照512K个字(16)位进行组织存储单元。其具有高性能、低功耗特点。为方便用户扩展SRAM的存储空间,为用户有提供了两个片选引脚;此外,含有两个字节控制信号UB和LB,可方便用户按字节访问SRAM或按字访问SRAM。IS62WV51216具有45ns/55ns访问速度,因为是全静态操作,因此无需外部时钟和刷新要求。 IS62WV51216功能框图 IS62WV51216有地址译码器、数据IO、控制逻辑和存储阵列四部分构成。地址译码器将1
[单片机]
<font color='red'>STM32</font> FSMC操作SRAM的步骤简析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved