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傍边。