void rtc_init(void)
{
RTC_DateTypeDef RTC_DateStructure;
RTC_TimeTypeDef RTC_TimeStructure;
RTC_InitTypeDef RTC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/* Enable the PWR clock ,使能电源控制时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC,允许访问备份电路 */
PWR_BackupAccessCmd(ENABLE);
#if 0
/* 使能LSE*/
RCC_LSEConfig(RCC_LSE_ON);
/* 检查该LSE是否有效*/
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
/* 选择LSE作为RTC的硬件时钟源*/
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else //若LSE无法工作,可用内部LSI
/* 使能LSI*/
RCC_LSICmd(ENABLE);
/* 检查该LSI是否有效*/
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
/* 选择LSI作为RTC的硬件时钟源*/
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
/* Enable the RTC Clock,使能RTC时钟 */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation,等待RTC相关寄存器就绪 */
RTC_WaitForSynchro();
#if 0 //LSE
/* Configure the RTC data register and RTC prescaler,配置RTC数据寄存器与RTC的分频值 */
RTC_InitStructure.RTC_AsynchPrediv = 127; //异步分频系数
RTC_InitStructure.RTC_SynchPrediv = 255; //同步分频系数
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //24小时格式
RTC_Init(&RTC_InitStructure);
#else //LSI
/* Configure the RTC data register and RTC prescaler,配置RTC数据寄存器与RTC的分频值 */
RTC_InitStructure.RTC_AsynchPrediv = 127; //异步分频系数
RTC_InitStructure.RTC_SynchPrediv = 249; //同步分频系数
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //24小时格式
RTC_Init(&RTC_InitStructure);
#endif
/* Set the date: Sunday August 1th 2021 */
RTC_DateStructure.RTC_Year = 0x21;
RTC_DateStructure.RTC_Month = RTC_Month_August;
RTC_DateStructure.RTC_Date = 0x01;
RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Sunday;
RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);
/* Set the time to 14h 59mn 55s PM */
RTC_TimeStructure.RTC_H12 = RTC_H12_PM;
RTC_TimeStructure.RTC_Hours = 0x14;
RTC_TimeStructure.RTC_Minutes = 0x59;
RTC_TimeStructure.RTC_Seconds = 0x55;
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);
//关闭唤醒功能
RTC_WakeUpCmd(DISABLE);
//为唤醒功能选择RTC配置好的时钟源
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
//设置唤醒计数值为自动重载,写入值默认是0
RTC_SetWakeUpCounter(1-1);
//清除RTC唤醒中断标志
RTC_ClearITPendingBit(RTC_IT_WUT);
//使能RTC唤醒中断
RTC_ITConfig(RTC_IT_WUT, ENABLE);
//使能唤醒功能
RTC_WakeUpCmd(ENABLE);
/* Configure EXTI Line22,配置外部中断控制线22 */
EXTI_InitStructure.EXTI_Line = EXTI_Line22; //当前使用外部中断控制线22
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能外部中断控制线22
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn; //允许RTC唤醒中断触发
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; //抢占优先级为0x3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //响应优先级为0x3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
}
主函数代码
//做个标志位不然速度会太快
static volatile uint32_t g_rtc_wakeup_event=0;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
Led_init();
key_init();
/* 初始化串口1波特率为115200bps,若发送/接收数据有乱码,请检查PLL */
usart1_init(9600);
rtc_init();
printf("this is rtc test\r\n");
while(1)
{
//检测RTC唤醒中断是否触发
if(g_rtc_wakeup_event)
{
//获取时间
RTC_GetTime(RTC_Format_BCD,&RTC_TimeStructure);
printf("Time %02X:%02X:%02X\r\n",RTC_TimeStructure.RTC_Hours,RTC_TimeStructure.RTC_Minutes,RTC_TimeStructure.RTC_Seconds);
//获取日期
RTC_GetDate(RTC_Format_BCD,&RTC_DateStructure);
printf("Date 20%02X-%02X-%02X Week:%X\r\n",RTC_DateStructure.RTC_Year,RTC_DateStructure.RTC_Month,RTC_DateStructure.RTC_Date,RTC_DateStructure.RTC_WeekDay);
g_rtc_wakeup_event=0;
}
}
}
void RTC_WKUP_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_WUT) == SET)
{
printf("RTC_WKUP_IRQHandler\r\n");
g_rtc_wakeup_event=1;
RTC_ClearITPendingBit(RTC_IT_WUT);
EXTI_ClearITPendingBit(EXTI_Line22);
}
}
锁定时间不然复位键重置时间
static volatile uint32_t g_rtc_wakeup_event=0;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
led_init();
key_init();
/* 初始化串口1波特率为115200bps,若发送/接收数据有乱码,请检查PLL */
usart1_init(115200);
/* 若开机读取备份寄存器的值不等于0x1688,则进行rtc日期和时间的重置 */
if(RTC_ReadBackupRegister(RTC_BKP_DR0)!=0x1688)
{
rtc_init();
/* 对备份寄存器0写入数据0x1688,用于标记已经初始化过 */
RTC_WriteBackupRegister(RTC_BKP_DR0,0x1688);
}
else
{
/* Enable the PWR clock ,使能电源控制时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC,允许访问备份电路 */
PWR_BackupAccessCmd(ENABLE);
#if 0
/* 使能LSE*/
RCC_LSEConfig(RCC_LSE_ON);
/* 检查该LSE是否有效*/
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
/* 选择LSE作为RTC的硬件时钟源*/
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else //若LSE无法工作,可用内部LSI
/* 使能LSI*/
RCC_LSICmd(ENABLE);
/* 检查该LSI是否有效*/
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
/* 选择LSI作为RTC的硬件时钟源*/
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
/* Enable the RTC Clock,使能RTC时钟 */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation,等待RTC相关寄存器就绪 */
RTC_WaitForSynchro();
#if 0 //LSE
/* Configure the RTC data register and RTC prescaler,配置RTC数据寄存器与RTC的分频值 */
RTC_InitStructure.RTC_AsynchPrediv = 127; //异步分频系数
RTC_InitStructure.RTC_SynchPrediv = 255; //同步分频系数
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //24小时格式
RTC_Init(&RTC_InitStructure);
#else //LSI
/* Configure the RTC data register and RTC prescaler,配置RTC数据寄存器与RTC的分频值 */
RTC_InitStructure.RTC_AsynchPrediv = 127; //异步分频系数
RTC_InitStructure.RTC_SynchPrediv = 249; //同步分频系数
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //24小时格式
RTC_Init(&RTC_InitStructure);
#endif
//关闭唤醒功能
RTC_WakeUpCmd(DISABLE);
//为唤醒功能选择RTC配置好的时钟源
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
//设置唤醒计数值为自动重载,写入值默认是0
RTC_SetWakeUpCounter(1-1);
//清除RTC唤醒中断标志
RTC_ClearITPendingBit(RTC_IT_WUT);
//使能RTC唤醒中断
RTC_ITConfig(RTC_IT_WUT, ENABLE);
//使能唤醒功能
RTC_WakeUpCmd(ENABLE);
/* Configure EXTI Line22,配置外部中断控制线22 */
EXTI_InitStructure.EXTI_Line = EXTI_Line22; //当前使用外部中断控制线22
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能外部中断控制线22
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn; //允许RTC唤醒中断触发
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; //抢占优先级为0x3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //响应优先级为0x3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
}
printf("this is rtc test\r\n");
while(1)
{
//检测RTC唤醒中断是否触发
if(g_rtc_wakeup_event)
{
//获取时间
RTC_GetTime(RTC_Format_BCD,&RTC_TimeStructure);
printf("Time %02X:%02X:%02X\r\n",RTC_TimeStructure.RTC_Hours,RTC_TimeStructure.RTC_Minutes,RTC_TimeStructure.RTC_Seconds);
//获取日期
RTC_GetDate(RTC_Format_BCD,&RTC_DateStructure);
printf("Date 20%02X-%02X-%02X Week:%X\r\n",RTC_DateStructure.RTC_Year,RTC_DateStructure.RTC_Month,RTC_DateStructure.RTC_Date,RTC_DateStructure.RTC_WeekDay);
g_rtc_wakeup_event=0;
}
}
}