【蓝桥杯——物联网设计与开发】基础模块8 - RTC

news2025/4/6 13:42:41

目录

一、RTC

(1)资源介绍

        🔅简介

        🔅时钟与分频(十分重要‼️)

(2)STM32CubeMX 软件配置

(3)代码编写

(4)实验现象

二、RTC接口函数封装

三、踩坑日记

(1)RTC时间读取问题

(2)RTC分频系数修改问题

(3)RTC时钟不准确问题


一、RTC

(1)资源介绍

        🔅简介

(以下资料来源于STM32L0_参考手册(L0x1))

  • RTC提供自动唤醒来管理所有低功耗模式。
  • 实时时钟(RTC)是一个独立的BCD定时器/计数器。RTC提供了一个带有可编程报警中断的时间时钟/日历。
  • RTC还包括一个具有中断能力的周期性可编程唤醒标志。
  • 两个32位寄存器包含秒、分、小时(12或24小时格式)、天(星期中的一天)、日期(月中的一天)、月和年,以二进制编码的十进制格式(BCD)表示。分秒值也可以以二进制格式提供。
  • 28天、29天(闰年)、30天和31天的补偿将自动执行。还可以执行夏令时补偿。
  • 额外的32位寄存器包含可编程报警子秒,秒,分钟,小时,日和日期。
  • 数字校准功能可用于补偿晶体振荡器精度的任何偏差。
  • 在RTC域重置后,所有RTC寄存器都受到保护,防止可能的寄生写访问。
  • 只要电源电压保持在工作范围内,无论设备状态(运行模式、低功耗模式或复位),RTC都不会停止。
图1        RTC框图

        🔅时钟与分频(十分重要‼️

        RTC时钟源(RTCCLK)是通过LSE时钟LSI振荡器时钟HSE时钟之间的时钟控制器来选择的。

        一个可编程的预分频器阶段产生一个1Hz的时钟,用于更新日历。为了尽量减少功耗,预分频器被分成2个可编程的预分频器:

  • 通过RTC_PRER寄存器的PREDIV_A位配置的7位异步预分频器
  • 通过RTC_PRER寄存器的PREDIV_S位配置的15位同步预分频器

⚠️注意:当同时使用两个预分频器时,建议将异步预分频器配置为较大的值,以减少消耗。

        LSE频率为32.768 kHz时,将异步预分频器的分频因子设置为128,将同步预分频器分频因子设置为256,得到的内部时钟频率为1Hz(ck_spre) 。即:(默认参数)

        PREDIV_A = 127;

        PREDIV_S = 255;

f_{CK\_ APRE}=\frac{f_{RTCCLK}}{PREDIV\_A+1}

f_{CK\_SPRE}=\frac{f_{RTCCLK}}{\left ( PREDIV\_S+1 \right )\times \left ( PREDIV\_A+1 \right )}

        但是,在蓝桥杯物联网竞赛实训平台上,RTC的时钟只能通过LSI RC(37kHz)来获得,所以默认的参数不适宜本平台,需要进行修改‼️

        在这里,根据以异步预分频器值较大为优先原则,计算出一个合理的参数值,即:

        PREDIV_A = 124;

        PREDIV_S = 295;

图2        时钟树

(2)STM32CubeMX 软件配置


🔅“工程建立、时钟树配置、Debug 串行线配置、代码生成配置” 在下文中有讲解,这里不再赘述❗️

【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出icon-default.png?t=O83Ahttps://blog.csdn.net/m0_63116406/article/details/135604705?spm=1001.2014.3001.5502

1️⃣点击"Timers" → 点击"RTC" → 勾选"Activate Clock Source""Activate Calendar" → 修改异步预分配值为124,同步预分频值为295 → 修改日历时间23时59分55秒

图3        RTC配置


2️⃣使能OLED

3️⃣使能TIM2

4️⃣生成代码即可;

(3)代码编写

🟢️main 函数

/* USER CODE BEGIN PV */
uint8_t puc_buf[17];                            // OLED显示缓存区
RTC_TimeTypeDef now_time;                       // RTC时间结构体
RTC_DateTypeDef now_date;                       // RTC日期结构体
uint8_t hour = 23, minute = 59, second = 55;    // 定时器计时
uint16_t cnt_1s;                                // 定时器计时1秒
/* USER CODE END PV */
/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM2)
	{
        /* 定时器计时1000次1ms,即1秒,更新一次数据 */
		if(++cnt_1s == 1000)
		{
			cnt_1s = 0;
			if(++second == 60)
			{
				second = 0;
				if(++minute == 60)
				{
					minute = 0;
					if(++hour == 24)
						hour = 0;
				}
			}
		}
	}
}
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
	HAL_RCC_EnableCSS();
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C3_Init();
  MX_RTC_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
	OLED_Init();
	HAL_TIM_Base_Start_IT(&htim2);    // 开启定时器2中断
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        /* 获取RTC值 */
		HAL_RTC_GetTime(&hrtc, &now_time, RTC_FORMAT_BIN);
		HAL_RTC_GetDate(&hrtc, &now_date, RTC_FORMAT_BIN);
        /* OLED显示 */
        // 第一行显示RTC的时间
		sprintf((char*)puc_buf, "  %2d : %2d : %2d  ", now_time.Hours, now_time.Minutes, now_time.Seconds);
		OLED_ShowString(0, 0, puc_buf, 16);
        // 第二行显示定时器的时间
		sprintf((char*)puc_buf, "  %2d : %2d : %2d  ", hour, minute, second);
		OLED_ShowString(0, 2, puc_buf, 16);	
		HAL_Delay(200);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
  }

(4)实验现象

  •         RTC更新的时间较快;
  •         计时器更新的时间与手机时钟相同;

二、RTC接口函数封装

🟡️RTC更新时钟函数

void RTC_Get(void)
{
	HAL_RTC_GetTime(&hrtc, &now_time, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &now_date, RTC_FORMAT_BIN);
}

🟡️定时器中断更新时钟函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM2)
	{
        /* 定时器计时1000次1ms,即1秒,更新一次数据 */
		if(++cnt_1s == 1000)
		{
			cnt_1s = 0;
			if(++second == 60)
			{
				second = 0;
				if(++minute == 60)
				{
					minute = 0;
					if(++hour == 24)
						hour = 0;
				}
			}
		}
	}
}

三、踩坑日记

(1)RTC时间读取问题

        🔅RTC读取需要先读取时间,后必须读取日期,否则读取的时间不能更新❗️❗️❗️

        即需要调用下面两个函数,否则无法正常更新时间:

        HAL_RTC_GetTime(&hrtc, &now_time, RTC_FORMAT_BIN);

        HAL_RTC_GetDate(&hrtc, &now_date, RTC_FORMAT_BIN);

(2)RTC分频系数修改问题

        🔅由于开发板上RTC的时钟不为32.768kHz,所以不能使用默认的分频系数,根据其LSI RC37kHz)时钟源,计算出合理的分频系数:

        PREDIV_A = 124;

        PREDIV_S = 295;

而官方例程给出的分频系数为:

        PREDIV_A = 127;

        PREDIV_S = 290;

(127 + 1) * (290 + 1) = 37248,可知,该数据不太合理;

❗️但是,无论是本文给出的参数还是官方给出的参数,亦或是默认参数在实际测试时,频率都不准确❗️

(3)RTC时钟不准确问题

        🔅针对这一问题,上文已经给出另外一种解决方案,即使用一个1ms定时器来模拟RTC,实测效果与手机时钟基本一致,能够满足赛题精准要求;

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

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

相关文章

Web3.0安全开发实践:探索比特币DeFi生态中的PSBT

近年来,部分签名比特币交易(PSBT)在比特币生态系统中获得了显著关注。随着如Ordinal和基于铭文的资产等创新的兴起,安全的多方签名和复杂交易的需求不断增加,这使得PSBT成为应对比特币生态不断发展中不可或缺的工具。 …

MaxKB基于大语言模型和 RAG的开源知识库问答系统的快速部署教程

1 部署要求 1.1 服务器配置 部署服务器要求: 操作系统:Ubuntu 22.04 / CentOS 7.6 64 位系统CPU/内存:4C/8GB 以上磁盘空间:100GB 1.2 端口要求 在线部署MaxKB需要开通的访问端口说明如下: 端口作用说明22SSH安装…

【VMware虚拟机】安装win10系统教程双机可ping通

目录 1、下载1.1、点击链接下载媒体创建工具:1.2、下载后得到MediaCreationTool_22H2.exe:1.3、获取ISO镜像 2、安装3、显示4、配置网络4.1、配置4.2、排查4.2.1、关闭防火墙4.2.2、增加路由 1、下载 Windows10微软官网下载链接: https://www.microsoft…

AI一键制作圣诞帽头像丨附详细教程

我用AI换上圣诞帽头像啦~🎅 不管是搞笑表情、宠物头像还是你的自拍!!都能一键添加圣诞帽元素,毫无违和感!🎉 详细教程在P3、P4,手残党也能轻松搞定! 宝子们需要打“need”&#xff0…

活动图的理解和实践

在软件开发和系统设计中,理解系统的工作流程和并发行为是至关重要的。活动图作为一种重要的建模工具,为我们提供了一种直观且有效的方法来描述这些复杂的过程。本文将详细探讨活动图的理解与实践,包括其基本概念、用途、构建方法以及实际应用…

电磁兼容(EMC):一文解读磁芯复合材料——塑磁

目录 01 塑磁的定义 02 塑磁的常见规格型号 03 塑磁材料的优点 04 塑磁的应用 塑磁,也称为注塑磁,是一种将磁性粉末注入到塑料基体中制成的复合磁体材料。以下是塑磁的定义、应用和材料特性的总结: 01 塑磁的定义 塑磁是以塑料为基体,通过特殊工艺在其中加入磁性粒子(…

C语言-结构体内存大小

#include <stdio.h> #include <string.h> struct S1 { char a;//1 int b;//4 char c;//1 }; //分析 默认对齐数 成员对齐数 对齐数(前两个最小值) 最大对齐数 // 8 1 …

设计模式的主要分类是什么?请简要介绍每个分类的特点。

大家好&#xff0c;我是锋哥。今天分享关于【设计模式的主要分类是什么&#xff1f;请简要介绍每个分类的特点。】面试题。希望对大家有帮助&#xff1b; 设计模式的主要分类是什么&#xff1f;请简要介绍每个分类的特点。 1000道 互联网大厂Java工程师 精选面试题-Java资源分…

Java Web开发基础——Web应用的请求与响应机制

在本节中&#xff0c;我们将深入探讨Web应用程序中最为核心的部分之一——请求与响应机制。理解Web应用如何处理客户端请求并生成响应是成为Java Web开发者的关键。我们将从HTTP协议的基础知识开始&#xff0c;逐步过渡到请求参数的获取、响应内容的发送以及会话管理&#xff0…

免杀对抗—Behinder魔改流量特征去除

前言 在现实的攻防中&#xff0c;往往webshell要比主机后门要用得多&#xff0c;因为我们首先要突破的目标是网站嘛&#xff0c;而且waf也往往会更注重webshell的检测。webshell的免杀分为两个&#xff0c;一是静态查杀&#xff0c;二是流量查杀。静态查杀不用多说了&#xff…

Flutter 异步编程简述

1、isolate 机制 1.1 基本使用 Dart 是基于单线程模型的语言。但是在开发当中我们经常会进行耗时操作比如网络请求&#xff0c;这种耗时操作会堵塞我们的代码。因此 Dart 也有并发机制 —— isolate。APP 的启动入口main函数就是一个类似 Android 主线程的一个主 isolate。与…

RAID5原理简介和相关问题

1、RAID5工作原理 2、RAID5单块硬盘的数据连续吗&#xff1f; 3、RAID5单块硬盘存储的是原始数据&#xff0c;还是异或后的数据&#xff1f; 4、RAID5的分块大小 ‌RAID5的分块大小一般选择4KB到64KB之间较为合适‌。选择合适的分块大小主要取决于以下几个考量因素&#xff1…

四、使用langchain搭建RAG:金融问答机器人--构建web应用,问答链,带记忆功能

经过前面3节完成金融问答机器人基本流程&#xff0c;这章将使用Gradio构建web应用&#xff0c;同时加入memory令提示模板带有记忆的&#xff0c;使用LCEL构建问答链。 加载向量数据库 from langchain.vectorstores import Chroma from langchain_huggingface import HuggingF…

理解神经网络

神经网络是一种模拟人类大脑工作方式的计算模型&#xff0c;是深度学习和机器学习领域的基础。 基本原理 神经网络的基本原理是模拟人脑神经系统的功能&#xff0c;通过多个节点&#xff08;也叫神经元&#xff09;的连接和计算&#xff0c;实现非线性模型的组合和输出。每个…

Mac系统下 IDEA配置Maven本地仓库

1.为什么需要配置本地仓库&#xff1f; 在软件开发过程中&#xff0c;使用Maven工具进行依赖管理是常见的做法。Maven通过集中管理各种依赖库&#xff0c;能够帮助开发者在项目中轻松地引入所需的第三方库&#xff0c;并确保项目能够顺利构建和部署。然而&#xff0c;在使用Mav…

selenium学习笔记(一)

文章目录 前言一、selenium的简介java使用seleniumPython使用selenium常用的浏览器selenium的功能 二、chromeDriver的安装查看本机的chrome版本&#xff1f;匹配对应的chromedriver并下载在服务器上例如Centos如何安装Chrome 三、selenium内容详解chrome启动chrome启动参数元素…

MDS-NPV/NPIV

在存储区域网络&#xff08;SAN&#xff09;中&#xff0c;域ID&#xff08;Domain ID&#xff09;是一个用于区分不同存储区域的关键参数。域ID允许SAN环境中的不同部分独立操作&#xff0c;从而提高效率和安全性。以下是关于域ID的一些关键信息&#xff1a; 域ID的作用&…

一篇文章学会HTML

目录 页面结构 网页基本标签 图像标签 超链接标签 文本链接 图像链接 锚链接 功能链接 列表 有序列表 无序列表 自定义列表 表格 跨列/跨行 表头 媒体元素 视频 音频 网站的嵌套 表单 表单元素 文本框 单选框 多选框 按钮 下拉框 文本域和文件域 表…

畅捷通-条件竞争

反编译dll 逻辑上很清晰了。取得上传数据然后直接写入Templates目录里去&#xff0c;且写入路径直接拼接文件名&#xff0c;说明写入路径可控。然后马上又调用Delete方法删除文件。看起来貌似很正常的样子&#xff0c;但实际上这里已经出现了严重的安全问题。首先是未限制上传…

web三、 window对象,延时器,定时器,时间戳,location对象(地址),本地存储-localStorage,数组去重new Set

一、window对象 window对象 是一个全局对象&#xff0c;也可以说是JavaScript中的 顶级对象 像document、alert()、console.log()这些都是window的属性&#xff0c;基本BOM的属性和方法都是window的 所有通过 var定义 在全局作用域中的 变量 、 函数 都会变成window对象的属…