/*************************************************************
Function : Calendar_RTC_Init
Description: RTC初始化
Input : none
return : none
*************************************************************/
static void Calendar_RTC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);//允许访问BKP数据
BKP_DeInit(); /复位BPK
RCC_LSEConfig(RCC_LSE_ON); //打开LSE低速时钟
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);//等待LSE稳定
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择LSE作为RTC的时钟源
RCC_RTCCLKCmd(ENABLE); /打开RTC时钟
RTC_WaitForSynchro(); //等待RTC寄存器同步
RTC_WaitForLastTask(); //等待最后一个写操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE);//打开RTC中断
RTC_WaitForLastTask(); //等待最后写操作完成
RTC_SetPrescaler(32767);//设置于分频,周期 period = RTCCLK/RTC_PR = (32.768kHz)/(32767 + 1) = 1s
RTC_WaitForLastTask();//等待最后的写操作完成
}
/*************************************************************
Function : Calendar_Time_Regulate
Description: 校准RTC时间
Input : none
return : none
*************************************************************/
static u32 Calendar_Time_Regulate(void)
{
u32 Tmp_HH = 0xff, Tmp_MM = 0xff, Tmp_SS = 0xff;
PRINTF("==================Time Settings================\r\n");
PRINTF("Please set hours:");
while(Tmp_HH == 0xff)
{
Tmp_HH = Calendar_Adjust_Scanf(23);//输入小时数
}
PRINTF("%d\r\n", Tmp_HH);
PRINTF("Please set minites:");
while(Tmp_MM == 0xff)
{
Tmp_MM = Calendar_Adjust_Scanf(59);//输入分钟数
}
PRINTF("%d\r\n", Tmp_MM);
PRINTF("Please set seconds:");
while(Tmp_SS == 0xff)
{
Tmp_SS = Calendar_Adjust_Scanf(59);//输入秒数
}
PRINTF("%d\r\n", Tmp_SS);
return (Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS);//返回秒数
}
/*************************************************************
Function : Calendar_Adjust_Scanf
Description: 输入要设计的时间
Input : none
return : none
*************************************************************/
static u8 Calendar_Adjust_Scanf(u32 value)
{
u32 index = 0;
u32 tmp[2] = {0, 0};
while(index < 2)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);//等待直到,串口接收到数据
tmp[index++] = USART_ReceiveData(USART1);//存输入的数据
if((tmp[index - 1] < '0') || (tmp[index - 1] > '9'))//输入有效数字0~9
{
PRINTF("Please enter valid number between 0~9\r\n");
index--;
}
}
index = (tmp[0] - '0')*10 + (tmp[1] - '0');//将字符转换成数字
if(index > value)//数字要小于value
{
PRINTF("Please enter valid number between 0 ~%d\r\n", value);
return 0xff;
}
return index;//返回设置值
}
/*************************************************************
Function : Calendar_Time_Adjust
Description: 设置当前时间:时、分、秒
Input : none
return : none
*************************************************************/
static void Calendar_Time_Adjust(void)
{
RTC_WaitForLastTask(); //等待操作完成
RTC_SetCounter(Calendar_Time_Regulate());//修改当前时间
RTC_WaitForLastTask(); //等待操作完成
}
/*************************************************************
Function : Calendar_Int_Config
Description: 设置RTC中断配置
Input : none
return : none
*************************************************************/
static void Calendar_Int_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //设置RTC中断
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*************************************************************
Function : Calendar_init
Description: 日历初始化
Input : none
return : none
*************************************************************/
void Calendar_init(void)
{
Calendar_Int_Config();//配置RTC秒中断
if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)//查看BKP,判断RTC是否配置
{
PRINTF("RTC not yet configured!\r\n");
Calendar_RTC_Init();//RTC初始化
PRINTF("RTC configured!\r\n");
Calendar_Time_Adjust();//通过串口设置时间
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
}
else
{
if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)//上电复位标志
{
PRINTF("Power on reset!\r\n");
}
else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)//引脚复位标志
{
PRINTF("External reset occured!\r\n");
}
PRINTF("No need to configure RTC\r\n");
RTC_WaitForSynchro(); //等待RTC寄存器同步
RTC_ITConfig(RTC_IT_SEC, ENABLE);//打开秒中断
RTC_WaitForLastTask(); //等待对吼一个寄存器操作完成
}
RCC_ClearFlag();//清除复位标志
}
/*************************************************************
Function : Calendar_Time_Display
Description: 显示当前时间
Input : none
return : none
*************************************************************/
void Calendar_Time_Display(void)
{
u32 THH = 0, TMM = 0, TSS = 0;
u32 timeValue = 0;
timeValue = RTC_GetCounter();
if(timeValue == 0x0001517F) //0x0001515F对应的时间是23:59:59
{
RTC_SetCounter(0x0);//RTC时钟定时时间清零
RTC_WaitForLastTask();//等待操作完成
}
THH = timeValue / 3600;//计算小时
TMM = (timeValue % 3600) / 60;//计算分钟
TSS = (timeValue % 3600) % 60;//计算秒
PRINTF("Time: %0.2d:%0.2d:%0.2d\r\n", THH, TMM, TSS);//输出当前时间
}
#ifndef __CALENDAR_H__
#define __CALENDAR_H__
#include "stm32f10x.h"
void Calendar_init(void);
void Calendar_Time_Display(void);
#endif
/*************************************************************
Function : RTC_IRQHandler
Description: RTC秒中断
Input : none
return : none
*************************************************************/
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_SEC); //清除秒中断标志
LED1_Toggle(); //翻转LED灯
RTC_WaitForLastTask(); //等待RTC操作完成
}
}
/*************************************************************
Function : main
Description: main入口
Input : none
return : none
*************************************************************/
int main(void)
{
BSP_Init();
PRINTF("\nmain() is running!\r\n");
Calendar_init();
while(1)
{
Calendar_Time_Display();
Delay_ms(1000);
}
}
上一篇:STM32 备份寄存器操作
下一篇:STM32 串口DMA发送
推荐阅读最新更新时间:2024-03-16 15:14