STM32之RTC时钟,闹钟,日历

您所在的位置:网站首页 怎样设定定时器闹钟时间和日期 STM32之RTC时钟,闹钟,日历

STM32之RTC时钟,闹钟,日历

2024-07-14 02:15| 来源: 网络整理| 查看: 265

RTC时钟的一些功能介绍

RTC时钟即实时时钟,它提供了用于管理所有低功耗模式的自动唤醒单元,还提供了具有可编程闹钟中断功能的日历时钟/日历。

并且可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。并且还可以进行夏令时补偿。

中断屏蔽事件:有两个闹钟,时间戳,入侵检测,唤醒中断。

硬件上需要注意的部分

若要使用rtc功能,并且能够掉电继续工作,那么要外接纽扣电池或其他电池电源。

这里参考的是STM32F767芯片及正点的底板的设计原理图

(用BAT54C做多电源供电电路,当单片机上电时,使用VCC3.3供电,当单片机掉电时,VBAT会自动切换到BAT供电。)

在这里插入图片描述

RTC框图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OUajQLmX-1649826743461)(C:\Users\15894\AppData\Roaming\Typora\typora-user-images\image-20220413105031857.png)]

RTC的时钟源

​ 可以是外部低速晶振(LSE),外部高速晶振(HSE),内部低速晶振(LSI)。我们一般选用外部低速晶振(32.768kHz)作为时钟源。

RTC时钟走向

​ 先经过RTC校准寄存器(RTC_CALR)对RTC时钟进行校准;然后进入预分频寄存器(RTC_PRER)进行预分频,有两类:异步预分频(7位,默认128)、同步预分频(15位,默认256);时钟另外一个走向是预分频寄存器(WUCKSEL)这个是作为RTC唤醒定时器的时钟源。

3个影子寄存器 时间寄存器(RTC_TR):用来初始化配置日历时间日期寄存器(RTC_DR):用来初始化配置日历日期亚秒寄存器(RTC_SSR):用来进一步精确时间变化 控制寄存器(RTC_CR)

用于配置RTC的功能。

RTC时钟初始化配置 RTC_HandleTypeDef RTC_Handler; //RTC句柄 //配置RTC底层驱动和时钟 void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) { //配置RCC的时钟 RCC_OscInitTypeDef RCC_OscInitStruct; //配置RCC扩展外设时钟 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; __HAL_RCC_PWR_CLK_ENABLE(); //使能电源时钟PWR HAL_PWR_EnableBkUpAccess(); //取消备份区域写保护 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; //LSE配置 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; //不启用RCC分频 RCC_OscInitStruct.LSEState = RCC_LSE_ON; //RTC使用LSE HAL_RCC_OscConfig(&RCC_OscInitStruct); //将配置好的参数写入结构体 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; //外设为RTC PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; //RTC时钟源为LSE HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); //将配置好的参数写入结构体 __HAL_RCC_RTC_ENABLE();//RTC时钟使能 } //RTC初始化参数配置 u8 RTC_Init(void) { RTC_Handler.Instance=RTC; RTC_Handler.Init.HourFormat=RTC_HOURFORMAT_24; //RTC设置为24小时格式 RTC_Handler.Init.AsynchPrediv=0X7F; //RTC异步分频系数(1~0X7F) RTC_Handler.Init.SynchPrediv=0XFF; //RTC同步分频系数(0~7FFF) RTC_Handler.Init.OutPut=RTC_OUTPUT_DISABLE; //不用外部输出 RTC_Handler.Init.OutPutPolarity=RTC_OUTPUT_POLARITY_HIGH; RTC_Handler.Init.OutPutType=RTC_OUTPUT_TYPE_OPENDRAIN; //执行初始化并检查初始化是否成功 if(HAL_RTC_Init(&RTC_Handler)!=HAL_OK) return 2; //用备份域的寄存器DR0来标记配置标志 if(HAL_RTCEx_BKUPRead(&RTC_Handler,RTC_BKP_DR0) != 0X5050)//是否第一次配置 { RTC_Set_Time(23,59,56,RTC_HOURFORMAT12_PM); //设置时间 RTC_Set_Date(15,12,27,7); //设置日期 HAL_RTCEx_BKUPWrite(&RTC_Handler,RTC_BKP_DR0,0X5050); //标记已经初始化过了 } return 0; }

RTC设置时间和日期

//RTC时间设置 HAL_StatusTypeDef RTC_Set_Time(u8 hour,u8 min,u8 sec,u8 ampm) { RTC_TimeTypeDef RTC_TimeStructure; RTC_TimeStructure.Hours=hour; RTC_TimeStructure.Minutes=min; RTC_TimeStructure.Seconds=sec; RTC_TimeStructure.TimeFormat=ampm; //配置12小时或24小时格式 RTC_TimeStructure.DayLightSaving=RTC_DAYLIGHTSAVING_NONE; RTC_TimeStructure.StoreOperation=RTC_STOREOPERATION_RESET; return HAL_RTC_SetTime(&RTC_Handler,&RTC_TimeStructure,RTC_FORMAT_BIN); } //RTC日期设置 HAL_StatusTypeDef RTC_Set_Date(u8 year,u8 month,u8 date,u8 week) { RTC_DateTypeDef RTC_DateStructure; RTC_DateStructure.Date=date; RTC_DateStructure.Month=month; RTC_DateStructure.WeekDay=week; RTC_DateStructure.Year=year; return HAL_RTC_SetDate(&RTC_Handler,&RTC_DateStructure,RTC_FORMAT_BIN); } RTC配置闹钟

配置RTC周期性唤醒定时器

void RTC_Set_WakeUp(u32 wksel,u16 cnt) { __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RTC_Handler, RTC_FLAG_WUTF);//清除RTC WAKE UP的标志 HAL_RTCEx_SetWakeUpTimer_IT(&RTC_Handler,cnt,wksel); //设置重装载值和时钟 HAL_NVIC_SetPriority(RTC_WKUP_IRQn,0x02,0x02); //抢占优先级1,子优先级2 HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn); } //RTC WAKE UP中断服务函数 void RTC_WKUP_IRQHandler(void) { HAL_RTCEx_WakeUpTimerIRQHandler(&RTC_Handler); } //RTC WAKE UP中断处理 void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) { //........... }

配置闹钟

void RTC_Set_AlarmA(u8 week,u8 hour,u8 min,u8 sec) { RTC_AlarmTypeDef RTC_AlarmSturuct; RTC_AlarmSturuct.AlarmTime.Hours=hour; //小时 RTC_AlarmSturuct.AlarmTime.Minutes=min; //分钟 RTC_AlarmSturuct.AlarmTime.Seconds=sec; //秒 RTC_AlarmSturuct.AlarmTime.SubSeconds=0; RTC_AlarmSturuct.AlarmTime.TimeFormat=RTC_HOURFORMAT12_AM; RTC_AlarmSturuct.AlarmMask=RTC_ALARMMASK_NONE; //精确匹配星期,时分秒 RTC_AlarmSturuct.AlarmSubSecondMask=RTC_ALARMSUBSECONDMASK_NONE; RTC_AlarmSturuct.AlarmDateWeekDaySel=RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;//按星期 RTC_AlarmSturuct.AlarmDateWeekDay=week; //星期 RTC_AlarmSturuct.Alarm=RTC_ALARM_A; //闹钟A HAL_RTC_SetAlarm_IT(&RTC_Handler,&RTC_AlarmSturuct,RTC_FORMAT_BIN); HAL_NVIC_SetPriority(RTC_Alarm_IRQn,0x01,0x02); //抢占优先级1,子优先级2 HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn); } 将数据显示在LCD上 //获取时间:时分秒 HAL_RTC_GetTime(&RTC_Handler,&RTC_TimeStruct,RTC_FORMAT_BIN); sprintf((char*)tbuf,"Time:%02d:%02d:%02d",RTC_TimeStruct.Hours,RTC_TimeStruct.Minutes,RTC_TimeStruct.Seconds); LCD_ShowString(30,140,210,16,16,tbuf); //获取日期:年月日,周 HAL_RTC_GetDate(&RTC_Handler,&RTC_DateStruct,RTC_FORMAT_BIN); sprintf((char*)tbuf,"Date:20%02d-%02d-%02d",RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Date); LCD_ShowString(30,160,210,16,16,tbuf); sprintf((char*)tbuf,"Week:%d",RTC_DateStruct.WeekDay); LCD_ShowString(30,180,210,16,16,tbuf);


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3