RTC概述
简介
RTC (Real Time Clock):实时时钟
STM32 的 RTC 外设,实质是一个掉电后还继续运行的定时器。RTC是个独立的BCD定时器/计数器。提供一个日历时钟,两个可编程闹钟中断,以及一个具有中断功能的周期性可编程唤醒标志。RTC还包含用于管理低功耗模式的自动唤醒单元。
两个32位寄存器包含二进码十进制格式(BCD)的秒,分钟,小时(12或24小时制),星期几,日期,月份和年份。此外,还可以提供二进制的亚秒值。系统可以自动将月份的天数补偿为28,29(闰年),30,31天。并且还可以进行夏令时补偿。
主要特性
包含亚秒、秒、分钟、小时(12/24 小时制)、星期几、日期、月份和年份的日历。
软件可编程的夏令时补偿。
两个具有中断功能的可编程闹钟。可通过任意日历字段的组合驱动闹钟。
自动唤醒单元,可周期性地生成标志以触发自动唤醒中断。
参考时钟检测:可使用更加精确的第二时钟源(50 Hz 或 60 Hz)来提高日历的精确度。
利用亚秒级移位特性与外部时钟实现精确同步。
可屏蔽中断/事件:
— 闹钟 A
— 闹钟 B
— 唤醒中断
— 时间戳
— 入侵检测
数字校准电路(周期性计数器调整)
— 精度为 5 ppm
— 精度为 0.95 ppm,在数秒钟的校准窗口中获得
用于事件保存的时间戳功能(1 个事件)
入侵检测:
— 2 个带可配置过滤器和内部上拉的入侵事件
20 个备份寄存器(80 字节)。发生入侵检测事件时,将复位备份寄存器。
复用功能输出 (RTC_OUT),可选择以下两个输出之一:
RTC_CALIB:512 Hz 或 1 Hz 时钟输出(LSE 频率为 32.768 kHz)。
可通过将 RTC_CR 寄存器中的 COE[23] 位置 1 来使能此输出。该输出可连接到器件 RTC_AF1 功能。
RTC_ALARM(闹钟 A、闹钟 B 或唤醒)。
可通过配置 RTC_CR 寄存器的 OSEL[1:0] 位选择此输出。该输出可连接到器件
RTC_AF1 功能。
RTC 复用功能输入:
RTC_TS:时间戳事件检测。该输入可连接到器件 RTC_AF1 和 RTC_AF2 功能。
RTC_TAMP1:TAMPER1 事件检测。该输入可连接到器件 RTC_AF1 和RTC_AF2功能。
RTC_TAMP2:TAMPER2 事件检测。
RTC_REFIN:参考时钟输入(通常为市电,50 Hz 或 60 Hz)。
RTC相关库函数
RTC时钟源和时钟操作函数:
void RCC_RTCCLKConfig(uint32_t CLKSource);//时钟源选择
void RCC_RTCCLKCmd(FunctionalState NewState)//时钟使能
RTC初始化函数
ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct);
typedef struct
{
uint32_t RTC_HourFormat; //小时格式:24/12
uint32_t RTC_AsynchPrediv; //异步分频 系数
uint32_t RTC_SynchPrediv; //同步分频系数
}RTC_InitTypeDef
RTC日历配置相关函数
//设置时间
ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);
//获取时间
void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);
//设置日期
ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);
//获取日期
void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);
//获取到亚秒的信息
uint32_t RTC_GetSubSecond(void);
RTC闹钟相关函数
//禁止或使能RTC闹钟。
ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState);
//RTC闹钟时间配置。
void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct);
//获取RTC闹钟的时间配置
void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct);
//功能配置RTC AlarmA/B的亚秒
void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask);
//得到RTC的亚秒时间。
uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm);
RTC周期唤醒相关函数
//配置RTC唤醒时钟源
void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock);
//配置RTC唤醒计数
void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter);
//得到唤醒定时器的计数值
uint32_t RTC_GetWakeUpCounter(void);
//关闭WAKE UP
RTC_WakeUpCmd(DISABLE);
RTC 中断配置以及状态相关函数
//使能或禁止RTC中断
void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState);
//查询RTC标志,主要用于非中断函数
FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG);
//清除RTC标志,主要用于非中断函数
void RTC_ClearFlag(uint32_t RTC_FLAG);
//查询RTC中断标志
ITStatus RTC_GetITStatus(uint32_t RTC_IT);
//清除RTC中断标志
void RTC_ClearITPendingBit(uint32_t RTC_IT);
RTC相关约束函数
//取消写保护
void RTC_WriteProtectionCmd(FunctionalState NewState);
//进入配置模式,RTC_ISR_INITF位设置为1
ErrorStatus RTC_EnterInitMode(void);
//退出初始化模式。
void RTC_ExitInitMode(void)
其他相关函数
//从备份数据寄存器读出数据。
uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR);
//写数据到RTC备份数据寄存器
void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data);
//使能或禁止RTC中断
void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState);
RTC日历配置步骤
使能PWR时钟:RCC_APB1PeriphClockCmd();
使能后备寄存器访问: PWR_BackupAccessCmd();
配置RTC时钟源,使能RTC时钟:
RCC_RTCCLKConfig();
RCC_RTCCLKCmd();
如果使用LSE,要打开LSE:RCC_LSEConfig(RCC_LSE_ON);
初始化RTC(同步/异步分频系数和时钟格式):RTC_Init ();
设置时间:RTC_SetTime ();1
设置日期:RTC_SetDate();2
#define RTC_BKP_VALE 0x2021
void Rtc_Init(void)
{
RTC_InitTypeDef RTC_InitStruct;
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;
//1、使能PWR时钟:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
//2、使能后备寄存器访问: 这类寄存器是掉电保存数据的
PWR_BackupAccessCmd(ENABLE);
if(RTC_ReadBackupRegister(RTC_BKP_DR0) != RTC_BKP_VALE)
{
//3、配置RTC时钟源,使能RTC时钟:
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
//要打开LSE:
RCC_LSEConfig(RCC_LSE_ON);
delay_ms(50); //延时等待时钟稳定
RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24; //时间格式
RTC_InitStruct.RTC_AsynchPrediv = 0x7F; //异步分频器
RTC_InitStruct.RTC_SynchPrediv = 0xFF; //同步分频器
//4、 初始化RTC(同步/异步分频系数和时钟格式):
RTC_Init(&RTC_InitStruct);
RTC_TimeStruct.RTC_H12 = RTC_H12_PM; //对于24小时格式,这个参数可以不用
RTC_TimeStruct.RTC_Hours = 16; //时
RTC_TimeStruct.RTC_Minutes = 36; //分
RTC_TimeStruct.RTC_Seconds = 00; //秒
//5、 设置时间:
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
RTC_DateStruct.RTC_Year = 20; //20年,前年20要自己补
RTC_DateStruct.RTC_Month = 8; //月
RTC_DateStruct.RTC_Date = 19; //日
RTC_DateStruct.RTC_WeekDay = 3; //星期
//6、设置日期:
RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct);
//写后备寄存器
RTC_WriteBackupRegister(RTC_BKP_DR0, RTC_BKP_VALE);
}
}
RTC闹钟配置步骤
所有 RTC 中断均与 EXTI 控制器相连。
要使能 RTC 闹钟中断,需按照以下顺序操作:
将 EXTI 线 17 配置为中断模式并将其使能,然后选择上升沿有效。
配置 NVIC 中的 RTC_Alarm IRQ 通道并将其使能。
配置 RTC 以生成 RTC 闹钟(闹钟 A 或闹钟 B)。
①:RTC已经初始化好相关参数。
②:关闭闹钟:RTC_AlarmCmd(RTC_Alarm_A,DISABLE);
③:配置闹钟参数:RTC_SetAlarm();3
④:开启闹钟:RTC_AlarmCmd(RTC_Alarm_A,EABLE);
⑤:开启配置闹钟中断:
RTC_ITConfig();
EXTI_Init();
NVIC_Init();
⑥:编写中断服务函数:RTC_Alarm_IRQHandler();
//闹钟A
void RTC_Alarm_AInit(void)
{
RTC_TimeTypeDef RTC_AlarmTime;
RTC_AlarmTypeDef RTC_AlarmStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//2、关闭闹钟:
RTC_AlarmCmd(RTC_Alarm_A,DISABLE);
//闹钟时间设置
RTC_AlarmTime.RTC_H12 = RTC_H12_PM; //对于24小时格式,这个参数可以不用
RTC_AlarmTime.RTC_Hours = 16; //时
RTC_AlarmTime.RTC_Minutes = 36; //分
RTC_AlarmTime.RTC_Seconds = 30; //秒
RTC_AlarmStruct.RTC_AlarmTime = RTC_AlarmTime; //时间设置
RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_None; //无掩码位 按实际时间来响应闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_WeekDay; //按星期来闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDay = RTC_Weekday_Wednesday; //星期3
//3、配置闹钟参数:
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStruct);
//4、开启闹钟:
RTC_AlarmCmd(RTC_Alarm_A,ENABLE);
//5、开启配置闹钟中断:
RTC_ITConfig(RTC_IT_ALRA,ENABLE);
EXTI_InitStruct.EXTI_Line = EXTI_Line17; //中断线17
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = RTC_Alarm_IRQn; //NVIC通道,在stm32f4xx.h可查看通道 (可变)
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
void RTC_Alarm_IRQHandler(void)
{
//判断中断标志是否为1
if(EXTI_GetITStatus(EXTI_Line17) == SET)
{
//判断是否为闹钟A
if(RTC_GetFlagStatus(RTC_FLAG_ALRAF) == SET)
{
//闹钟响应事件
PFout(9) = 0;
RTC_ClearFlag(RTC_FLAG_ALRAF);
}
//清空标志位
EXTI_ClearITPendingBit(EXTI_Line17);
}
}
//闹钟B
void RTC_Alarm_BInit(void)
{
RTC_TimeTypeDef RTC_AlarmTime;
RTC_AlarmTypeDef RTC_AlarmStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//2、关闭闹钟:
RTC_AlarmCmd(RTC_Alarm_B,DISABLE);
//闹钟时间设置
RTC_AlarmTime.RTC_H12 = RTC_H12_PM; //对于24小时格式,这个参数可以不用
RTC_AlarmTime.RTC_Hours = 16; //时
RTC_AlarmTime.RTC_Minutes = 36; //分
RTC_AlarmTime.RTC_Seconds = 35; //秒
RTC_AlarmStruct.RTC_AlarmTime = RTC_AlarmTime; //时间设置
RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_None; //无掩码位 按实际时间来响应闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; //按日期来闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDay = 19; //19日
//3、配置闹钟参数:
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_B, &RTC_AlarmStruct);
//4、开启闹钟:
RTC_AlarmCmd(RTC_Alarm_B,ENABLE);
//5、开启配置闹钟中断:
RTC_ITConfig(RTC_IT_ALRB,ENABLE);
EXTI_InitStruct.EXTI_Line = EXTI_Line17; //中断线17
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = RTC_Alarm_IRQn; //NVIC通道,在stm32f4xx.h可查看通道 (可变)
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
RTC概述
简介
RTC (Real Time Clock):实时时钟
STM32 的 RTC 外设,实质是一个掉电后还继续运行的定时器。RTC是个独立的BCD定时器/计数器。提供一个日历时钟,两个可编程闹钟中断,以及一个具有中断功能的周期性可编程唤醒标志。RTC还包含用于管理低功耗模式的自动唤醒单元。
两个32位寄存器包含二进码十进制格式(BCD)的秒,分钟,小时(12或24小时制),星期几,日期,月份和年份。此外,还可以提供二进制的亚秒值。系统可以自动将月份的天数补偿为28,29(闰年),30,31天。并且还可以进行夏令时补偿。
主要特性
包含亚秒、秒、分钟、小时(12/24 小时制)、星期几、日期、月份和年份的日历。
软件可编程的夏令时补偿。
两个具有中断功能的可编程闹钟。可通过任意日历字段的组合驱动闹钟。
自动唤醒单元,可周期性地生成标志以触发自动唤醒中断。
参考时钟检测:可使用更加精确的第二时钟源(50 Hz 或 60 Hz)来提高日历的精确度。
利用亚秒级移位特性与外部时钟实现精确同步。
可屏蔽中断/事件:
— 闹钟 A
— 闹钟 B
— 唤醒中断
— 时间戳
— 入侵检测
数字校准电路(周期性计数器调整)
— 精度为 5 ppm
— 精度为 0.95 ppm,在数秒钟的校准窗口中获得
用于事件保存的时间戳功能(1 个事件)
入侵检测:
— 2 个带可配置过滤器和内部上拉的入侵事件
20 个备份寄存器(80 字节)。发生入侵检测事件时,将复位备份寄存器。
复用功能输出 (RTC_OUT),可选择以下两个输出之一:
RTC_CALIB:512 Hz 或 1 Hz 时钟输出(LSE 频率为 32.768 kHz)。
可通过将 RTC_CR 寄存器中的 COE[23] 位置 1 来使能此输出。该输出可连接到器件 RTC_AF1 功能。
RTC_ALARM(闹钟 A、闹钟 B 或唤醒)。
可通过配置 RTC_CR 寄存器的 OSEL[1:0] 位选择此输出。该输出可连接到器件
RTC_AF1 功能。
RTC 复用功能输入:
RTC_TS:时间戳事件检测。该输入可连接到器件 RTC_AF1 和 RTC_AF2 功能。
RTC_TAMP1:TAMPER1 事件检测。该输入可连接到器件 RTC_AF1 和RTC_AF2功能。
RTC_TAMP2:TAMPER2 事件检测。
RTC_REFIN:参考时钟输入(通常为市电,50 Hz 或 60 Hz)。
RTC相关库函数
RTC时钟源和时钟操作函数:
void RCC_RTCCLKConfig(uint32_t CLKSource);//时钟源选择
void RCC_RTCCLKCmd(FunctionalState NewState)//时钟使能
RTC初始化函数
ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct);
typedef struct
{
uint32_t RTC_HourFormat; //小时格式:24/12
uint32_t RTC_AsynchPrediv; //异步分频 系数
uint32_t RTC_SynchPrediv; //同步分频系数
}RTC_InitTypeDef
RTC日历配置相关函数
//设置时间
ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);
//获取时间
void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);
//设置日期
ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);
//获取日期
void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);
//获取到亚秒的信息
uint32_t RTC_GetSubSecond(void);
RTC闹钟相关函数
//禁止或使能RTC闹钟。
ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState);
//RTC闹钟时间配置。
void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct);
//获取RTC闹钟的时间配置
void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct);
//功能配置RTC AlarmA/B的亚秒
void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask);
//得到RTC的亚秒时间。
uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm);
RTC周期唤醒相关函数
//配置RTC唤醒时钟源
void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock);
//配置RTC唤醒计数
void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter);
//得到唤醒定时器的计数值
uint32_t RTC_GetWakeUpCounter(void);
//关闭WAKE UP
RTC_WakeUpCmd(DISABLE);
RTC 中断配置以及状态相关函数
//使能或禁止RTC中断
void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState);
//查询RTC标志,主要用于非中断函数
FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG);
//清除RTC标志,主要用于非中断函数
void RTC_ClearFlag(uint32_t RTC_FLAG);
//查询RTC中断标志
ITStatus RTC_GetITStatus(uint32_t RTC_IT);
//清除RTC中断标志
void RTC_ClearITPendingBit(uint32_t RTC_IT);
RTC相关约束函数
//取消写保护
void RTC_WriteProtectionCmd(FunctionalState NewState);
//进入配置模式,RTC_ISR_INITF位设置为1
ErrorStatus RTC_EnterInitMode(void);
//退出初始化模式。
void RTC_ExitInitMode(void)
其他相关函数
//从备份数据寄存器读出数据。
uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR);
//写数据到RTC备份数据寄存器
void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data);
//使能或禁止RTC中断
void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState);
RTC日历配置步骤
使能PWR时钟:RCC_APB1PeriphClockCmd();
使能后备寄存器访问: PWR_BackupAccessCmd();
配置RTC时钟源,使能RTC时钟:
RCC_RTCCLKConfig();
RCC_RTCCLKCmd();
如果使用LSE,要打开LSE:RCC_LSEConfig(RCC_LSE_ON);
初始化RTC(同步/异步分频系数和时钟格式):RTC_Init ();
设置时间:RTC_SetTime ();1
设置日期:RTC_SetDate();2
#define RTC_BKP_VALE 0x2021
void Rtc_Init(void)
{
RTC_InitTypeDef RTC_InitStruct;
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;
//1、使能PWR时钟:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
//2、使能后备寄存器访问: 这类寄存器是掉电保存数据的
PWR_BackupAccessCmd(ENABLE);
if(RTC_ReadBackupRegister(RTC_BKP_DR0) != RTC_BKP_VALE)
{
//3、配置RTC时钟源,使能RTC时钟:
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
//要打开LSE:
RCC_LSEConfig(RCC_LSE_ON);
delay_ms(50); //延时等待时钟稳定
RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24; //时间格式
RTC_InitStruct.RTC_AsynchPrediv = 0x7F; //异步分频器
RTC_InitStruct.RTC_SynchPrediv = 0xFF; //同步分频器
//4、 初始化RTC(同步/异步分频系数和时钟格式):
RTC_Init(&RTC_InitStruct);
RTC_TimeStruct.RTC_H12 = RTC_H12_PM; //对于24小时格式,这个参数可以不用
RTC_TimeStruct.RTC_Hours = 16; //时
RTC_TimeStruct.RTC_Minutes = 36; //分
RTC_TimeStruct.RTC_Seconds = 00; //秒
//5、 设置时间:
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
RTC_DateStruct.RTC_Year = 20; //20年,前年20要自己补
RTC_DateStruct.RTC_Month = 8; //月
RTC_DateStruct.RTC_Date = 19; //日
RTC_DateStruct.RTC_WeekDay = 3; //星期
//6、设置日期:
RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct);
//写后备寄存器
RTC_WriteBackupRegister(RTC_BKP_DR0, RTC_BKP_VALE);
}
}
RTC闹钟配置步骤
所有 RTC 中断均与 EXTI 控制器相连。
要使能 RTC 闹钟中断,需按照以下顺序操作:
将 EXTI 线 17 配置为中断模式并将其使能,然后选择上升沿有效。
配置 NVIC 中的 RTC_Alarm IRQ 通道并将其使能。
配置 RTC 以生成 RTC 闹钟(闹钟 A 或闹钟 B)。
①:RTC已经初始化好相关参数。
②:关闭闹钟:RTC_AlarmCmd(RTC_Alarm_A,DISABLE);
③:配置闹钟参数:RTC_SetAlarm();3
④:开启闹钟:RTC_AlarmCmd(RTC_Alarm_A,EABLE);
⑤:开启配置闹钟中断:
RTC_ITConfig();
EXTI_Init();
NVIC_Init();
⑥:编写中断服务函数:RTC_Alarm_IRQHandler();
//闹钟A
void RTC_Alarm_AInit(void)
{
RTC_TimeTypeDef RTC_AlarmTime;
RTC_AlarmTypeDef RTC_AlarmStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//2、关闭闹钟:
RTC_AlarmCmd(RTC_Alarm_A,DISABLE);
//闹钟时间设置
RTC_AlarmTime.RTC_H12 = RTC_H12_PM; //对于24小时格式,这个参数可以不用
RTC_AlarmTime.RTC_Hours = 16; //时
RTC_AlarmTime.RTC_Minutes = 36; //分
RTC_AlarmTime.RTC_Seconds = 30; //秒
RTC_AlarmStruct.RTC_AlarmTime = RTC_AlarmTime; //时间设置
RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_None; //无掩码位 按实际时间来响应闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_WeekDay; //按星期来闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDay = RTC_Weekday_Wednesday; //星期3
//3、配置闹钟参数:
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStruct);
//4、开启闹钟:
RTC_AlarmCmd(RTC_Alarm_A,ENABLE);
//5、开启配置闹钟中断:
RTC_ITConfig(RTC_IT_ALRA,ENABLE);
EXTI_InitStruct.EXTI_Line = EXTI_Line17; //中断线17
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = RTC_Alarm_IRQn; //NVIC通道,在stm32f4xx.h可查看通道 (可变)
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
void RTC_Alarm_IRQHandler(void)
{
//判断中断标志是否为1
if(EXTI_GetITStatus(EXTI_Line17) == SET)
{
//判断是否为闹钟A
if(RTC_GetFlagStatus(RTC_FLAG_ALRAF) == SET)
{
//闹钟响应事件
PFout(9) = 0;
RTC_ClearFlag(RTC_FLAG_ALRAF);
}
//清空标志位
EXTI_ClearITPendingBit(EXTI_Line17);
}
}
//闹钟B
void RTC_Alarm_BInit(void)
{
RTC_TimeTypeDef RTC_AlarmTime;
RTC_AlarmTypeDef RTC_AlarmStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//2、关闭闹钟:
RTC_AlarmCmd(RTC_Alarm_B,DISABLE);
//闹钟时间设置
RTC_AlarmTime.RTC_H12 = RTC_H12_PM; //对于24小时格式,这个参数可以不用
RTC_AlarmTime.RTC_Hours = 16; //时
RTC_AlarmTime.RTC_Minutes = 36; //分
RTC_AlarmTime.RTC_Seconds = 35; //秒
RTC_AlarmStruct.RTC_AlarmTime = RTC_AlarmTime; //时间设置
RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_None; //无掩码位 按实际时间来响应闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; //按日期来闹钟
RTC_AlarmStruct.RTC_AlarmDateWeekDay = 19; //19日
//3、配置闹钟参数:
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_B, &RTC_AlarmStruct);
//4、开启闹钟:
RTC_AlarmCmd(RTC_Alarm_B,ENABLE);
//5、开启配置闹钟中断:
RTC_ITConfig(RTC_IT_ALRB,ENABLE);
EXTI_InitStruct.EXTI_Line = EXTI_Line17; //中断线17
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = RTC_Alarm_IRQn; //NVIC通道,在stm32f4xx.h可查看通道 (可变)
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
举报