STM32入门笔记14_RTC实时时钟

news2024/11/24 5:41:16

BKP和RTC实时时钟

BKP

BKP简介

  • BKP(Backup Registers) 备份寄存器
  • BKP可用于存储用户应用程序数据。当VDD(2.0-3.6V) 电源被切断时,仍然由VBAT(1.8-3.6V) 维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,也不会被复位
  • TAMPER引脚产生的侵入事件将所有备份寄存器内容清除(可做防拆卸设计)
  • RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲
  • 存储RTC时钟校准寄存器
  • 用户数据存储容量:20字节(中容量和小容量)/ 84字节(大容量和互联型)

BKP基本结构

在这里插入图片描述

  • 每个数据寄存器存2个字节数据,中容量和小容量共十个DR,大容量和互联型共42个DR

RTC

RTC简介

  • RTC(real time clock) 实时时钟
  • RTC是一个独立的定时器,可为系统提供时钟和日历的功能
  • RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD(2.0-3.6V)断电后可借助VBAT(1.8-3.6V)供电继续走时
  • 32位的可编程计数器,可对应Unix时间戳的秒计数器
  • 20位的可编程预分频器,可适配不同频率的输入时钟
  • 可选择三种RTC时钟源:( 通常使用LSE)
    • HSE时钟除以128(通常为8MHz/128)
    • LSE振荡器时钟(通常为32.768KHz)
    • LSI振荡器时钟(40KHz)

在这里插入图片描述

  • RTCCLK 一般信号频率一般为32.768kHz

  • RTC预分频器通过计数实现对输入信号的分频,RTC_DIV实际是一个计数器,RTC_PRL用于设置预分频值( 分频倍数 = RTC_PRL+1 )

    • 为得到每秒的计时(RTC_PRL一般为32767)
  • RTC_CNT中存放的是UNIX时间戳的秒数

  • RTC_ALR是RTC的闹钟功能,当RTC_CNT=RTC_ALR时,触发RTC_Alarm中断。若配置了RTC_Alarm中断服务,可在中断服务函数中执行需要的操作

  • RTC_Overflow但RCT_CNT溢出时会触发该中断,一般不会触发

  • RTC_Second, 每秒中断(具体时间由输入信号频率与预分频系数配置决定)

RTC框图

在这里插入图片描述

  • 一般情况信号源为LSE,且外部一般接32.768khz的石英晶振 (制作工艺和使用方便)

硬件电路

在这里插入图片描述

  • C1和C2的参数教程是参考手册,但若有硬件设计需求,建议参考所选用晶振的负载电容大小

在这里插入图片描述

在这里插入图片描述

  • 值得注意的是: 晶振本身就有百万分之几十的误差(ppm), 因此电容相差不太的情况, 所造成的误差可能也就几百万分之一

  • 电容对频率的影响: 电容越大频率越低,反之越高

  • 这里是一个UP对晶振电容大小和频率的测试视频 【晶振的负载电容到底怎么选择?】

RTC操作注意事项

  • 执行以下操作将使能对BKP和RTC的访问:

    • 设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和BKP时钟

    • 设置PWR_CR的DBP,使能对BKP和RTC的访问

  • 若在读取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1 (等待同步)

  • 必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器 (进入配置模式, 无需软件操作 )

  • 对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器 (等待写入)

程序设计

读写BKP

在这里插入图片描述

#include "stm32f10x.h" 
#include "delay.h"
#include "OLED.h"

int main(void)
{
    OLED_Init();
	// RCC
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);  // 使能BKP
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);  // 使能PWR
	
	PWR_BackupAccessCmd(ENABLE);   // 配置DBP
	
	BKP_WriteBackupRegister(BKP_DR1, 0x01);  // 写入数据 中容量 DR1-DR10 第二次注释该行
	OLED_ShowHexNum(1, 1, BKP_ReadBackupRegister(BKP_DR1), 4);   // 读BKP DR寄存器
	// 在提供备用电源的情况下,断电和复位不会情况BKP里的数据
	while(1)
	{
		
	}
}

  • PWR_BackupAccessCmd(ENABLE) 实际配置了CR寄存器的DBP位
/**
  * @brief  Enables or disables access to the RTC and backup registers.
  * @param  NewState: new state of the access to the RTC and backup registers.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void PWR_BackupAccessCmd(FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState;
}

读写RTC

在这里插入图片描述

MyRTC.c

#include "stm32f10x.h"
#include <time.h>
uint16_t MyRTC_Time[] = {2023, 9, 18, 20, 40, 58};

/**
* @brief 设置时间
*/
void MyRTC_SetTime(void)
{
	time_t time_cnt;
	struct tm time_date;
	
	time_date.tm_year = MyRTC_Time[0] - 1900;  // 年
	time_date.tm_mon = MyRTC_Time[1] - 1;  // 月
	time_date.tm_mday = MyRTC_Time[2];  // 日
	time_date.tm_hour = MyRTC_Time[3];  // 时
	time_date.tm_min = MyRTC_Time[4];  // 分
	time_date.tm_sec = MyRTC_Time[5];   // 秒
  	
	time_cnt = mktime(&time_date) - 8 * 60 * 60;  // 转换为时间戳 减去东八偏移
	
	RTC_SetCounter(time_cnt);  // 将数据写入RTC的CNT
	RTC_WaitForLastTask();  // 等待写入完成
	
}

/**
* @brief 读取时间
*/
void MyRTC_ReadTime(void)
{
	time_t time_cnt;
	struct tm time_date;
	
	time_cnt = RTC_GetCounter() + 8 * 60 * 60;  // 加上东八区偏移
	
	time_date = *localtime(&time_cnt);
	
	MyRTC_Time[0] = time_date.tm_year + 1900; // 年
	MyRTC_Time[1] = time_date.tm_mon + 1;// 月
	MyRTC_Time[2] = time_date.tm_mday;  // 日
	MyRTC_Time[3] = time_date.tm_hour;  // 时
    MyRTC_Time[4] = time_date.tm_min ;  // 分
    MyRTC_Time[5] = time_date.tm_sec ;   // 秒
	
}

/**
* @brief 初始化RTC
*/
void MyRTC_Init(void)
{
	// RCC
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
	
	PWR_BackupAccessCmd(ENABLE);  // 设置CR寄存器的DBP位
	
	if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) // 避免时间重复写入
	{
		RCC_LSEConfig(RCC_LSE_ON);  // 开启LSE时钟 外接32.768khz晶振 LSE默认不上电
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);  // 等待LSE起振
		
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // 设置RTC时钟源为LSE
		RCC_RTCCLKCmd(ENABLE);  // 使能时钟
		
		RTC_WaitForSynchro();  // 等待同步
		RTC_WaitForLastTask(); // 等待写入完成 
		
		RTC_SetPrescaler(37628-1);  // 设置分频系数
		RTC_WaitForLastTask();
		
		MyRTC_SetTime();  // 设置时间 
		
		BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
	}
	else
	{
		RTC_WaitForSynchro();  // 等待同步
		RTC_WaitForLastTask(); // 等待写入完成 
	}
}

MyRTC.h

#ifndef __MYRTC_H
#define __MYRTC_H

extern uint16_t MyRTC_Time[];

void MyRTC_Init(void);
void MyRTC_SetTime(void);
void MyRTC_ReadTime(void);
void MyRTC_Init(void);

#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"

int main(void)
{
	OLED_Init();
	MyRTC_Init();
	
	OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
	OLED_ShowString(2, 1, "Time:XX:XX:XX");
	OLED_ShowString(3, 1, "CNT :");
	OLED_ShowString(4, 1, "DIV :");
	
	while (1)
	{
		MyRTC_ReadTime();
		
		OLED_ShowNum(1, 6, MyRTC_Time[0], 4);
		OLED_ShowNum(1, 11, MyRTC_Time[1], 2);
		OLED_ShowNum(1, 14, MyRTC_Time[2], 2);
		OLED_ShowNum(2, 6, MyRTC_Time[3], 2);
		OLED_ShowNum(2, 9, MyRTC_Time[4], 2);
		OLED_ShowNum(2, 12, MyRTC_Time[5], 2);
		
		OLED_ShowNum(3, 6, RTC_GetCounter(), 10);
		OLED_ShowNum(4, 6, RTC_GetDivider(), 10);  // 余数寄存器
	}
}

资料

【晶振的负载电容到底怎么选择?】

【STM32入门教程-2023持续更新中】

STM32F10xxx参考手册(中文).pdf

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NoSQL之Redis 群集模式实现高可用

目录 1 Redis 群集模式 1.1 集群的作用&#xff0c;可以归纳为两点 1.2 Redis集群的数据分片 2 搭建Redis 群集模式 2.1 开启群集功能 2.2 启动redis节点 2.3 启动集群 2.4 测试群集 1 Redis 群集模式 集群&#xff0c;即Redis Cluster&#xff0c;是Redis 3.0开始引入…

基于FPGA的数字时钟系统设计

在FPGA的学习中&#xff0c;数字时钟是一个比较基础的实验案例&#xff0c;通过该实验可以更好的锻炼初学者的框架设计能力以及逻辑思维能力&#xff0c;从而打好坚实的基本功&#xff0c;接下来就开始我们的学习吧&#xff01; 1.数码管介绍 数码管通俗理解就是将8个LED(包含…

ARM-day5作业

.text .global _start _start: 1、设置GPIOE、GPIOF寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28 LDR R0,0x50000a28 LDR R1,[R0] ORR R1,R1,#(0x3<<4) STR R1,[R0]2、设置PE10、PF10、PE8管脚为输出模式 GPIOE_MODER[21:20]->01 0x50006000…

【数据恢复篇】记一次Winhex镜像还原(恢复)到磁盘测试记录

【数据恢复篇】记一次Winhex镜像还原&#xff08;恢复&#xff09;到磁盘测试记录 镜像恢复到磁盘&#xff0c;怎么操作&#xff1f;会不会对磁盘有影响&#xff0c;是恢复到空磁盘&#xff1f;还是恢复到有数据的磁盘也可以&#xff1f;有数据的盘磁盘空间很多&#xff0c;恢…

TDengine+OpenVINO+AIxBoard,助力时序数据分类

时间序列数据分析在工业&#xff0c;能源&#xff0c;医疗&#xff0c;交通&#xff0c;金融&#xff0c;零售等多个领域都有广泛应用。其中时间序列数据分类是分析时序数据的常见任务之一。本文将通过一个具体的案例&#xff0c;介绍 Intel 团队如何使用 TDengine 作为基础软件…

合适才是最好的!Mac或iPhone用户应该在家里更新Wi-Fi 6或6E路由器吗

Wi-Fi联盟制定了行业标准Wi-Fi设备的认证程序&#xff0c;几年前为所有出现的几代Wi-Fi创建了一个新的品牌体系。此前&#xff0c;Wi-Fi通常由IEEE工程标准组织不知名的工作组编号来识别&#xff0c;如802.11n或802.11ac。为了更简单地混合和匹配设备&#xff0c;并了解你使用的…

图观 | 从新加坡破获巨大洗钱案反观图数据库技术的重要性

前言&#xff1a; 新加坡破获的巨大洗钱案突显了金融领域对于高效数据管理和分析的需求&#xff0c;同时也凸显了图数据库技术在应对复杂犯罪网络和洗钱活动方面的重要性。传统的关系型数据库很难有效处理具有多层次关系和复杂连接模式的数据&#xff0c;而图数据库则以其在处…

目标识别项目实战:基于Yolov7-LPRNet的动态车牌目标识别算法模型(三)

前言 目标识别如今以及迭代了这么多年&#xff0c;普遍受大家认可和欢迎的目标识别框架就是YOLO了。按照官方描述&#xff0c;YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c;以进一步提升性能和灵活性…

高压放大器的主要技术指标是什么

高压放大器是一种特殊类型的放大器&#xff0c;主要用于将低电压信号放大到高电压水平。它在许多领域中具有重要的应用&#xff0c;如医学成像、科学研究、工业设备等。为了正确选择和评估高压放大器&#xff0c;我们需要了解其主要技术指标。以下是高压放大器的主要技术指标的…

Databend 开源周报第 113 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 数据导入具有额…

IO流 之 数据流 和 对象序列化

数据流 数据输出流&#xff08;DataOutputStream&#xff09;&#xff1a;允许把一些数据和其类型一起写道文件中去。 代码使用&#xff1a; package day0927;import java.io.DataOutput; import java.io.DataOutputStream; import java.io.FileOutputStream;public class de…

人体姿态标注

人体姿态标注 一 标注工具labelme1.1 安装方式1.2 界面说明 二 数据集准备 不要在网上搜图以下每张图片的命名方式&#xff1a;状态_学号_序号.jpg (注意 一定是jpg格式) 保存到一个文件夹中&#xff0c;便于标注。 例如&#xff1a;FALL_0000_0001.jpg 站立数据(UP)&#xff1…

C位操作符

目录 一、位操作符 1.位与& 2.位或| 3.位取反~ 4.位异或^ 5.位与&#xff0c;位或&#xff0c;位异或的特点总结 6.左移位《《 右移位 》》 二、位与&#xff0c;位或&#xff0c;位异或在操作寄存器时的特殊作用 1.寄存器操作的要求&#xff08;特定位改变而不…

社科院与杜兰大学能源管理硕士项目——惊喜会随时间慢慢酝酿而出

我们越来越难感受到惊喜&#xff0c;按部就班的生活让我们丧失了感知力&#xff0c;我们再难以被简单的确幸所打动。试试停下脚步&#xff0c;惊喜往往不期而遇。社科院与杜兰大学能源管理硕士项目是你人生中的小确幸吗 学习是一种持续不断的自我提升&#xff0c;它能让我们逐渐…

【Python_PySide2学习笔记(十五)】按键QPushButton类的基本用法

按键QPushButton类的基本用法 前言正文1、创建按键2、按键设置文本3、按键设置启用、禁用4、按键设置背景色及透明度5、按键设置字体、字体大小、字体颜色6、按键设置图标7、按键信号&#xff1a;被点击8、按键设置背景图片 前言 此篇文章中介绍PySide2中 按键QPushButton类的…

Cuckoo沙箱各Ubuntu版本安装及使用

1.沙箱简介 1.1 沙箱 沙箱是一个虚拟系统程序&#xff0c;允许你在沙箱环境中运行浏览器或其他程序&#xff0c;因此运行所产生的变化可以随后删除。它创造了一个类似沙盒的独立作业环境&#xff0c;在其内部运行的程序并不能对硬盘产生永久性的影响。 在网络安全中&#xff…

短视频时代的领军者:TikTok能否引领数字创新浪潮?

曾经&#xff0c;人们认为短视频只是娱乐和消遣的一种方式&#xff0c;然而&#xff0c;TikTok却颠覆了这一观念。它已经超越了娱乐&#xff0c;成为了一个强大的内容创作和传播平台&#xff0c;重新定义了数字时代的社交互动方式。 那么&#xff0c;TikTok是否真的能够引领创…

【arm实验1】GPIO实验-LED灯的流水亮灭

linuxlinux:~/study/01-asm$ cat asm-led.S .text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28 LDR R0,0X50000A28 LDR R1,[R0] 从r0为起始地址的4字节数据取出放在R1 ORR R1,R1,#(0x1<<4) 第4位设置为1 ORR R…

0基础学习VR全景平台篇 第105篇:调色原理和色彩分析

“我心藏瑰宝灿烂如歌&#xff0c;唯有画作可为我吟唱。” 绘画、摄影、音乐等一切艺术&#xff0c;皆如是&#xff0c;敬梵高。 本节教程邀请李小岩老师讲授&#xff0c;大家欢迎&#xff01; 大家好&#xff01;欢迎收看我们这一节的课程&#xff0c;我们这一节呢主要讲的是…

定时任务 - 若依cloud -【 132 ~ 133 】

132 定时任务相关使用 | RuoYi&#xff08;单独启动&#xff09; 1、后台添加定时任务处理类&#xff08;支持Bean调用、Class类调用&#xff09; &#xff08;1&#xff09;bean调用 bean调用&#xff1a;需要添加对应Bean注解Component或Service。调用方式&#xff1a;ryTa…