当前位置: 首页 > news >正文

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); }}

在这里插入图片描述

相关文章:

STM32F4X RTC

STM32F4X RTC 什么是RTCSTM32F4X RTCSTM32F4X RTC框图STM32F4X RTC计数频率STM32F4X RTC日历STM32F4X RTC闹钟 STM32F4X RTC例程 什么是RTC RTC全程叫Real-Time Clock实时时钟,是MCU中一个用来计时的模块。RTC的一个主要作用是用来显示实时时间,就像日常…...

[git] 如何克隆仓库,进行项目撰写,并绑定自己的远程仓库

摘要:删除.git文件,才可重新绑定远程仓库。 具体步骤: 文件夹右键,进入”Git Bash Here“执行命令 1. 执行 ”git clone 仓库地址“,克隆仓库 2. 在生成的仓库中,删除 .git 文件 3. git init 初始化仓库…...

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

个人主页:🍝在肯德基吃麻辣烫 我的gitee:C仓库 个人专栏:C专栏 文章目录 一、二叉搜索树的Insert操作(非递归)分析过程代码求解 二、二叉搜索树的Erase操作(非递归)分析过程代码求解…...

Yolov8-pose关键点检测:模型轻量化创新 | ScConv结合c2f | CVPR2023

💡💡💡本文解决什么问题:ScConv(空间和通道重建卷积),一个即插即用的架构单元,可以可以直接用来替代各种卷积神经网络中的标准卷积。 ScConv | GFLOPs从9.6降低至9,参数量从6482kb降低至6479kb Yolov8-Pose关键点检测专栏介绍:https://blog.csdn.net/m0_637742…...

【洛谷 P1060】[NOIP2006 普及组] 开心的金明 题解(动态规划+01背包)

[NOIP2006 普及组] 开心的金明 题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说…...

什么是CI/CD:持续集成与持续交付?(InsCode AI 创作助手)

在现代软件开发领域,CICD(Continuous Integration and Continuous Delivery)是一种关键性的开发实践,它有助于提高软件交付的质量和效率。本文将深入探讨CICD的定义、原理和重要性,以及如何在项目中实施CICD流程。 什…...

redis 高可用

Redis 高可用 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供…...

什么样的词条可以创建维基百科?

维基百科在国内用得比较少,有一些特殊原因,维基百科的控制权海外,目前维基百科和谷歌是一样的,在国内是无法正常访问的。但做海外推广的朋友都是知道维基百科的,小马识途营销顾问认为它在世界互联网领域的地位&#xf…...

poll epoll初学习

正是select这些缺点,才有了poll 1.I/O多路转接之poll 2.I/O多路转接之epoll 其中的struct epoll_event:...

BMS电池管理系统——电芯需求数据(三)

BMS电池管理系统 文章目录 BMS电池管理系统前言一、有什么基础数据二、基础数据分析1.充放电的截至电压2.SOC-OCV关系表3.充放电电流限制表4.充放电容量特性5.自放电率 总结 前言 在新能源产业中电芯的开发也占有很大部分,下面我们就来看一下电芯的需求数据有哪些 …...

【uniapp】关于小程序输入框聚焦、失焦(输入法占位)的问题

聊天小程序,界面带有输入框,当输入框中聚焦后,底部自动谈起输入法。此时输入框也要随之出现在输入法上方。默认情况下,输入框此时会被输入法覆盖掉。 以下是亲自实践,解决这个问题的方法: 一、小程序大概…...

MySQL的故事——创建高性能的索引

创建高性能的索引 文章目录 创建高性能的索引一、索引基础二、索引的优点三、高性能的索引策略 一、索引基础 要理解MySQL中索引是如何工作的,最简单的方法就是去看看一本书的“索引 ”部分:如果在一本书中找到某个特定主题,一般会先看书的“…...

渗透测试漏洞原理之---【组件安全】

文章目录 1、组件安全概述1.1、常见组件1.1.1、操作系统1.1.2、Web容器1.1.3、中间件1.1.4、数据库1.1.5、开发框架1.1.6、OA系统1.1.7、其他组件 1.2、漏洞复现1.2.1 漏洞复现模板1.2.3、漏洞名称参考1.2.4、漏洞库 2、Apache2.1、Apache HTTPD2.2、Apache Shiro2.3、Apache T…...

uni-app集成mui-player

uni-app集成mui-player,仅说明集成方法,mui-player 相关配置请查看其官网 准备 在uniapp项目根目录新建hybrid目录在hybrid目录下新建html目录在html目录中新建css、js、img等目录,用于存放相关文件 集成 静态webview 在pages目录下新建v…...

力扣(LeetCode)算法_C++—— 两个数组的交集

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1: 输入:nums1 [1,2,2,1], nums2 [2,2] 输出:[2] 示例 2: 输入:nums1 …...

异步编程 - 12 异步、基于事件驱动的网络编程框架 Netty

文章目录 Netty概述Netty中的一些概念Netty的线程模型Netty Server端Netty Netty 端 TCP半包与粘包问题基于Netty与CompletableFuture实现RPC异步调用 Netty概述 Netty是一个异步、基于事件驱动的网络应用程序框架,其对Java NIO进行了封装,大大简化了TC…...

STM32 Nucleo-144开发板开箱bring-up

文章目录 1. 开篇2. 开发环境搭建2.1 下载官方例程2.2 ST-Link安装 3. STM32F446ZE demo工程3.1 STM32F446ZE简介3.2 跑个demo试一试 1. 开篇 最近做项目,用到STM32F446ZET6这款MCU,为了赶进度,前期软件需要提前开发,于是在某宝买…...

计算机毕业设计 基于SSM的问卷调查管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...

基于SpringBoot的无忌在线考试系统(源码+讲解+调试运行)做毕设课设均可

技术栈 前后端分离 前端使用: Vue Element Plus 后端使用: SpringBoot Mysql8.0 Mybatis-Plus 功能 分为 管理员端 和 老师端 和 学生端 管理员端 登陆页 ​科目管理 查看所有科目 ,增加 ,修改 ,删除科目 , 模糊搜索课程 ​考试管理 查看所有考试 ,增加 ,修改 ,删除考试 题库…...

无涯教程-JavaScript - EOMONTH函数

描述 EOMONTH函数返回该月最后一天的序列号,该序列号是start_date之前或之后的月份数。 语法 EOMONTH (start_date, months)争论 Argument描述Required/OptionalStart_date 代表开始日期的日期。 应该使用DATE函数或其他公式或函数的输出输入日期。 如果将日期作为文本输入…...

【LeetCode-面试经典150题-day21】

目录 120.三角形最小路径和 64.最小路径和 63.不同路径Ⅱ 5.最长回文子串 120.三角形最小路径和 题意: 给定一个三角形 triangle ,找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标…...

算法刷题记录-双指针/滑动窗口(LeetCode)

809. Expressive Words 思路 根据题目描述,我们可以知道,如果要将某个单词定义为可扩张(stretchy),需要满足如下两个条件: 所以,我们在实现的时候,可以通过两个指针p1和p2&#x…...

Python基础tuple元组定义与函数

元组的特点 有序:元组中的元素是按照顺序排列的。不可更改:一旦创建,元组中的元素不可被修改、增加或删除。元素类型多样化:元组可以包含任何数据类型的元素。 定义一个非空元组 name_tuple (a, b, c, d)定义一个空元组 name…...

【linux命令讲解大全】088.深入理解 shell 脚本中的 trap 命令

文章目录 trap概要主要用途选项参数返回值关于信号例子 从零学 python trap 捕捉信号和其他事件并执行命令。 概要 trap [-lp] [[arg] signal_spec ...]主要用途 用于指定在接收到信号后将要采取的动作。 脚本程序被中断时执行清理工作。 选项 -l:打印信号名称…...

bean的管理-bean的获取

获取bean 默认情况下,在Spring项目启动时,会把bean都创建好(但是还会受到作用域及延迟初始化的影响)放在IOC容器中,如果想主动获取这些bean,可以通过如下方式 根据name获取bean Object getBean&#xff08…...

如何快速清理已经上传到Git仓库的.DS_Store文件

很久以前,发过这样一篇文章《Git全局忽略MacOS系统下的.DS_Store文件》,主要是针对MacOS用户,如何方便的在自己机器中免疫所有.DS_Store文件的误提交。如果有这个需求,且还没有搞过的读者可以通过上面这篇文章学习。 今天想要分享…...

美的的笔试

第一题 有两只猫咪和n条不同类型的鱼,每条鱼都只能被其中一只猫咪吃掉。 下标为i处的鱼被吃掉的得分为: 如果第一只猫咪吃掉,则得分为reward1[i]。如果第二只猫咪吃掉,则得分为reward[i]。 给你一个正整数数组reward1 ,一个正整数数组reward2&#xff0…...

Android 1.2 开发环境搭建

目录 1.2 开发环境搭建 1.JDK安装与配置 2.开发工具二选一 3.相关术语的解析 4.ADB命令行的一些指令 5.APP程序打包与安装的流程: 6.APP的安装过程: 7.本节小结 1.2 开发环境搭建 现在主流的Android开发环境有: ①Eclipse ADT SDK ②Android Stu…...

vue 页面加水印

首先创建一个waterMark.js文件,当然文件命名可自定义, use strictconst watermark {}/**** param {要设置的水印的内容} str* param {需要设置水印的容器} container*/ const setWatermark (str, container) > {const id 1.23452384164.123412415…...

Android ImageView详解

scaleType属性详解 在 Android 中,ImageView 控件的 scaleType 属性用于指定图像在 ImageView 内部的缩放和对齐方式。scaleType 属性可以帮助你控制图像的显示方式,以适应 ImageView 的尺寸或实现其他特定的显示效果。以下是常见的 scaleType 属性值和…...