RTC是工業領域實時控制離不開的一個外設,相當于一個獨立的定時器,STM32的RTC外設由一組連續計數的計數器組成,具體來說,由兩個部分組成:第一部分指APB1接口用來和APB1總線相連,此單元還包含一組1位寄存器,可通過APB1總線對其進行讀寫操作,APB1接口由APB1總線時鐘驅動,用來與APB1總線相連;另一部分由一組可編程計數器組成,主要分為兩個模塊:第一個模塊為RTC的預分頻模塊,它可編程產生最長為1s的RTC時間基準TR_CLK,RTC的預分頻模塊包含了一個20位的可編程分頻器(RTC預分頻器),如果在RTC_CR寄存器中設置了相應的允許位,則在每個TR_CLK周期中RTC產生一個中斷,即所謂的秒中斷;第二個模塊是一個32位的可編程計數器,可被初始化為當前的系統時間。系統時間按TR_CLK周期累加并與存儲在RTC_ALR寄存器中的可編程時間相比較,如果TR_CLK控制寄存器中設置了相應允許位,比較匹配時將產生一個鬧鐘中斷,具體見下圖所示;

#include "stm32f10x_lib.h"
#include "platform_config.h"
#include
vu32 TimeDisplay = 0;
u32 hour = 0, minute = 0, second = 0;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void RTC_Configuration(void);
void NVIC_Configuration(void);
void Time_Adjust(void);
void Time_Display(u32 TimeVar);
void Time_Regulate(u32 Tmp_HH,u32 Tmp_MM,u32 Tmp_SS);
int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
RTC_Configuration();
if (BKP_ReadBackupRegister(BKP_DR1) !=0xA5A5)
{
Time_Adjust();
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
}
else
{
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
}
Time_Regulate(12,45,30);
while (1)
{
if(TimeDisplay == 1)
{
Time_Display(RTC_GetCounter());
TimeDisplay = 0;
}
}
}
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08)
{}
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC , ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel =RTC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIO_LED,&GPIO_InitStructure);
}
void RTC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR |RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) ==RESET)
{}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
}
void Time_Adjust(void)
{
RTC_WaitForLastTask();
RTC_SetCounter(0);
RTC_WaitForLastTask();
}
void Time_Regulate(u32 Tmp_HH,u32 Tmp_MM,u32 Tmp_SS)
{
u32 RTC_Counter;
RTC_Counter = Tmp_HH*3600 + Tmp_MM*60 +Tmp_SS;
RTC_WaitForLastTask();
RTC_SetCounter(RTC_Counter);
RTC_WaitForLastTask();
}
void Time_Display(u32 TimeVar)
{
hour = TimeVar / 3600;
minute = (TimeVar % 3600) / 60;
second = (TimeVar % 3600) % 60;
}
|