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

目录

一、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,实测效果与手机时钟基本一致,能够满足赛题精准要求;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

API安全学习笔记

必要性 前后端分离已经成为web的一大趋势,通过TomcatNgnix(也可以中间有个Node.js),有效地进行解耦。并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器&#x…

2011-2020年各省城镇职工基本医疗保险年末参保人数数据

2011-2020年各省城镇职工基本医疗保险年末参保人数数据 1、时间:2011-2020年 2、来源:国家统计局 3、指标:省份、时间、城镇职工基本医疗保险年末参保人数 4、范围:31省 5、指标解释:参保人数指报告期末按国家有关…

【蓝桥杯——物联网设计与开发】拓展模块4 - 脉冲模块

目录 一、脉冲模块 (1)资源介绍 🔅原理图 🔅采集原理 (2)STM32CubeMX 软件配置 (3)代码编写 (4)实验现象 二、脉冲模块接口函数封装 三、踩坑日记 &a…

Kubernetes Gateway API-2-跨命名空间路由

1 跨命名空间路由 Gateway API 具有跨命名空间路由的核心支持。当多个用户或团队共享底层网络基础设施时,这很有用,但必须对控制和配置进行分段,以尽量减少访问和容错域。 Gateway 和 Route(HTTPRoute,TCPRoute,GRPCRoute) 可以部署到不同的命名空间中,路由可以跨命名空间…

Windows Powershell实战指南(未完成)

目前只作简单了解,开始吧。 一、初识Powershell 目标 初步认识 Powershell和其集成环境 Ise,学会基本设置 实验 我们从简单的例子开始:希望你能从控制台和ISE的配置中实现相同的结果。然后按照下面五步进行。 (1)选…

Android着色器SweepGradient渐变圆环,Kotlin

Android着色器SweepGradient渐变圆环,Kotlin import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.SweepGradient import android…

项目上传到gitcode

首先需要在个人设置里面找到令牌 记住自己的账号和访问令牌(一长串),后面git要输入这个, 账号是下面这个 来到自己的仓库 #查看远程仓库,是不是自己的云仓库 git remote -v # 创建新分支 git checkout -b llf # 三步…

SAQ问卷的定义,SAQ问卷是什么?

SAQ问卷,全称为可持续发展评估问卷(Sustainability Assessment Questionnaire),是一种在线自评工具,其深远意义与广泛应用在当今商业环境中愈发凸显。它不仅是一种衡量企业在环境、社会和治理(ESG&#xff…

SpringBoot获取bean的几种方式

目录 一、BeanFactory与ApplicationContext的区别 二、通过BeanFactory获取 三、通过BeanFactoryAware获取 四、启动获取ApplicationContext 五、通过继承ApplicationObjectSupport 六、通过继承WebApplicationObjectSupport 七、通过WebApplicationContextUtils 八、通…

web3基于zkEVM的L2扩容方案-Scroll

项目简介 Scroll 是2021年由华人创始团队推出的 基于zkEVM 的 以太坊ZKR扩容方案,不同于zkSync的语言级别兼容,Scroll实现了完全EVM等效,即字节码层级兼容,除了数据结构和状态树等部分,zkEVM看起来与以太坊完全一样&a…

深入浅出 Linux 操作系统

深入浅出 Linux 操作系统 引言 在当今数字化的时代,Linux 操作系统无处不在。从支撑互联网巨头庞大的数据中心,到嵌入智能家居设备的微型芯片,Linux 都发挥着关键作用。然而,对于许多人来说,Linux 仍笼罩着一层神秘的…

Python毕业设计选题:基于python的白酒数据推荐系统_django+hive

开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 白酒管理 系统管理 看板展示 系统首页 白酒详情…

【赵渝强老师】MongoDB逻辑存储结构

MongoDB的逻辑存储结构是一种层次结构,主要包括了三个部分,即:数据库(Database)、集合(Collection,也可以叫做表)和文档(Document,也可以叫做记录&#xff09…

Python数据可视化小项目

英雄联盟S14世界赛选手数据可视化 由于本学期有一门数据可视化课程,课程结课作业要求完成一个数据可视化的小Demo,于是便有了这个小项目,课程老师要求比较简单,只要求熟练运用可视化工具展示数据,并不要求数据来源&am…

继承超详细介绍

一 、继承 1 继承的概念 继承是面向对象程序设计使得代码可以复用的最重要手段,它使得我们可以在原有类的特性的基础上进行扩展,增加方法和属性(成员函数与成员变量),这样产生新的类,叫作派生类。继承呈现了…

Numpy指南:解锁Python多维数组与矩阵运算(上)

文章一览 前言一、nmupy 简介和功能二、numpy 安装三、numpy基本使用3.1、ndarray 对象3.2、基础数据结构 ndarray 数组3.3、ndarray 数组定义3.4、ndarray 数组属性计算3.5、ndarray 数组创建3.5.1 通过 array 方式创建 ndarray 数组3.5.2 通过 arange 创建数组3.5.3 通过 lin…

C++:单例模式

创建自己的对象,同时确保对象的唯一性。 单例类只能有一个实例☞静态成员static☞静态成员 必须类外初始化 单例类必须自己创建自己的唯一实例 单例类必须给所有其他对象提供这一实例 静态成员类内部可以访问 构造函数私有化☞构造函数私有外部不能创建&#x…

【火猫DOTA2】VP一号位透露队伍不会保留原阵容

1、最近VP战队的一号位选手Kiritych在直播中透露,VP战队的阵容将会有新的变动,原有的阵容将不再保留。 【目前VP战队阵容名单如下】 一号位:Kiritych 二号位:squad1x 三号位:Noticed 四号位:Antares 五号位:待定 2、Spirit的战队经理Korb3n在直播时谈到了越来越多的职业选…

FOC软件 STM32CubeMX 使用

1、安装-及相关软件版本 展示版本注意事项:keil MDK和STM32CubeMX版本至少要大于等于图中版本。 2、 Motor Profiler 5.2.0使用方法

分布式 I/O 配合高冗余 PLC,打造高效控制新典范

在当今工业自动化领域,高效且稳定的控制解决方案始终是企业追求的目标。而分布式 I/O 与高冗余 PLC 的完美配合,正如同强强联合的双子星,为工业生产带来了前所未有的高效控制体验,助力企业在激烈的市场竞争中脱颖而出。 MR30分布…