1、介绍
体系复位后,对后备存放器和RTC的拜访被制止,这是为了避免对后备区域(BKP)的意外写操作。履行以下操作将使能对后备存放器和RTC的拜访:
l设置存放器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟(调用:RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE));
l设置存放器PWR_CR的DBP位,使能对后备存放器和RTC的拜访(调用:PWR_BackupAccessCmd(ENABLE))。
2、RTC留意事项
lRTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV存放器仅能经过备份域复位信号复位;体系复位或电源复位不会影响他们的值;
lRTC供给APB1接口通ABP1读取RTC存放器的值,但有必要等候RTC_CRL存放器中的RSF(同步标志位)位被硬件置“1”之后进行;
lRTC的装备必需在前一次写操作完毕(判别RTC_CR存放器中的RTOFF是否为1,为1表明更新完结),并设置RTC_CRL存放器中的CNF位,使RTC进入装备形式后,才干写入RTC_PRL、RTC_CNT、RTC_ALR存放器,铲除CNF标志位时,写操作才实践有用(阐明RTC是动态装备的,便是在RTC运转起来之后再进行装备);
lRTC中的任何标志位都将坚持挂起状况(由于OWF、ALRF、SECF和RSF只能由硬件置位由软件清零),直到恰当的RTC_CR恳求位被软件复位,表明一切恳求的中止现已被承受;
l若ALRF=1且ALRIE=1,则答应发生RTC大局中止,假如EXTI操控器中答应发生EXTI线17中止,则答应发生RTC大局中止和RTC闹钟中止,在这种情况下,一般设置闹铃中止优先级高于大局中止,假如大局中止优先级高于闹铃中止,则在大局中止中有必要铲除闹钟中止标志之后,才干进入闹钟中止处理函数进一步处理(由于不铲除标志,则会一向引发中止,而大局中止优先级高,就会一向在大局中止中无法跳出来);
l若ALRF=1,假如在EXTI操控器中设置了EXTI线17的中止形式,则答应发生RTC闹钟中止;假如在EXTI操控器中设置了EXTI线17的事情形式,则这条线上会发生一个脉冲(不会发生RTC闹钟中止);
l当APB1时钟不运转时,OWF、ALRF、SECF和RSF位不被更新;
l体系复位时制止一切中止,无挂起中止恳求,能够对RTC存放器进行写操作;
l对RTC的写操作有必要运用如下进程之一与RTC秒标志同步:
运用RTC闹钟中止,并在中止处理程序中修正RTC闹钟和/或RTC计数器;
等候RTC操控存放器中秒标志SECF置位,再更改RTC闹钟和/或RTC计数器。
图1简化的RTC框图(详见手册)
3、RTC存放器描绘
lRTC操控存放器高位RTC_CRH/低位RTC_CRL
lRTC预分频装载存放器(RTC_PRLH/RTC_PRLL)
lRTC预分频器余数存放器(RTC_DIVH/RTC_DIVL)
lRTC计数器存放器(RTC_CNTH/RTC_CNTL)
lRTC闹钟存放器(RTC_ALRH/RTC_ALRL)
与RTC相关的存放器有:
lAPB1外设时钟使能存放器RCC_APB1ENR的PWREN和BKPEN,使能电源和后备时钟
l电源操控存放器PWR_CR的后备区域维护位:DBP
4、RTC装备流程
?装备RCC:挑选体系时钟、装备总线时钟、使能外围设备时钟等;
?调用RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE)函数,使能电源和备份域时钟;
?调用PWR_BackupAccessCmd(ENABLE)获取后备区域拜访权限;
?调用BKP_DeInit()函数将外设BKP的悉数存放器重设为缺省值;
?装备并挑选RTC时钟:调用RCC_RTCCLKConfig(RCC_RTCCLKSource_XXX)挑选是LSE、HSE的128分频或许LSI;
?RTC装备:
n调用RCC_RTCCLKCmd(ENABLE)使能RTC时钟;
n调用RTC_WaitForSynchro()等候RTC存放器(RTC_CNT、RTC_ALR和RTC_PRL)与RTC的APB时钟同步(等候RTOFF方位1);
n调用RTC_WaitForLastTask()函数等候最近一次对RTC存放器的写操作完结;
n调用RTC装备函数(如RTC_SetPrescaler(40000))装备RTC(阐明:对RTC的操控存放器是能够直接读写的;对RTC_PRL、RTC_CNT、RTC_ALR的写操作需求进入装备形式,而读他们则只需求等候同步完结(RSF置1)经过APB1接口读取);
n每次调用RTC装备函数之后需求调用RTC_WaitForLastTask()等候本次装备成功。
?EXTI装备:若需求将RTC于EXTI线17相连,则装备EXTI线17为中止/事情形式;
?NVIC装备:若要发生中止,则装备中止向量操控器,使能EXTI15_10_IRQHandler中止,或许使能RTC_IRQHandler中止;
?编写中止处理函数:留意必定要在中止处理函数中调用RTC_ClearITPendingBit()函数铲除对应的中止标志位;
5、RTC装备实例
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM,0x00);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x00);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel =RTCAlarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*设置闹钟中止优先级高于大局中止*/
NVIC_InitStructure.NVIC_IRQChannel =RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSICmd(ENABLE);
while(RESET == RCC_GetFlagStatus(RCC_FLAG_LSIRDY))
{
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_ALR,ENABLE);
RTC_ITConfig(RTC_IT_SEC,ENABLE);
RTC_SetPrescaler(6000);
RTC_WaitForLastTask();
RTC_SetAlarm(29);
RTC_WaitForLastTask();
BKP_TamperPinCmd(DISABLE);
BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);
}
void EXTI_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/*中止处理函数*/
void RTC_IRQHandler(void)
{
if(SET == RTC_GetITStatus(RTC_IT_SEC))
{
RTC_ClearITPendingBit(RTC_IT_SEC);
GPIO_WriteBit(GPIOB,GPIO_Pin_13,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_13)));
}
}
void RTCAlarm_IRQHandler(void)
{
if(SET == RTC_GetFlagStatus(RTC_IT_ALR))
{
RTC_ClearFlag(RTC_IT_ALR); /*铲除中止标志位,包含外部中止线标志*/
if(EXTI_GetITStatus(EXTI_Line17));
{
EXTI_ClearITPendingBit(EXTI_Line17);
GPIO_WriteBit(GPIOB,GPIO_Pin_8,(BitAction)(0));
}
}
}