您的位置 首页 软件

STM32 RTC时钟源LSE

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

一开始,一切试验都是在神舟板上去完结,根本就没有发现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. voidRTC_Configuration(void)
  2. {
  3. u8i=0;
  4. /*EnablePWRandBKPclocks*/
  5. /*PWR时钟(电源操控)与BKP时钟(RTC后备存放器)使能*/
  6. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
  7. /*AllowaccesstoBKPDomain*/
  8. /*使能RTC和后备存放器拜访*/
  9. PWR_BackupAccessCmd(ENABLE);
  10. /*ResetBackupDomain*/
  11. /*将外设BKP的悉数存放器重设为缺省值*/
  12. BKP_DeInit();
  13. /*EnableLSE*/
  14. /*使能LSE(外部32.768KHz低速晶振)*/
  15. RCC_LSEConfig(RCC_LSE_ON);
  16. /*WaittillLSEisready*/
  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. /*SelectLSEasRTCClockSource*/
  36. /*运用外部32.768KHz晶振作为RTC时钟*/
  37. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  38. }
  39. /*EnableRTCClock*/
  40. /*使能RTC的时钟供应*/
  41. RCC_RTCCLKCmd(ENABLE);
  42. /*WaitforRTCregisterssynchronization*/
  43. /*等候RTC存放器同步*/
  44. RTC_WaitForSynchro();
  45. /*WaituntillastwriteoperationonRTCregistershasfinished*/
  46. /*等候上一次对RTC存放器的写操作完结*/
  47. RTC_WaitForLastTask();
  48. /*EnabletheRTCSecond*/
  49. /*使能RTC的秒中止*/
  50. RTC_ITConfig(RTC_IT_SEC,ENABLE);
  51. /*WaituntillastwriteoperationonRTCregistershasfinished*/
  52. /*等候上一次对RTC存放器的写操作完结*/
  53. RTC_WaitForLastTask();
  54. /*SetRTCprescaler:setRTCperiodto1sec*/
  55. /*32.768KHz晶振预分频值是32767,假如对精度要求很高可以修正此分频值来校准晶振*/
  56. if(i!=10)//LSE不能正常
  57. RTC_SetPrescaler(32767);/*RTCperiod=RTCCLK/RTC_PR=(32.768KHz)/(32767+1)*/
  58. else
  59. RTC_SetPrescaler(195312);//25000000/128=195312.5,假如是8M/128=62500,则这儿应该填为62499
  60. /*WaituntillastwriteoperationonRTCregistershasfinished*/
  61. /*等候上一次对RTC存放器的写操作完结*/
  62. RTC_WaitForLastTask();
  63. }
  64. voidInit_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. /*Backupdataregistervalueisnotcorrectornotyetprogrammed(when
  75. thefirsttimetheprogramisexecuted)*/
  76. /*RTCConfiguration*/
  77. RTC_Configuration();
  78. /*Adjusttimebyvaluesentredbytheuseronthehyperterminal*/
  79. RTC_SetCounter(Time_Regulate(YEAR_BASE,01,01,0,0,0));//2008-1-10:0:0
  80. /*修正后备存放器1的值为0XA5A5*/
  81. BKP_WriteBackupRegister(BKP_DR1,RTC_SEQ_ID);
  82. }else
  83. {
  84. /*CheckifthePowerOnResetflagisset*/
  85. //RCC_GetFlagStatus(RCC_FLAG_PORRST)!=RESET
  86. //printf(“\r\n\nPowerOnResetoccurred….”);
  87. /*CheckifthePinResetflagisset*/
  88. //elseif(RCC_GetFlagStatus(RCC_FLAG_PINRST)!=RESET)
  89. //printf(“\r\n\nExternalResetoccurred….”);
  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\nNoneedtoconfigureRTC….”);
  99. /*WaitforRTCregisterssynchronization*/
  100. RTC_WaitForSynchro();
  101. /*EnabletheRTCSecond*/
  102. RTC_ITConfig(RTC_IT_SEC,ENABLE);
  103. /*WaituntillastwriteoperationonRTCregistershasfinished*/
  104. RTC_WaitForLastTask();
  105. }
  106. #ifdefRTCClockOutput_Enable
  107. /*EnablePWRandBKPclocks*/
  108. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
  109. /*AllowaccesstoBKPDomain*/
  110. PWR_BackupAccessCmd(ENABLE);
  111. /*DisabletheTamperPin*/
  112. BKP_TamperPinCmd(DISABLE);/*TooutputRTCCLK/64onTamperpin,thetamper
  113. functionalitymustbedisabled*/
  114. /*EnableRTCClockOutputonTamperPin*/
  115. BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
  116. #endif
  117. /*Clearresetflags*/
  118. RCC_ClearFlag();
  119. }

实践测验,RTC作用还行,然后合作上位机隔必定的时刻后同步时刻基本上可以满足要求。

万恶的LSE晶振,这东西几乎不能忍耐……

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/ruanjian/268401.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部