豆皮 - STM32开发板基础教程(十) - RTC初探(原创) 版权所有 STMFANS 原创,转载请保留出处
|
STM32的RTC实际是一个独立的定时器。 下面将介绍如何使用RTC。 我们将头一次牵扯到振源的问题。 首先介绍一下STM32使用的各种振源。 有三种 HSE: 外置晶振 HSI: 内置RC振荡 LSE: 外置RTC振荡(32768居多) APB1 和 APB2 是经过PLL以后的振荡源。 STM32启动,首先使用的HSI振荡,在确认HSE振荡可用的情况下,才可以转而使用HSE, 当HSE出现问题,STM32可自动切换回HSI振荡,维持工作。 LSE振荡则是专门供RTC使用。 LSE晶振需要特别注意。 STM32非常奇怪,要求使用 6p负载的晶振, 市面买到的时钟晶振,绝大多是是12.5pF的 算是一个不小的bug, 大家做相关开发的时候,要留神。 要买6pF的晶振,配10pF的谐振电容。 由此,马七怀念一下AVR单片机。不用谐振电容都跑的飞,当然是Mega系列。 下面介绍RTC驱动过程。 第一件事情,喂时钟。 RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR, ENABLE); 注意,喂的是什么?不是RTC,是电源管理和BKP备份器的时钟。用于备份模式下。 即系统掉电了,BKP和RTC还能继续工作,RTC继续计时。 那么RTC的时钟呢?前面提到,RTC的时钟,一般用LSE。 第二件事情,初始化RTC // RTC config void RTC_configuration() { //Open the BKP PWR_BackupAccessCmd(ENABLE); BKP_DeInit(); //RTC use the LSE Clock RCC_LSEConfig(RCC_LSE_ON); //RCC打开了LSE时钟 //Wait LSE Ready while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET); //等待LSE就绪,一般来说,如果谐振不对,就会死在这里。实 际代码请慎重 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //RTC使用时钟,可以使用LSE,也可以使用HSI,也可以使用HSE/128 RCC_RTCCLKCmd(ENABLE); //RTC的时钟开启 RTC_WaitForSynchro(); //RTC等待同步, RTC_WaitForLastTask(); //这个代码在RTC中常常出现,类似于等待就绪的含义 // Interrupt Each Second RTC_ITConfig(RTC_IT_SEC, ENABLE); //RTC开中断,RTC中断有三种,秒中断,闹钟中断,溢出中断,很明显他们的作用。秒中断用于即时操作,闹钟中断用于关闭或者唤醒,溢出中断的话,用于复位RTC RTC_WaitForLastTask();// RTC_SetPrescaler(32767); //RTC预分频,32768HZ,分为一秒一个振荡,RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) RTC_WaitForLastTask(); //等待同步 } 这样,RTC就启动了。 通过 RTC_GetCounter() 这个函数。读到计数器的值。 既然 一秒增一个。 很容易就可以从 计数器的值,算出确切的时间值。 对于这种时间分量复杂的,我习惯用结构体定义 typedef struct { unsigned char Sec; unsigned char Min; unsigned char Hour; unsigned char Day; unsigned char Month; unsigned char Year; }Time_Struct; // translate seconds to YY::MM:D::HH::MM::SS Time_Struct read_RTC_time() { unsigned long Time_Value; Time_Struct TimeStruct; Time_Value = RTC_GetCounter(); TimeStruct.Year = Time_Value/(12*30*24*3600); TimeStruct.Month = Time_Value/(30*24*3600) - TimeStruct.Year*12; TimeStruct.Day = Time_Value/(24*3600) - TimeStruct.Year*12*30 - TimeStruct.Month*30; TimeStruct.Hour = Time_Value/3600 - TimeStruct.Year*12*30*24 - TimeStruct.Month*30*24 - TimeStruct.Day*24; TimeStruct.Min = Time_Value/60 - TimeStruct.Year*12*30*24*60 - TimeStruct.Month*30*24*60 - TimeStruct.Day*24*60 - TimeStruct.Hour*60; TimeStruct.Sec = Time_Value - TimeStruct.Year*12*30*24*60*60 - TimeStruct.Month*30*24*60*60 - TimeStruct.Day*24*60*60 - TimeStruct.Hour*60*60 -TimeStruct.Min*60; return TimeStruct; } 当然,也可以在任意时候设置这个时间,手工修改Counter即可。相关函数在工程文件rtc.c当中。 |
STM32开发板基础教程(十) - RTC初探(转帖)
最新推荐文章于 2022-05-22 17:26:32 发布