STM32F10x芯片RTC实时时钟

来源:互联网 发布:mac下载的文件在哪里找 编辑:程序博客网 时间:2024/05/06 06:52

1、介绍

       系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:

l         设置寄存器RCC_APB1ENRPWRENBKPEN位,使能电源和后备接口时钟(调用:RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE))

l         设置寄存器PWR_CRDBP位,使能对后备寄存器和RTC的访问(调用:PWR_BackupAccessCmd(ENABLE))

2RTC注意事项

l         RTC_PRLRTC_ALRRTC_CNTRTC_DIV寄存器仅能通过备份域复位信号复位;系统复位或电源复位不会影响他们的值;

l         RTC提供APB1接口通ABP1读取RTC寄存器的值,但必须等待RTC_CRL寄存器中的RSF(同步标志位)位被硬件置“1”之后进行;

l         RTC的配置必需在前一次写操作结束(判断RTC_CR寄存器中的RTOFF是否为1,为1表示更新完成),并设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRLRTC_CNTRTC_ALR寄存器,清除CNF标志位时,写操作才实际有效(说明RTC是动态配置的,即是在RTC运行起来之后再进行配置);

l         RTC中的任何标志位都将保持挂起状态(因为OWFALRFSECFRSF只能由硬件置位由软件清零),直到适当的RTC_CR请求位被软件复位,表示所有请求的中断已经被接受;

l         ALRF=1ALRIE=1,则允许产生RTC全局中断,如果EXTI控制器中允许产生EXTI线17中断,则允许产生RTC全局中断和RTC闹钟中断,在这种情况下,一般设置闹铃中断优先级高于全局中断,如果全局中断优先级高于闹铃中断,则在全局中断中必须清除闹钟中断标志之后,才能进入闹钟中断处理函数进一步处理因为不清除标志,则会一直引发中断,而全局中断优先级高,就会一直在全局中断中无法跳出来);

l         ALRF=1,如果在EXTI控制器中设置了EXTI线17的中断模式,则允许产生RTC闹钟中断;如果在EXTI控制器中设置了EXTI线17的事件模式,则这条线上会产生一个脉冲(不会产生RTC闹钟中断);

l         APB1时钟不运行时,OWFALRFSECFRSF位不被更新;

l         系统复位时禁止所有中断,无挂起中断请求,可以对RTC寄存器进行写操作;

l         RTC的写操作必须使用如下过程之一与RTC秒标志同步:

*         使用RTC闹钟中断,并在中断处理程序中修改RTC闹钟和/RTC计数器;

*         等待RTC控制寄存器中秒标志SECF置位,再更改RTC闹钟和/RTC计数器。

简化的RTC框图(详见手册)

 

3RTC寄存器描述

l         RTC控制寄存器高位RTC_CRH/低位RTC_CRL

l         RTC预分频装载寄存器(RTC_PRLH/RTC_PRLL

l         RTC预分频器余数寄存器(RTC_DIVH/RTC_DIVL

l         RTC计数器寄存器(RTC_CNTH/RTC_CNTL

l         RTC闹钟寄存器(RTC_ALRH/RTC_ALRL

RTC相关的寄存器有:

l         APB1外设时钟使能寄存器RCC_APB1ENRPWRENBKPEN,使能电源和后备时钟

l         电源控制寄存器PWR_CR的后备区域保护位:DBP

4RTC配置流程

?         配置RCC:选择系统时钟、配置总线时钟、使能外围设备时钟等;

?         调用RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE)函数,使能电源和备份域时钟;

?         调用PWR_BackupAccessCmd(ENABLE)获取后备区域访问权限;

?         调用BKP_DeInit()函数将外设BKP的全部寄存器重设为缺省值;

?         配置并选择RTC时钟:调用RCC_RTCCLKConfig(RCC_RTCCLKSource_XXX)选择是LSEHSE128分频或者LSI

?         RTC配置:

n         调用RCC_RTCCLKCmd(ENABLE)使能RTC时钟;

n         调用RTC_WaitForSynchro()等待RTC寄存器(RTC_CNTRTC_ALRRTC_PRL)与RTCAPB时钟同步(等待RTOFF位置1);

n         调用RTC_WaitForLastTask()函数等待最近一次对RTC寄存器的写操作完成;

n         调用RTC配置函数(如RTC_SetPrescaler(40000))配置RTC(说明:对RTC的控制寄存器是可以直接读写的;对RTC_PRLRTC_CNTRTC_ALR的写操作需要进入配置模式,而读他们则只需要等待同步完成(RSF1)通过APB1接口读取);

n         每次调用RTC配置函数之后需要调用RTC_WaitForLastTask()等待本次配置成功。

?         EXTI配置:若需要将RTCEXTI线17相连,则配置EXTI线17为中断/事件模式;

?         NVIC配置:若要产生中断,则配置中断向量控制器,使能EXTI15_10_IRQHandler中断,或者使能RTC_IRQHandler中断;

?         编写中断处理函数:注意一定要在中断处理函数中调用RTC_ClearITPendingBit()函数清除对应的中断标志位;

5RTC配置实例

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));

              }

       }

}

0 0
原创粉丝点击