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