STM32F4X RTC

STM32F4X RTC

  • 什么是RTC
  • STM32F4X RTC
    • STM32F4X RTC框图
    • STM32F4X RTC计数频率
    • STM32F4X RTC日历
    • STM32F4X RTC闹钟
  • STM32F4X RTC例程

什么是RTC

RTC全程叫Real-Time Clock实时时钟,是MCU中一个用来计时的模块。RTC的一个主要作用是用来显示实时时间,就像日常生活中的时钟一样,RTC除了可以显示时间之外,还有闹钟功能,唤醒功能等。很多的MCU里面都会有RTC模块,当然也可以外接RTC芯片使用。

STM32F4X RTC

STM32F4X RTC框图

在这里插入图片描述

  1. RTC时钟源:RTC的时钟源有3个,分别是外部低频晶振(LSE)、内部低频晶振(LSI)和外部高频晶振(HSE)。一般来说我们都会选择32768Hz的LSE作为RTC的时钟源。
  2. RTC分频器:时钟源选择好之后,就需要对时钟源进行分频。STM32F4X的RTC分频器有两个,分别是异步分频器7位的PREDIV_A和15位的同步分频器 PREDIV_A。RTC的分频由这两个分频器共同决定。
  3. RTC闹钟:STM32F4X的RTC有两个闹钟,用户可以通过设置闹钟的触发条件,当闹钟设置的触发条件跟当前RTC的计数时间一致时就会产生一个信号,如果使能了闹钟中断,就会触发闹钟中断
  4. RTC唤醒:当系统进入低功耗模式时,可以通过RTC唤醒系统。RTC有一个唤醒预分频器,可以设置2/4/6/8分频,还有一个16位的唤醒自动重装载寄存器,用来设置唤醒时间。
  5. RTC影子寄存器:影子寄存器的作用是提供给用户读取日历使用,用户不能直接访问影子寄存器,由STM32F4X每隔两个TRCCLK周期进行复制。

STM32F4X RTC计数频率

对于RTC来说,我们需要得到一个1秒的计数频率,这样才符合日常生活的习惯。下面就以RTC的时钟源为32768Hz来计算,看如何得到1Hz的频率。
STM32F4X给出了RTC时钟频率的计算公式
在这里插入图片描述
STM32F4X的RTC分频需要PREDIV_A和PREDIV_S两个分频器共同决定。其中PREDIV_A为7位,PREDIV_S为15位。我们可以设置PREDIV_A为0x7F,PREDIV_S为0xFF。

F = 32768 / (0x7F + 1) * (0xFF + 1) = 32768 / 32768 = 1Hz
刚好可以得到1Hz的频率,这样就可以让RTC以1秒的频率进行计数。

STM32F4X RTC日历

用户可以设置RTC的日历功能,通过RTC_TR和RTC_DR寄存器可以设置日历。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

STM32F4X RTC闹钟

STM32F4X的RTC有两个闹钟,分别是ALARM A和ALARM B。可以通过RTC_ALRMAR和RTC_ALRMBR进行设置。可以设置闹钟的触发条件和触发时间。
在这里插入图片描述
在这里插入图片描述

STM32F4X RTC例程

#include "rtc.h"
#define ALARM_HOUR_MIN_SEC  1 // 闹钟匹配 时分秒
#define ALARM_HOUR_MIN      2 // 闹钟匹配 时分
#define ALARM_MIN_SEC       3 // 闹钟匹配 分秒
#define ALARM_HOUR          4 // 闹钟匹配 时
#define ALARM_MIN           5 // 闹钟匹配 分
#define ALARM_SEC           6 // 闹钟匹配 秒
ErrorStatus rtc_set_time(u8 hour,u8 min,u8 sec,u8 ampm)
{RTC_TimeTypeDef RTC_TimeStruct;RTC_TimeStruct.RTC_H12 = ampm;RTC_TimeStruct.RTC_Hours = hour; // 设置小时RTC_TimeStruct.RTC_Minutes = min; // 设置分钟RTC_TimeStruct.RTC_Seconds = sec;// 设置秒return RTC_SetTime(RTC_Format_BIN,&RTC_TimeStruct);
}
ErrorStatus rtc_set_date(u8 year,u8 mon,u8 day,u8 week)
{RTC_DateTypeDef RTC_DateStruct;RTC_DateStruct.RTC_Date = day; // 设置日RTC_DateStruct.RTC_Month = mon; // 设置月RTC_DateStruct.RTC_WeekDay = week;// 设置周RTC_DateStruct.RTC_Year = year;//设置年return RTC_SetDate(RTC_Format_BIN,&RTC_DateStruct);
}void set_alarm_time(u32 alarmx,u8 hour,u8 min,u8 sec,u8 week,u8 alarm_type)
{RTC_AlarmTypeDef RTC_AlarmStruct;RTC_TimeTypeDef RTC_AlarmTime; NVIC_InitTypeDef NVIC_InitStruct;EXTI_InitTypeDef   EXTI_InitStructure;RTC_AlarmCmd(alarmx,DISABLE); // 关闭闹钟RTC_AlarmTime.RTC_H12 = RTC_H12_AM;RTC_AlarmTime.RTC_Hours = hour; // 闹钟小时RTC_AlarmTime.RTC_Minutes = min; // 闹钟分RTC_AlarmTime.RTC_Seconds = sec;// 闹钟秒RTC_AlarmStruct.RTC_AlarmDateWeekDay = week; // 闹钟周RTC_AlarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;// 闹钟类型选择if(alarm_type == ALARM_HOUR_MIN_SEC)RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay ;else if(alarm_type == ALARM_HOUR_MIN)RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Seconds;else if(alarm_type == ALARM_MIN_SEC)RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours;else if(alarm_type == ALARM_HOUR)RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Minutes | RTC_AlarmMask_Seconds;else if(alarm_type == ALARM_MIN)RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours | RTC_AlarmMask_Seconds;else if(alarm_type == ALARM_SEC)RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes;elseRTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes;RTC_AlarmStruct.RTC_AlarmTime = RTC_AlarmTime;RTC_SetAlarm(RTC_Format_BIN,alarmx,&RTC_AlarmStruct);NVIC_InitStruct.NVIC_IRQChannel = RTC_Alarm_IRQn; // RTC 闹钟中断号NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 2;NVIC_Init(&NVIC_InitStruct);EXTI_InitStructure.EXTI_Line = EXTI_Line17;//LINE17EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE17EXTI_Init(&EXTI_InitStructure);//配置if (alarmx == RTC_Alarm_A){RTC_ClearITPendingBit(RTC_IT_ALRA);RTC_ITConfig( RTC_IT_ALRA,ENABLE);}else if(alarmx == RTC_Alarm_B){RTC_ClearITPendingBit(RTC_IT_ALRB);RTC_ITConfig( RTC_IT_ALRB,ENABLE);}RTC_AlarmCmd(alarmx,ENABLE);
}u8 bsp_rtc_init(void)
{u32 lse_rdy_count = 0xFFFF;RTC_InitTypeDef RTC_InitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR时钟PWR_BackupAccessCmd(ENABLE);	//使能后备寄存器访问 RCC_LSEConfig(RCC_LSE_ON); // 使能LSE时钟if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x525443)  // 判断是不是第一次配置{while(1){if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == SET) // 等待LSE时钟稳定break;lse_rdy_count--;delay_ms(10);if(lse_rdy_count == 0)return 1;}RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // RTC时钟源选择LSE时钟RCC_RTCCLKCmd(ENABLE);                  // RTC使能// RTC最终的计数频率 = 32768 / (0x7F + 1) * (0xFF + 1) RTC_InitStruct.RTC_AsynchPrediv = 0x7F; // 设置异步分频器RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24; // 24小时制RTC_InitStruct.RTC_SynchPrediv = 0xFF;  // 设置同步分频器RTC_Init(&RTC_InitStruct);rtc_set_time(4,7,4,RTC_H12_AM); // 设置时间 4:7:4rtc_set_date(23,9,8,5);         // 设置日期 2023-9-8 RTC_WriteBackupRegister(RTC_BKP_DR0,0x525443); // 如果是第一次就往备份寄存器写一个值}return 0;}void RTC_Alarm_IRQHandler(void)
{if(RTC_GetITStatus(RTC_IT_ALRA) == SET){printf("Alarm A\r\n");RTC_ClearITPendingBit(RTC_IT_ALRA);}if(RTC_GetITStatus(RTC_IT_ALRB) == SET){printf("Alarm B\r\n");RTC_ClearITPendingBit(RTC_IT_ALRB);}EXTI_ClearITPendingBit(EXTI_Line17);	//清除中断线17的中断标志 	
}
int main(void)
{RTC_TimeTypeDef RTC_TimeStruct;RTC_DateTypeDef RTC_DateStruct;uint32_t crc_value = 0;NVIC_PriorityGroupConfig(2);system_tick_init();bsp_usart_init(115200);bsp_rtc_init();set_alarm_time(RTC_Alarm_A,10,0,55,2,ALARM_SEC); // 设置闹钟A 按秒闹 set_alarm_time(RTC_Alarm_B,10,1,45,2,ALARM_SEC); // 设置闹钟B 按秒闹while(1){delay_ms(1000);RTC_GetTime(RTC_Format_BIN,&RTC_TimeStruct);	// 获取时间RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct); // 获取日期printf("20%02d-%02d-%02d %02d:%02d:%02d\r\n",RTC_DateStruct.RTC_Year,RTC_DateStruct.RTC_Month,RTC_DateStruct.RTC_Date,RTC_TimeStruct.RTC_Hours,RTC_TimeStruct.RTC_Minutes,RTC_TimeStruct.RTC_Seconds); }}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/125574.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用less实现多主题切换(配合天气现象)

1. 先看效果: 2. 话不多说直接撸吧: 原理:先给body元素添加style,再根据天气现象动态更改style 开撸: 创建src/assets/style/variables.less 使用 XXX:var(–XXX,‘style’) 声明系列变量,之后添加其他变…

单臂路由实验:通过Trunk和子接口实现VLAN互通

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. PC 配置 IP 地址2. PC3 属于 Vlan10,PC4 属于 Vlan20,配置单臂路由实现 Vlan10 和 Vlan20 三层互通3. 测试在 PC3 上 Ping PC4 ,可以 Ping 通 PC4 摘要: 本文…

任意文件读取及漏洞复现

文章目录 渗透测试漏洞原理任意文件读取1. 任意文件读取概述1.1 漏洞成因1.2 漏洞危害1.3 漏洞分类1.4 任意文件读取1.4.1 文件读取1.4.2 任意文件读取1.4.3 权限问题 1.5 任意文件下载1.5.1 一般情况1.5.2 PHP实现1.5.3 任意文件下载 2. 任意文件读取攻防2.1 路径过滤2.1.1 过…

引爆用户参与:消息重弹,让您的推送不再被忽略

在当前各大APP拉新促活成本居高不下的大背景下,如何稳定存量用户、提升用户粘性就显得尤为关键。从促销活动到个性化推荐,从互动通知到功能提醒,消息推送已成为各大APP连接存量用户和目标市场之间的桥梁,通过点击推送,…

springboot初试elasticsearch

引入依赖 elasticsearch的依赖版本与你elasticsearch要一致 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency> 索引库的操作 创建索引库 impo…

Visual Studio 2019下使用C++与Python进行混合编程——环境配置与C++调用Python API接口

前言 在vs2019下使用C与Python进行混合编程,在根源上讲&#xff0c;Python 本身就是一个C库&#xff0c;那么这里使用其中最简单的一种方法是把Python的C API来嵌入C项目中&#xff0c;来实现混合编程。当前的环境是&#xff0c;win10,IDE是vs2019,python版本是3.9&#xff0c…

LeetCode 刷题记录——从零开始记录自己一些不会的

1. 最多可以摧毁的敌人城堡数目 题意 思路 两层循环&#xff0c;太low了 用一个变量记录前一个位置 代码 class Solution { public:int captureForts(vector<int>& forts) {int ans 0, pre -1;for (int i 0; i < forts.size(); i) {if (forts[i] 1 || forts…

04、javascript 修改对象中原有的属性值、修改对象中原有属性的名字(两种方式)、添加对象中新属性等的操作

1、修改对象中原有的属性值 其一、代码为&#xff1a; // 想将 obj 中的 flag 值&#xff0c;根据不同的值来变化(即&#xff1a;修改对象中原有的属性值)&#xff1b; let obj {"port": "port_0","desc": "desc_0","flag&quo…

IP应用场景查询API:深入了解网络用户行为的利器

前言 随着数字时代的不断发展&#xff0c;互联网已经成为人们生活的重要组成部分。而随着越来越多的业务和社交活动迁移到在线平台上&#xff0c;了解和理解网络用户行为变得至关重要。为了满足这个需求&#xff0c;IP 应用场景查询 API 崭露头角&#xff0c;成为深入了解网络…

安卓绘制原理概览

绘制原理 Android 程序员都知道 Android 的绘制流程分为 Measure、Layout、Draw 三步骤&#xff0c;其中 Measure 负责测量 View 的大小Layout 负责确定 View 的位置Draw 负责将 View 画在屏幕上 由 ViewRootImpl 实现的 performTraversal 方法是 Measure、layout、draw 的真正…

Linux创建新文件的几种方式

第一种是 vi 文件名&#xff0c;然后进入vi编辑&#xff0c;完了之后保存退出&#xff1b;然后ls看一下&#xff0c;文件有了&#xff1b; 在终端输入 cat > 文件名&#xff0c;这没用过&#xff1b;输入以后回车&#xff0c;不会退出命令&#xff1b;输入一行文字&#xff…

TLA+学习记录1——hello world

0x01 TLA是个好工具 编程人员一个好习惯是凡事都想偷懒&#xff0c;当然是指要科学地偷懒&#xff0c;而不是真的偷懒。一直想找到一种能检验写出的代码&#xff0c;做出的设计是否真的完全正确&#xff0c;而不是靠经验检视、代码Review、反复测试去检验。因为上述方法不管怎…

学习心得07:C#

之前也没有看过C#的书&#xff0c;C#的程序倒是搞了一些。好在项目不大&#xff0c;我又会套路。 C#很象是JAVA。好像就是JAVA出来之后&#xff0c;微软抄的。好东西就要学习&#xff0c;这不丢脸。 我倒是想&#xff0c;有没有办法把JAVA和C#进行映射&#xff0c;然后直接编译…

Unity入门教程||创建项目(上)

一、介绍 目的&#xff1a;通过尝试制作一款使用玩家角色把小球弹飞的简单小游戏&#xff0c;熟悉使用Unity进行游戏开发的基本流程。 软件环境&#xff1a;Unity 2017.3.0f3&#xff0c;Visual Studio 2013 二、创建新项目 1&#xff0c;启动Unity后将出现一个并列显示Pro…

Springboot 实践(14)spring config 配置与运用--手动刷新

前文讲解Spring Cloud zuul 实现了SpringbootAction-One和SpringbootAction-two两个项目的路由切换&#xff0c;正确访问到项目中的资源。这两个项目各自拥有一份application.yml项目配置文件&#xff0c;配置文件中有一部分相同的配置参数&#xff0c;如果涉及到修改&#xf…

【C++】模拟实现二叉搜索树的增删查改功能

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 我的gitee&#xff1a;C仓库 个人专栏&#xff1a;C专栏 文章目录 一、二叉搜索树的Insert操作&#xff08;非递归&#xff09;分析过程代码求解 二、二叉搜索树的Erase操作&#xff08;非递归&#xff09;分析过程代码求解…

激光焊接汽车尼龙塑料配件透光率测试仪

激光塑性成型技术是近年来塑性加工界出现的一种新技术。通常塑料主要是通过加热加压依赖模具成型。这对于单品种、大批量生产是有效的&#xff1b;而对于各种不同形状的塑料制件则需要昂贵的模具‚装置也较庞大。 高度聚焦的激光束垂直照射在待变形的板料上‚由于塑料直接吸收激…

Zstack 安装 黑群晖未找到硬盘:解决方法

错误原因&#xff1a; 发生错误的原因&#xff0c;黑群晖要求硬盘为Sata格式&#xff0c;而默认创建的硬盘格式为Virtio&#xff0c;我们要做的就是修改挂载的虚拟硬盘改为Sata格式 解决方法&#xff1a; 1、进入 ZStack&#xff0c;找到黑群晖的主机&#xff0c;查看 UUID …

TSINGSEE青犀视频AI算法助力构建城市市容·街面秩序管理解决方案

随着城市化进程加快&#xff0c;未经合理规划设置自然形成的马路市场越来越多&#xff0c;这不仅存在交通安全隐患&#xff0c;也造成了市容秩序混乱&#xff0c;严重影响城市市容面貌。 TSINGSEE青犀AI智能分析网关V3内部部署了几十种算法&#xff0c;包括人脸、人体、车辆、…

Jmeter系列-环境部署、详细介绍、安装目录介绍(1)

环境部署 官网下载Jmeter http://jmeter.apache.org/下载最新版本的 JMeter&#xff0c;解压文件到任意目录 安装JDK&#xff0c;配置Java环境 1、下载&#xff08;注意选择操作系统对应的位数32/64&#xff09; 官网 &#xff1a;http://www.oracle.com 2、安装&#xff0…