RTC出现上电后计数值变化情况
最经的一个项目要使用F103的RTC功能,为了加快项目的进度,使用了网上现有的例程,通过简单的修改先使用着。
具体实施方法:硬件上,CR2032电池通过二极管和芯片的VBAT引脚连接,并使用104电容做退耦;软件上,使用了[软件参考]http://www.openedv.com/forum.php?mod=viewthread&tid=230238 文章中也介绍了RTC的结构原理和使用方法,重点要注意RTC的几个点:
- 开启RTC电源和时钟。
- 访问RTC寄存器的使能方法,如果不使能标志位,将无法对RTC寄存器的访问。
- 要注意一个细节,这个需要仔细阅读原版文件中的时钟同步的说明。
遇到的问题
最开始在做驱动时,直接使用了上面链接中的软件方法,基本上照抄过来,实际使用时性能都正常,通过测试。进而后来再也没有考虑过这个RTC功能的事情直接去做应用去了。但是直到程序末期在设备上实际使用时才将问题暴露出来:在对整个设备做重新上电重启时会出现偶然间的RTC计数器值变化大的情况5000到10000不等,也没有任何规律。 突然间在自己脑子中开始设想N多种原因,但是解决办法只能回去实际测试。

原因分析和实施
原因1. 现象是在整机上电时出现时间变化的情况,怀疑是不是由于电源电路出现的干扰导致32768晶振工作出现波动(增加)导致寄存器计数瞬间加快,出现的计数时间变化的情况。
根据这个原因,首先对电源电路电路做分析:由于使用的电源为DC24V电源,在PCB板上我增加了一个TD1507的dcdc,降压到5V在由LM1117-3.3降压的3.3V对整个CPU系统供电。如下图:

分析1:使用示波器测量5V和3.3V电源的纹波情况,实际得到的结果3.3V基本没有纹波为直线型电源。5V电源有100~150khz的80mv纹波。发现了5V电源出现的纹波情况后,更改使用7805芯片做降压,通过示波器观察5V已经没有纹波出现,但是依然会出现上电后RTC计时器数值变化的情况。问题并没有得到解决。
分析2:由于出现的现象为RTC计数值偏大,所以问题分析思路依然是在上电时32768晶振工作频率不稳定的原因。

由于使用的无源晶振无法使用示波器测量器输出频率,所以更换使用了有源晶振替代原原来无源晶振的办法。使用外部有源晶振(JFVNY XO14NYA 32768,一款军用的有源晶振)通过飞线和芯片管脚连接。测试时将示波器接入到波形输出管脚,实时测量有源晶振的输出波形。
结果: 问题依然存在,而且示波器显示并没有发现的波形频率变化情况。再次无解。不过这个说明了问题原因并不是由于震荡频率变化引起的。
上传芯片时钟配置程序:
主程序中对时钟的配置程序:
代码块
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
//Initializes the CPU, AHB and APB busses clocks
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
思路重新回到软件上
结合F103的资料对程序代码重新做细致分析,RTC的驱动程序是符合资料要做的操作流程。
- 分析1:芯片时钟初始化时可能出现了对RTC寄存器计数器值的影响;
-
分析2:RTC被其他初始化函数影响;
修改办法:将RTC初始化函数放置到其他驱动初始化后面。
结果:通过反复上电实验,计数器的值保持稳定。测试基本通过,再到现场后在做定论。
结论:具体没有想到是因为什么原因,或者应为那个函数对RTC寄存器造成的影响。也没有仔细做分析。希望有大神可以看到能分析出详细的原因。欢迎评论。
附上初始化函数(以便大神帮忙分析具体原因)
init1.png
init2.png
init3.png
网友评论