一开始,所有实验都是在神舟板上去完成,根本就没有发现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的正常。下次需要上位机重新去设置时间。

代码大致如下:

  1. void RTC_Configuration(void)

  2. {

  3. u8 i = 0;

  4. /* Enable PWR and BKP clocks */

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

  6. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  7. /* Allow access to BKP Domain */

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

  9. PWR_BackupAccessCmd(ENABLE);

  10. /* Reset Backup Domain */

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

  12. BKP_DeInit();

  13. /* Enable LSE */

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

  15. RCC_LSEConfig(RCC_LSE_ON);

  16. /* Wait till LSE is ready */

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

  18. TIM5_Init_Query(CALC_TYPE_MS); //ms 级别

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

  20. {

  21. if (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != RESET)

  22. break;

  23. TIM5_MS_CALC(1); //1ms延时

  24. }

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

  26. if (i == 10)

  27. {

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

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

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

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

  32. RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);

  33. }else

  34. {

  35. /* Select LSE as RTC Clock Source */

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

  37. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  38. }

  39. /* Enable RTC Clock */

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

  41. RCC_RTCCLKCmd(ENABLE);

  42. /* Wait for RTC registers synchronization */

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

  44. RTC_WaitForSynchro();

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

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

  47. RTC_WaitForLastTask();

  48. /* Enable the RTC Second */

  49. /* 使能RTC的秒中断 */

  50. RTC_ITConfig(RTC_IT_SEC, ENABLE);

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

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

  53. RTC_WaitForLastTask();

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

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

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

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

  58. else

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

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

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

  62. RTC_WaitForLastTask();

  63. }

  64. void Init_RTC(void)

  65. {

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

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

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

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

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

  71. */

  72. if (BKP_ReadBackupRegister(BKP_DR1) != RTC_SEQ_ID)

  73. {

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

  75. the first time the program is executed) */

  76. /* RTC Configuration */

  77. RTC_Configuration();

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

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

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

  81. BKP_WriteBackupRegister(BKP_DR1, RTC_SEQ_ID);

  82. }else

  83. {

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

  85. //RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET

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

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

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

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

  90. if (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)

  91. {

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

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

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

  95. //RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);

  96. RTC_Configuration();

  97. }

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

  99. /* Wait for RTC registers synchronization */

  100. RTC_WaitForSynchro();

  101. /* Enable the RTC Second */

  102. RTC_ITConfig(RTC_IT_SEC, ENABLE);

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

  104. RTC_WaitForLastTask();

  105. }

  106. #ifdef RTCClockOutput_Enable

  107. /* Enable PWR and BKP clocks */

  108. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  109. /* Allow access to BKP Domain */

  110. PWR_BackupAccessCmd(ENABLE);

  111. /* Disable the Tamper Pin */

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

  113. functionality must be disabled */

  114. /* Enable RTC Clock Output on Tamper Pin */

  115. BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);

  116. #endif

  117. /* Clear reset flags */

  118. RCC_ClearFlag();

  119. }

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

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

纠结的STM32 RTC时钟源LSE相关推荐

  1. STM32 RTC时钟源LSE

    一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题.直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题. 这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻 ...

  2. 什么是RCT实时时钟?(STM32中RTC时钟源)

    什么是RCT(Real Time Clock,实时时钟)? 一.RTC时钟简介 RTC(Real Time Clock,实时时钟)是指安装在电子设备或实现其功能的IC(集成电路)上的时钟,一般会是集成 ...

  3. STM32 RTC时钟读取时间

    文章目录 一.RTC简介 1.1 RTC 1.2 RTC特征 1.3 RTC原理框图 1.4 RTC工作流程 1.5 RTC时钟选择 1.6 RTC复位过程 1.7 RTC中断 二.CubeMX配置 ...

  4. STM32 RTC时钟掉电日期不更新 STM32 HAL库RTC时钟配置

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 STM32 RTC时钟掉电日期不更新 & STM32 HAL库RTC时钟配置 一.STM32CubeMX RTC配置 二.RT ...

  5. stm32 RTC时钟配置

    stm32--RTC实时时钟 一.关于时间 2038年问题 在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作.所有使用UNIX时间表示时间的程序都将将受其影响,因为它们以自19 ...

  6. STM32 RTC时钟掉电日期不更新

    RTC(Real-Time Clock)实时时钟,是一个独立的定时器.拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能.修改计数器的值可以重新设置系统当前的时间和日期. RTC 模块和 ...

  7. 认识STM32的时钟源和晶振

    STM32 五个时钟源,为HSI.HSE.LSI.LSE.PLL 如何识别? 1.HSI是高速内部时钟,RC振荡器   2.HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源 3.LSI是低 ...

  8. 关于STM32 RTC时钟使用内部/外部晶振的切换方法

    对于使用STM32单片开发项目的同志,经常会使用到STM32的RTC功能,而在配置RTC的功能时需要配置晶振的使用,可以使用内部晶振或外部晶振,配置流程参考官方的示例代码即可. 但在之前的项目中遇到一 ...

  9. (22)STM32——RTC时钟笔记(基于正点原子探索者)

    目录 学习目标 运行结果 内容 介绍 配置 寄存器 配置过程 日历 闹钟 自动唤醒 代码 总结 学习目标 今天我们要介绍的有关PTC时钟的相关知识,其中包括了RTC日历.RTC时钟和RTC周期性自动唤 ...

最新文章

  1. 基于Javaweb实现企业财务管理系统
  2. MATLAB的iptcheckinput函数详解
  3. makefile 和shell文件相互调用
  4. 深度学习模型保存_解读计算机视觉的深度学习模型
  5. spring声明式事务管理方式( 基于tx和aop名字空间的xml配置+@Transactional注解)
  6. 终于学会后空翻!历经多次NG,波士顿动力机器人再get新技能
  7. thinkpad 使用技巧
  8. PTA数组后五道演讲比赛中有10个评委打分(实型数据,十分制分数)一维数组中,然后输入欲删除数x,最后删除数组中值为x的元素并输出,键盘输入一个4×4阶的矩阵,编程输出它的转置矩阵。
  9. Java程序员月薪30K和月薪3K差别在哪?
  10. java程序设计实用教程_清华大学出版社-图书详情-《Java程序设计实用教程》
  11. 弘辽科技:怎样的淘宝店铺装修更能吸引顾客
  12. B. Shifting Sort (思维)
  13. AHU-727 美妙音乐 【DP】
  14. 关于yii2 treemanager插件中lft和rgt的说明
  15. javascript鼠标拖尾特效
  16. android 仿360浮动,Android仿360悬浮小球自定义view实现示例
  17. 腾讯云——轻量数据库服务
  18. gnome设置dvorak键盘布局
  19. abex' creak me#1
  20. .NET敏捷开发框架-RDIFramework.NET V3.6版全新发布 100%源码

热门文章

  1. 深入JVM彻底剖析前面ygc越来越慢的case
  2. 深度历险:Redis 内存模型详解
  3. 多线程:happens-before原则
  4. 【Linux - mysql】怎么修改数据库编码
  5. 2009年出现的计算机术语,2009年计算机一级考试真题及答案
  6. java 爬中 验证码识别_JAVA爬虫---验证码识别技术(一)
  7. jsonutil java_Java实现的JSONUtil工具类与用法示例
  8. 数据中心智慧机房解决方案
  9. 回顾2019年5个重大宕机事件
  10. 如何看懂发电机功率圆图