STM32之RTC时钟,闹钟,日历

article/2025/8/6 23:43:43

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个影子寄存器

  1. 时间寄存器(RTC_TR):用来初始化配置日历时间
  2. 日期寄存器(RTC_DR):用来初始化配置日历日期
  3. 亚秒寄存器(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();		//使能电源时钟PWRHAL_PWR_EnableBkUpAccess();		//取消备份区域写保护RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;	//LSE配置RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;				//不启用RCC分频RCC_OscInitStruct.LSEState = RCC_LSE_ON;                  	//RTC使用LSEHAL_RCC_OscConfig(&RCC_OscInitStruct);						//将配置好的参数写入结构体PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;	//外设为RTCPeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;	//RTC时钟源为LSEHAL_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,子优先级2HAL_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;     			//闹钟AHAL_RTC_SetAlarm_IT(&RTC_Handler,&RTC_AlarmSturuct,RTC_FORMAT_BIN);HAL_NVIC_SetPriority(RTC_Alarm_IRQn,0x01,0x02); 	//抢占优先级1,子优先级2HAL_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);

http://chatgpt.dhexx.cn/article/YDrNstoW.shtml

相关文章

深入学习RTC时钟库 DS1302

❤️博主介绍❤️ 😬 作者:单片机菜鸟哥 👉火爆博客:ESP8266 Arduino教程 零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇…

深入学习 RTC时钟库 DS3231

❤️博主介绍❤️ 😬 作者:单片机菜鸟哥 👉火爆博客:ESP8266 Arduino教程 零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇…

rtc时钟

一、设计效果 配置RTC时钟,初始化为2000年1月1日00:00:00;通过RTC时钟秒中断串口每秒打印一次当前时刻,并切换一次流水灯状态;配置闹铃为10:00:05,在闹铃中断中每秒切换一次蜂鸣器状态闹铃,直到按KEY1关闭…

RTC时钟实现实时日历

文章目录 1、RTC时钟简介1.2、初识RTC1.2、相关寄存器 2、创建项目23、完善代码4、总结 1、RTC时钟简介 1.2、初识RTC 1、简介: RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使…

STM32之RTC时钟

前言 了解实时时钟RTC的原理。STM32芯片自带RTC,因此不须像其他MCU需外接RTC模块。请编程实现STM32的日历读取、设置和输出。要求: 1)读取RTC初始时间,验证是否为 1970年1月1日零分零秒; 2)将RTC时间调整为…

【STM32】HAL库 STM32CubeMX教程十三---RTC时钟

前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6/ STM32F103ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软…

【STM32】详解RTC实时时钟的概念和配置示例代码

一、什么是RTC RTC(Real-time Clock):实时时钟,本质上是一个支持BCD编码的定时器/计数器。主电源断电后能够由电池供电,使其时钟跳转依然正常。 二、STM32F4芯片内的RTC功能 ①日历时钟(时分秒、年月日、星期) ②两个闹…

android小错误:Failure retrieving text 0x7f050001 in package

1.在启动android应用程序的过程中,logcat打印如下的错误: 报错的原因:资源的id没有找到。资源在R.java文件中,找到0x7f050001 对应的定义 R.java public static final int AppTheme0x7f050001; AppTheme这个文件在AndroidMan…

Windows7系统蓝屏-解决办法, 错误代码:0x0000007F

1.电脑突然蓝屏提示stop:0x0000007F,如下图所示: 2.故障排除 重启电脑,一直按F8,进入“安全模式”,如能正常进入系统,查看系统错误日志。针对系统记录的错误日志,解决问题。如下图,…

java.lang.IllegalArgumentException No view found for id 0x7

java.lang.IllegalArgumentException No view found for id 0x7 布局上找不到这个View,看下ERROR的地方,可以看到是因为Container找不到因此报错了。 从布局入手,参考了很多文章主要分为以下两种原因 1 Fragment 嵌套了 Fragment 例如&…

Fragment报java.lang.IllegalArgumentException:No view found for id 0x7f070250的错误

我用的是Fragment嵌套Fragment做的,放fragment切换快的时候程序就会崩溃,解决这个办法就是在View生成前先将FragemnentManger创建好,就不会报错了

Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f解析

先看日志报错这个错误纠结我两天了,真的要崩溃了~_~ 关于android.content.res.Resources$NotFoundException: Resource ID的问题,那行代码是onCreate加载.xml布局,是加载的R.layout.xxxx,不是R.id.xxxx,布局文件存在&a…

关于No view found for id 0x7f080135 (com.xxx.xxx:id/viewpager) for fragment PopupWindow

最近在开发项目中,遇到了一个问题。PopupWindow中无法嵌套viewpagerFragment,现在进行总结一下。 问题描述:在Fragment中弹出一个PopupWindow,PopupWindow中用viewpager加载多个Fragment时出现上面问题。 网上搜的都是那些什么没有设置id之…

流水灯设计

流水灯设计 目的与要求 通过采用单片机控制8个LED发光二极管顺序点亮的流水灯系统设计与制作,让读者了解C语言的数据类型、常量与变量、运算符和表达式等基本概念及使用方法。 设计要求:首先点亮连接到P1.7引脚的发光二极管,延时一定时间后…

IT管理人才必备的十大能力

公众号回复:干货,领取价值58元/套IT管理体系文档 公众号回复:ITIL教材,领取最新ITIL4中文教材 正文 作为IT技术人员,相信没有一个人愿意永远在底层编写程序或做简单的系统维护。经过一段时间的技术和经验的积累&#x…

他,连续 3 年担任新星计划导师,这次的内容有点特别

一、新星计划 新星计划是一个发掘潜力新人、培养优质博主为目标的创作活动,通过为期两周的时间,明白为什么要写博客,写作的意义是什么?制定学习计划,完善Java知识体系。 二、学习计划 创作打卡阶段第1周&#xff08…

Python 彻底甩掉 Java,位居 48 种编程语言之首!

Python 彻底甩掉 Java,位居 48 种编程语言之首! 昨日,IEEE Spectrum 杂志发布了一年一度的编程语言排行榜,这个排行榜已经连续发布了五年。对于每位开发者而言,想要衡量编程语言流行度则需要依赖相对流行的网站统计数据…

java并发问题概述

转自 https://www.jb51.net/article/131411.htm java并发问题概述 转载 更新时间:2017年12月25日 09:28:54 作者:人圭先生 我要评论 这篇文章主要介绍了java并发问题概述,具有一定借鉴价值,需要的朋友可以参考下。 1什么是…

【Java基础系列教程】第一章 编程入门

一、计算机概述 1.1 计算机简介 计算机(computer)俗称电脑,是现代一种用于高速计算的电子计算机器,可以进行数值计算,又可以进行逻辑计算,还具有存储记忆功能。是能够按照程序运行,自动、高速处…

关于程序员这14条经典定律,我全中~

定律1:最难定位的问题要么是最疑难的问题,要么是最低级的问题,这两种问题都有一个共同特征,就是让你意想不到。 举一个例子,一次代码编译不过,报函数没有定义,开始怀疑是类没有“;”结束符,然后怀疑有没有匹配的“{”,折腾了好久,最后才发现是开头的“#ifndef”定义…