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

ops/2024/12/25 14:16:31/

目录

RTC-toc" style="margin-left:0px;">一、RTC

(1)资源介绍

        🔅简介

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

(2)STM32CubeMX 软件配置

(3)代码编写

(4)实验现象

RTC%E6%8E%A5%E5%8F%A3%E5%87%BD%E6%95%B0%E5%B0%81%E8%A3%85-toc" style="margin-left:0px;">二、RTC接口函数封装

三、踩坑日记

RTC%E6%97%B6%E9%97%B4%E8%AF%BB%E5%8F%96%E9%97%AE%E9%A2%98-toc" style="margin-left:40px;">(1)RTC时间读取问题

RTC%E5%88%86%E9%A2%91%E7%B3%BB%E6%95%B0%E4%BF%AE%E6%94%B9%E9%97%AE%E9%A2%98-toc" style="margin-left:40px;">(2)RTC分频系数修改问题

RTC%E6%97%B6%E9%92%9F%E4%B8%8D%E5%87%86%E7%A1%AE%E9%97%AE%E9%A2%98-toc" style="margin-left:40px;">(3)RTC时钟不准确问题


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_{<a class=RTCCLK}}{PREDIV\_A+1}" class="mathcode" src="https://latex.csdn.net/eq?f_%7BCK%5C_%20APRE%7D%3D%5Cfrac%7Bf_%7BRTCCLK%7D%7D%7BPREDIV%5C_A&plus;1%7D" />

f_{CK\_SPRE}=\frac{f_{<a class=RTCCLK}}{\left ( PREDIV\_S+1 \right )\times \left ( PREDIV\_A+1 \right )}" class="mathcode" src="https://latex.csdn.net/eq?f_%7BCK%5C_SPRE%7D%3D%5Cfrac%7Bf_%7BRTCCLK%7D%7D%7B%5Cleft%20%28%20PREDIV%5C_S&plus;1%20%5Cright%20%29%5Ctimes%20%5Cleft%20%28%20PREDIV%5C_A&plus;1%20%5Cright%20%29%7D" />

        但是,在蓝桥杯物联网竞赛实训平台上,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%E6%8E%A5%E5%8F%A3%E5%87%BD%E6%95%B0%E5%B0%81%E8%A3%85">二、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;}}}}
}

三、踩坑日记

RTC%E6%97%B6%E9%97%B4%E8%AF%BB%E5%8F%96%E9%97%AE%E9%A2%98">(1)RTC时间读取问题

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

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

        HAL_RTC_GetTime(&hrtc, &now_time, RTC_FORMAT_BIN);

        HAL_RTC_GetDate(&hrtc, &now_date, RTC_FORMAT_BIN);

RTC%E5%88%86%E9%A2%91%E7%B3%BB%E6%95%B0%E4%BF%AE%E6%94%B9%E9%97%AE%E9%A2%98" style="text-align:justify;">(2)RTC分频系数修改问题

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

        PREDIV_A = 124;

        PREDIV_S = 295;

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

        PREDIV_A = 127;

        PREDIV_S = 290;

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

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

RTC%E6%97%B6%E9%92%9F%E4%B8%8D%E5%87%86%E7%A1%AE%E9%97%AE%E9%A2%98" style="text-align:justify;">(3)RTC时钟不准确问题

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


http://www.ppmy.cn/ops/144861.html

相关文章

Rasa框架的优点和缺点

优点 1. 开源和免费 Rasa 是开源的&#xff0c;无需支付许可费用&#xff0c;可自由下载和修改源码&#xff0c;适合预算有限或需要定制化解决方案的团队。企业可以完全掌控自己的对话系统&#xff0c;无需依赖外部服务。 2. 数据隐私和安全 Rasa 支持完全本地部署&#xf…

【华为OD-E卷-木板 100分(python、java、c++、js、c)】

【华为OD-E卷-木板 100分&#xff08;python、java、c、js、c&#xff09;】 题目 小明有 n 块木板&#xff0c;第 i ( 1 ≤ i ≤ n ) 块木板长度为 ai。 小明买了一块长度为 m 的木料&#xff0c;这块木料可以切割成任意块&#xff0c;拼接到已有的木板上&#xff0c;用来加…

决策树(理论知识1)

目录 何为决策树决策树的组成决策树的构建 何为决策树 决策树(Decision Tree)是一种分类和回归方法&#xff0c;是基于各种情况发生的所需条件构成决策树&#xff0c;以实现期望最大化的一种图解法。由于这种决策 分支画成图形很像一棵树的枝干&#xff0c;故称决策树。它的运…

《解锁 Python 数据分析的强大力量》

《 解锁 Python 数据分析的强大力量》 一、Python 数据分析的崛起二、Python 数据分析基础&#xff08;一&#xff09;编程基础&#xff08;二&#xff09;数据分析相关库 三、数据分析流程全解析&#xff08;一&#xff09;数据获取&#xff08;二&#xff09;数据存储&#x…

tcp 的重传,流量控制,拥塞控制

tcp 的重传解决了什么问题tcp的几种重传机制分别解决什么问题?方案 1: 超时重传方案2: 快速重传选择性确认(sack)d-sack(重复接收) 滑动窗口:累计应答 流量控制解决什么问题?如何做的?问题1: 那如果第一次发送的数据都大于缓冲区的大小怎么办?问题2: 如果剩余大小为0会发生…

XILINX平台LINUX下高速ADC08060驱动

前置调研 原理图 AXI-FULL时序 由于项目需要实时性高&#xff0c;采用AXI-FULL接口ADC IP作为master端写入DDR中 引用&#xff1a; AXI_02 AXI4总线简介&#xff08;协议、时序&#xff09;_axi4总线时序-CSDN博客 AXI总线的访问 在ARM架构中&#xff0c;访问I/O地址通常通…

nacos-服务发现注册

服务发现注册分为三个角色&#xff1a;服务注册中心、服务提供者、服务消费者 服务注册中心&#xff1a;为服务提供者和消费者提供一个空间&#xff0c;服务提供者将自身服务注册到注册中心&#xff0c;仅对外暴露接口&#xff0c;服务消费者在将自身注册到注册中心的时候也会获…

React 前端框架简介

React 前端框架简介 React 是一个高效、灵活且开源的 JavaScript 库&#xff0c;用于构建用户界面 (UI)。 它专注于 视图层&#xff0c;通常与其他工具结合使用来开发复杂的前端应用。 为什么选择 React&#xff1f; 轻量灵活&#xff1a;仅负责视图层&#xff0c;适配多种框…