《電子技術應用》
您所在的位置:首頁 > 嵌入式技術 > 解決方案 > 淺談STM32F10X芯片RTC實時時鐘

淺談STM32F10X芯片RTC實時時鐘

2015-11-03
關鍵詞: RTC STM32F10x

1、介紹

系統(tǒng)復位后,,對后備寄存器和RTC的訪問被禁止,,這是為了防止對后備區(qū)域(BKP)的意外寫操作。執(zhí)行以下操作將使能對后備寄存器和RTC的訪問:

l         設置寄存器RCC_APB1ENR的PWREN和BKPEN位,,使能電源和后備接口時鐘(調(diào)用:RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE)),;

l         設置寄存器PWR_CR的DBP位,使能對后備寄存器和RTC的訪問(調(diào)用:PWR_BackupAccessCmd(ENABLE)),。

2,、RTC注意事項

l         RTC_PRL、RTC_ALR,、RTC_CNT和RTC_DIV寄存器僅能通過備份域復位信號復位;系統(tǒng)復位或電源復位不會影響他們的值;

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

l         RTC的配置必需在前一次寫操作結束(判斷RTC_CR寄存器中的RTOFF是否為1,為1表示更新完成),,并設置RTC_CRL寄存器中的CNF位,,使RTC進入配置模式后,才能寫入RTC_PRL,、RTC_CNT,、RTC_ALR寄存器,清除CNF標志位時,,寫操作才實際有效(說明RTC是動態(tài)配置的,,即是在RTC運行起來之后再進行配置);

l         RTC中的任何標志位都將保持掛起狀態(tài)(因為OWF,、ALRF,、SECF和RSF只能由硬件置位由軟件清零),直到適當?shù)腞TC_CR請求位被軟件復位,,表示所有請求的中斷已經(jīng)被接受,;

l         若ALRF=1且ALRIE=1,則允許產(chǎn)生RTC全局中斷,,如果EXTI控制器中允許產(chǎn)生EXTI線17中斷,,則允許產(chǎn)生RTC全局中斷和RTC鬧鐘中斷,在這種情況下,,一般設置鬧鈴中斷優(yōu)先級高于全局中斷,,如果全局中斷優(yōu)先級高于鬧鈴中斷,則在全局中斷中必須清除鬧鐘中斷標志之后,,才能進入鬧鐘中斷處理函數(shù)進一步處理(因為不清除標志,,則會一直引發(fā)中斷,而全局中斷優(yōu)先級高,,就會一直在全局中斷中無法跳出來),;

l         若ALRF=1,如果在EXTI控制器中設置了EXTI線17的中斷模式,,則允許產(chǎn)生RTC鬧鐘中斷,;如果在EXTI控制器中設置了EXTI線17的事件模式,則這條線上會產(chǎn)生一個脈沖(不會產(chǎn)生RTC鬧鐘中斷),;

l         當APB1時鐘不運行時,,OWF、ALRF,、SECF和RSF位不被更新,;

l         系統(tǒng)復位時禁止所有中斷,無掛起中斷請求,可以對RTC寄存器進行寫操作,;

l         對RTC的寫操作必須使用如下過程之一與RTC秒標志同步:

         使用RTC鬧鐘中斷,,并在中斷處理程序中修改RTC鬧鐘和/或RTC計數(shù)器;

         等待RTC控制寄存器中秒標志SECF置位,,再更改RTC鬧鐘和/或RTC計數(shù)器,。

 

圖1 簡化的RTC框圖(詳見手冊)

 

3、RTC寄存器描述

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

l         RTC預分頻裝載寄存器(RTC_PRLH/RTC_PRLL)

l         RTC預分頻器余數(shù)寄存器(RTC_DIVH/RTC_DIVL)

l         RTC計數(shù)器寄存器(RTC_CNTH/RTC_CNTL)

l         RTC鬧鐘寄存器(RTC_ALRH/RTC_ALRL)

與RTC相關的寄存器有:

l         APB1外設時鐘使能寄存器RCC_APB1ENR的PWREN和BKPEN,,使能電源和后備時鐘

l         電源控制寄存器PWR_CR的后備區(qū)域保護位:DBP

4,、RTC配置流程

?         配置RCC:選擇系統(tǒng)時鐘、配置總線時鐘,、使能外圍設備時鐘等,;

?         調(diào)用RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE)函數(shù),使能電源和備份域時鐘,;

?         調(diào)用PWR_BackupAccessCmd(ENABLE)獲取后備區(qū)域訪問權限,;

?         調(diào)用BKP_DeInit()函數(shù)將外設BKP的全部寄存器重設為缺省值;

?         配置并選擇RTC時鐘:調(diào)用RCC_RTCCLKConfig(RCC_RTCCLKSource_XXX)選擇是 LSE,、HSE的128分頻或者LSI,;

?         RTC配置:

n         調(diào)用RCC_RTCCLKCmd(ENABLE)使能RTC時鐘;

n         調(diào)用RTC_WaitForSynchro()等待RTC寄存器(RTC_CNT,、RTC_ALR和RTC_PRL)與RTC的APB時鐘同步(等待RTOFF位置1),;

n         調(diào)用RTC_WaitForLastTask()函數(shù)等待最近一次對RTC寄存器的寫操作完成;

n         調(diào)用RTC配置函數(shù)(如RTC_SetPrescaler(40000))配置RTC(說明:對RTC的控制寄存器是可以直接讀寫的,;對RTC_PRL,、RTC_CNT、RTC_ALR的寫操作需要進入配置模式,,而讀他們則只需要等待同步完成(RSF置1)通過APB1接口讀?。?/p>

n         每次調(diào)用RTC配置函數(shù)之后需要調(diào)用RTC_WaitForLastTask()等待本次配置成功,。

?         EXTI配置:若需要將RTC于EXTI線17相連,,則配置EXTI線17為中斷/事件模式;

?         NVIC配置:若要產(chǎn)生中斷,,則配置中斷向量控制器,,使能EXTI15_10_IRQHandler中斷,或者使能RTC_IRQHandler中斷,;

?         編寫中斷處理函數(shù):注意一定要在中斷處理函數(shù)中調(diào)用RTC_ClearITPendingBit()函數(shù)清除對應的中斷標志位,;

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

/* 設置鬧鐘中斷優(yōu)先級高于全局中斷 */

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

}

/* 中斷處理函數(shù) */

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

}

}

}

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章,、圖片,、音/視頻文件等資料的版權歸版權所有權人所有,。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認版權者,。如涉及作品內(nèi)容、版權和其它問題,,請及時通過電子郵件或電話通知我們,,以便迅速采取適當措施,避免給雙方造成不必要的經(jīng)濟損失,。聯(lián)系電話:010-82306118,;郵箱:[email protected]