完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
2个回答
|
|
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); } |
|
|
|
main.c
int main(void) { RTC_TimeTypeDef RTC_TimeStruct; RTC_DateTypeDef RTC_DateStruct; //NVIC分组(一个工程当中只能配置一次分组)抢占优先级2位,值范围:0~3;响应优先级2位,值范围:0~3; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Delay_Init(); Led_Init(); Usart1_Init(); Rtc_Init(); RTC_Alarm_AInit(); while(1) { RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct); RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct); printf(“时间:%d:%d:%drn”, RTC_TimeStruct.RTC_Hours, RTC_TimeStruct.RTC_Minutes, RTC_TimeStruct.RTC_Seconds); printf(“日期:20%d年%d月%d日,星期%drnrn”,RTC_DateStruct.RTC_Year, RTC_DateStruct.RTC_Month, RTC_DateStruct.RTC_Date, RTC_DateStruct.RTC_WeekDay); delay_s(1); } return 0; } RTC周期性自动唤醒配置一般步骤 RTC已经初始化好相关参数。 关闭WakeUp:RTC_WakeUpCmd(DISABLE); 配置WakeUp时钟分频系数/来源: RTC_WakeUpClockConfig(); 设置WakeUp自动装载寄存器:RTC_SetWakeUpCounter(); 使能WakeUp : RTC_WakeUpCmd( ENABLE); 开启配置闹钟中断: RTC_ITConfig(); EXTI_Init(); NVIC_Init(); 编写中断服务函数: RTC_WKUP_IRQHandler(); ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); 函数功能:时间设置 uint32_t RTC_Format:存储格式 RTC_Format_BIN:二进制存储 RTC_Format_BCD:BCD码格式 typedef struct { uint8_t RTC_Hours; //时 uint8_t RTC_Minutes; //分 uint8_t RTC_Seconds; //秒 uint8_t RTC_H12; //上下午 }RTC_TimeTypeDef; ↩︎ ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) 函数功能:日期设置 uint32_t RTC_Format:存储格式 RTC_Format_BIN:二进制存储 typedef struct { uint8_t RTC_WeekDay; //星期 uint8_t RTC_Month; //月 uint8_t RTC_Date; //日 uint8_t RTC_Year; //年 }RTC_DateTypeDef; ↩︎ void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); 函数功能:设置闹钟 uint32_t RTC_Format:存储格式 RTC_Format_BIN:二进制存储 RTC_Format_BCD:BCD码格式 uint32_t RTC_Alarm:选择哪个闹钟 typedef struct { RTC_TimeTypeDef RTC_AlarmTime; //时间设置结构体 uint32_t RTC_AlarmMask; //掩码位 uint32_t RTC_AlarmDateWeekDaySel; //选择闹钟响应方式(日期,星期) uint8_t RTC_AlarmDateWeekDay; //日期或者星期的设置 }RTC_AlarmTypeDef; typedef struct { uint8_t RTC_Hours; //时 uint8_t RTC_Minutes; //分 uint8_t RTC_Seconds; //秒 uint8_t RTC_H12; //上下午 }RTC_TimeTypeDef; ↩︎ |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 10:43 , Processed in 0.858313 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号