stm32-RTC时实时钟


1. 时间戳的基本概念

  • 定义
    时间戳是一个表示时间的标记,它通常以数字的形式出现,代表某一时刻距离参考时刻的时间差。最常见的是 Unix 时间戳,它表示从1970年1月1日 00:00:00 UTC 到某个时刻所经过的秒数(或毫秒、微秒等)。

  • 表示方式

    • 秒级时间戳:常见于 Unix 系统中,一个整数表示经过的秒数。
    • 毫秒级或微秒级时间戳:精度更高,用于需要更精确时间测量的场景,比如事件记录或高频数据采集。

以下是常用的时间戳转换库函数在头文件<time.h>里面


#include <stdio.h>
#include <time.h>
time_t time_cnt;
struct tm time_data;
int main(void)
{time_cnt=time(NULL);printf("%d\n",time_cnt);time_data=*localtime(&time_cnt);printf("%d\n",time_data.tm_year +1900);printf("%d\n",time_data.tm_mon +1);printf("%d\n",time_data.tm_mday );printf("%d\n",time_data.tm_min);printf("%d\n",time_data.tm_sec);return 0;
}

2. 时间戳的用途

  • 事件记录
    在日志系统中,每个事件都会带有一个时间戳,用于记录事件发生的具体时间。这对于调试、监控和安全审计非常重要。

  • 数据同步
    在分布式系统中,时间戳用于协调数据的顺序和版本控制,确保数据一致性。

  • 数据库操作
    数据库中常用时间戳来记录记录的创建时间和更新时间,这有助于数据管理和历史追溯。

  • 通信协议
    在网络通信和数据传输中,时间戳可以用来测量延迟、同步时间以及进行排序处理。

  • 多媒体应用
    在音视频流媒体中,时间戳用于标识帧的顺序和播放时间,确保音视频同步。


3. 时间戳的特点

  • 唯一性和连续性
    时间戳通常是单调递增的,能确保在同一系统中每个事件都有一个唯一的时间标记。

  • 时区独立性
    例如 Unix 时间戳通常使用 UTC 表示,不受时区影响,因此便于跨地域同步和比较。

  • 精度和分辨率
    时间戳的精度可以根据需求调整,从秒到微秒不等。高精度时间戳在需要精确测量时间间隔的应用中非常关键。


4. 时间戳的实现

  • Unix 时间戳
    通常表示为从1970年1月1日 00:00:00 UTC到当前时刻的秒数。例如,时间戳 1610000000 表示某个具体的时间点。

  • 数据库时间戳
    许多数据库系统使用内置的时间戳数据类型,如 SQL Server 的 timestamp(注意,SQL Server 的 timestamp 现已被称为 rowversion),以及 MySQL 中的 TIMESTAMP 类型,用于记录和跟踪记录变化。

  • 硬件计时器
    在嵌入式系统中,MCU 内部常见定时器模块可以生成时间戳,用于事件捕获和测量时间间隔。


5. 时间戳的转换

  • 从时间戳转换为日期
    开发者可以将时间戳转换为人类可读的日期和时间格式,常用编程语言都提供了相关函数。例如,在 C 语言中可以使用 localtime()strftime() 函数;在 Python 中使用 datetime.fromtimestamp() 等。

  • 从日期转换为时间戳
    同样,也可以将具体的日期和时间转换为对应的时间戳,以便进行计算和存储。


6. 实际应用中的注意点

  • 时钟同步
    在分布式系统中,不同设备的系统时钟可能存在偏差,因此常用 NTP(网络时间协议)来同步各设备的时钟,以确保时间戳的一致性。

  • 精度要求
    根据应用需求选择合适的时间戳精度。对于普通的事件记录,秒级时间戳通常足够;对于高精度测量(如音视频同步、实时数据采集),则需要毫秒甚至微秒级的时间戳。

  • 存储和传输
    时间戳在存储时通常为整数,传输时可以采用 JSON、XML 或二进制格式表示,确保数据在不同系统间一致性。

总结

时间戳是用于标识特定时间点的重要工具,广泛应用于日志记录、数据同步、数据库管理和实时系统中。它的主要特点包括唯一性、时区独立性和可调精度。正确理解和使用时间戳对于设计和实现各种时间敏感的应用非常重要。

STM32 BKP(Backup Registers)详解:备份寄存器的原理与应用

1. 什么是BKP寄存器?
BKP(Backup Registers)是STM32微控制器中的一组特殊寄存器,位于备份域(Backup Domain)。这些寄存器的特点是即使在主电源(VDD)掉电的情况下,只要备用电池(VBAT)存在,寄存器中的数据仍然可以保留。因此,BKP寄存器通常用于存储关键数据,如RTC校准值、系统配置参数或状态标志。

1.1 BKP寄存器的主要特点
数据保持:在VDD掉电时,只要VBAT存在,数据不会丢失。
16位宽度:每个BKP寄存器为16位,可以存储任意数据。
 数量有限:不同型号的STM32芯片,BKP寄存器的数量不同(通常为10~20个)。
-独立时钟域:BKP寄存器位于备份域,与主电源域分离。

---

 2. BKP寄存器的硬件结构

2.1 备份域(Backup Domain)
备份域是STM32中一个独立的电源域,包括以下部分:
BKP寄存器:用于存储用户数据。
RTC(实时时钟):提供时间和日期功能。
Tamper检测:用于检测外部篡改事件(部分型号支持)。
电源控制寄存器(PWR_CR):通过DBP位控制对备份域的写访问。

2.2 电源管理
备份域的电源由以下两种电源提供:
VDD:主电源,正常运行时使用。
VBAT:备用电池,当VDD掉电时,VBAT为备份域供电。

 2.3 写保护机制
为了防止误操作,STM32对BKP寄存器进行了写保护。要写入BKP寄存器,必须先使能PWR_CR寄存器中的DBP(Disable Backup Protection)位。

---

 3. BKP寄存器的应用场景

 3.1 RTC校准
BKP寄存器可以存储RTC的校准值,确保在系统复位或掉电后,RTC仍然能够保持准确的时间。

3.2 系统配置存储
在系统启动时,可以从BKP寄存器中读取配置参数(如工作模式、用户设置等),从而实现配置的持久化。

 3.3 状态标志存储
BKP寄存器可以用于存储系统状态标志,例如:
- 系统是否经历了异常复位。
- 用户是否进行了某些操作(如按下某个按钮)。

 3.4 数据备份
在关键应用中,BKP寄存器可以用于备份重要数据,确保在意外掉电时数据不会丢失。

这里的中小产品为20字节是在1-10的数据寄存器中每个数据寄存器占2个字节,另外大容量产品同样每个数据寄存器占2字节

4. BKP寄存器的使用方法

 4.1 初始化步骤
在使用BKP寄存器之前,需要进行以下初始化操作:
1. 使能PWR和BKP外设时钟。
2. 使能备份域的写访问(设置DBP位)。
3. 配置BKP寄存器(可选:配置Tamper检测或RTC)。

4.2 代码示例
以下是一个完整的代码示例,展示如何初始化BKP寄存器并读写数据:

```c
#include "stm32f10x.h"void BKP_Init(void) {// 1. 使能PWR和BKP外设时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);// 2. 使能备份域的写访问PWR_BackupAccessCmd(ENABLE);// 3. 配置BKP寄存器(可选)// 例如:写入一个初始值到BKP_DR1BKP_WriteBackupRegister(BKP_DR1, 0x1234);
}uint16_t BKP_ReadData(void) {// 读取BKP寄存器的值return BKP_ReadBackupRegister(BKP_DR1);
}void BKP_WriteData(uint16_t data) {// 写入数据到BKP寄存器BKP_WriteBackupRegister(BKP_DR1, data);
}int main(void) {// 初始化BKPBKP_Init();// 写入数据BKP_WriteData(0x5678);// 读取数据uint16_t data = BKP_ReadData();while (1) {// 主循环}
}
```### 4.3 代码解析
- **RCC_APB1PeriphClockCmd**:使能PWR和BKP外设的时钟。
- **PWR_BackupAccessCmd**:使能备份域的写访问。
- **BKP_WriteBackupRegister**:向BKP寄存器写入数据。
- **BKP_ReadBackupRegister**:从BKP寄存器读取数据。---

 5. 注意事项

 5.1 电源管理
- 确保VBAT引脚连接了备用电池,否则在VDD掉电时,BKP寄存器的数据会丢失。
- 如果不需要备份功能,可以将VBAT接地。

 5.2 写保护
- 在写入BKP寄存器之前,必须使能DBP位。
- 写入完成后,可以禁用DBP位以防止误操作。

5.3 寄存器数量
- 不同型号的STM32芯片,BKP寄存器的数量可能不同。请参考具体型号的数据手册。

 5.4 温度检测(Tamper)
- 部分STM32型号支持Tamper检测功能,可以用于检测外部篡改事件。如果使用此功能,需要额外配置。

 6. 总结
STM32的BKP寄存器是备份域的重要组成部分,能够在系统复位或掉电时保存关键数据。通过合理使用BKP寄存器,可以实现RTC校准、系统配置存储、状态标志备份等功能。在实际应用中,需要注意电源管理、写保护机制以及寄存器数量的限制。BKP本质上还是RAM,是数据已丢失的内存,在没有VBAT备用电源供电后数据仍然会进行丢失.但是如果有VBAT供电的情况下,VCC上电复位都不会造成BKP数据存储的丢失.

STM32 RTC 详细资料

1. RTC 概述

RTC(Real-Time Clock) 是 STM32 微控制器中的一个专用外设,用于提供准确的时间和日期功能。RTC 能够在系统断电(通过备用电池供电)时继续运行,因此适用于需要长时间持续计时的场合,如日历、定时器、闹钟等应用。

2. RTC 的特点

  • 低功耗:RTC 通常工作在低功耗模式下,并且由独立的低速晶振(LSE)或内部低速时钟(LSI)驱动,功耗非常低。
  • 独立备份域:RTC 通常属于备份域(Backup Domain),即使主系统断电,RTC 及其相关寄存器依然能够通过备用电池保持运行。
  • 丰富的寄存器:RTC 提供多组寄存器来存储时间、日期、闹钟、定时器和校准信息,如 RTC_DR(日期寄存器)、RTC_TR(时间寄存器)、RTC_CR(控制寄存器)、RTC_ALRM(闹钟寄存器)等。
  • 校准功能:RTC 可以进行校准,修正由于晶振误差引起的时间偏差。
  • 多种唤醒源:RTC 可以配置多种唤醒方式,比如闹钟中断、周期性唤醒等,为低功耗应用提供灵活支持。

3. RTC 的工作原理

  1. 时钟源

    • RTC 的时钟源通常有两种选择:外部低速晶振(LSE,一般为 32.768 kHz)和内部低速振荡器(LSI,约 40 kHz)。
    • LSE 优点是精度高,适用于需要高精度计时的应用,作为主流RTC时钟源,在VDD断电后能够通过VBAT备用供电 ,LSI 虽然精度较低,但成本低、集成度高,适用于对时间要求不那么严格的场合一般作为备用时钟源,频率为40kh,而且不存在备用电源VBAT供电,VDD断电后不能备用供电
  2. 计数方式

    • RTC 通过内部计数器不断累加时钟脉冲来计时。计数器通常分为秒计数器分秒、小时、日期、月份和年份寄存器
    • 当计数器达到预设值时,会自动进位,例如 59 秒进 1 分,23 小时进 1 天等。
  3. 备份域

    • RTC 与其他备份寄存器在同一电源域内,通常由备用电池供电。这样即使主系统电源断电,RTC 仍能持续运行,保持时间信息。
  4. 中断与唤醒

    • RTC 可配置定时唤醒中断、闹钟中断等。比如,当设置的闹钟时间到达时,RTC 会触发中断,使系统从低功耗模式中唤醒,执行相应任务。
    • 1. RTC概述

      RTC是STM32中用于计时和日历功能的模块,具有以下特点:

    • 独立供电:由VBAT引脚供电,即使主电源(VDD)掉电,RTC仍可继续运行。

    • 低功耗:在低功耗模式下仍能正常工作。

    • 日历功能:支持年、月、日、星期、时、分、秒的计时。

    • 闹钟功能:可以设置闹钟,在特定时间触发中断。

    • 周期性唤醒:可以配置周期性唤醒定时器,用于低功耗应用。


    • 2. RTC寄存器详解

      RTC的功能通过一组寄存器实现,以下是主要寄存器的功能说明:

      2.1 RTC控制寄存器(RTC_CR)

    • 功能:配置RTC的工作模式和控制功能。

    • 重要位

      • BYPSHAD:绕过影子寄存器(直接访问计数器)。

      • FMT:时间格式(0:24小时制,1:12小时制)。

      • OSEL:输出选择(选择RTC输出信号)。

      • ALRAE:闹钟A使能。

      • ALRBE:闹钟B使能。

    • 2.2 RTC预分频器寄存器(RTC_PRER)

    • 功能:配置RTC的时钟分频器。

    • 重要位

      • PREDIV_A:异步预分频器(通常设置为127)。

      • PREDIV_S:同步预分频器(通常设置为255)。

    • 2.3 RTC时间寄存器(RTC_TR)

    • 功能:存储当前时间(时、分、秒)。

    • 重要位

      • HT/HT[1:0]:小时的十位。

      • HU/HU[3:0]:小时的个位。

      • MNT/MNT[2:0]:分钟的十位。

      • MNU/MNU[3:0]:分钟的个位。

      • ST/ST[2:0]:秒的十位。

      • SU/SU[3:0]:秒的个位。

      • PM:12小时制下的上午/下午标志。

    • 2.4 RTC日期寄存器(RTC_DR)

    • 功能:存储当前日期(年、月、日、星期)。

    • 重要位

      • YT/YT[1:0]:年的十位。

      • YU/YU[3:0]:年的个位。

      • MT:月的十位。

      • MU:月的个位。

      • DT/DT[1:0]:日的十位。

      • DU/DU[3:0]:日的个位。

      • WDU[2:0]:星期几。

    • 2.5 RTC闹钟寄存器(RTC_ALRMAR/RTC_ALRMBR)

    • 功能:设置闹钟时间。

    • 重要位

      • MSKx:屏蔽位(用于选择闹钟比较的字段)。

      • ST/SU:秒。

      • MNT/MNU:分钟。

      • HT/HU:小时。

      • DT/DU:日期。

    • 2.6 RTC状态寄存器(RTC_ISR)

    • 功能:指示RTC的状态。

    • 重要位

      • ALRAF:闹钟A标志。

      • ALRBF:闹钟B标志。

      • RSF:寄存器同步标志。

      • INITS:初始化状态标志。

      • SHPF:移位操作标志。

    • 2.7 RTC写保护寄存器(RTC_WPR)

    • 功能:用于解除RTC寄存器的写保护。

    • 用法:写入特定的密钥(0xCA,0x53)以解除写保护。

      4. RTC的常见应用

      4.1 闹钟功能

      通过配置RTC_ALRMAR或RTC_ALRMBR寄存器,可以设置闹钟时间,并在闹钟触发时产生中断。

      4.2 周期性唤醒

      通过配置RTC_WUTR寄存器,可以设置周期性唤醒定时器,用于低功耗应用。

      4.3 时间戳功能

      部分STM32型号支持时间戳功能,可以记录外部事件的发生时间。

    • 在STM32微控制器中,实时时钟(RTC)通常有三个主要的中断,分别是秒中断(Second interrupt)、闹钟中断(Alarm interrupt)和唤醒中断(Wakeup interrupt)。以下是对这三个中断的详细介绍:

    • 秒中断(Second interrupt)
       功能描述:秒中断是RTC最基本的中断之一,它以秒为周期触发。当RTC的计数器每秒钟更新一次时,如果秒中断使能,就会产生一个中断信号,通知微控制器时间过去了一秒。
      应用场景:常用于需要精确到秒的定时任务,例如实时数据记录,以每秒为间隔记录传感器数据;也可用于实现简单的秒表功能,或者作为系统中其他定时操作的基本时间参考,如每隔一定秒数进行一次系统状态检查等。

    •  闹钟中断(Alarm interrupt)
       功能描述:闹钟中断允许用户设置一个特定的时间点,当RTC的时间计数到达这个设定的时间时,就会触发闹钟中断。用户可以通过配置RTC的闹钟寄存器来设置年、月、日、时、分、秒等时间参数,当RTC时间与设置的闹钟时间匹配时,产生中断信号。
      应用场景:广泛应用于定时提醒功能,比如在智能手表中设置定时提醒事件,在工业控制系统中设置定时报警,提醒工作人员进行设备维护或处理特定任务等。还可用于定时启动或停止某些设备或任务,如定时启动数据采集、定时关闭显示屏以节省能源等。

    • 唤醒中断(Wakeup interrupt)
      能描述:唤醒中断主要用于将微控制器从低功耗模式中唤醒。RTC可以设置一个唤醒周期,每隔一定的时间间隔产生一个唤醒中断信号,使微控制器从低功耗睡眠状态恢复到正常运行状态。唤醒周期可以通过配置RTC的唤醒寄存器来设置,通常可以设置为几毫秒到数小时不等。
      应用场景:在电池供电的设备中,为了节省电能,微控制器经常会进入低功耗模式。唤醒中断可以让设备在需要的时候定时唤醒,进行数据处理、通信等操作,然后再进入低功耗模式,从而有效降低设备的整体功耗,延长电池使用寿命。例如,在物联网传感器节点中,传感器可以定期唤醒进行数据采集和发送,然后继续进入低功耗状态等待下一次唤醒。


      5. 注意事项

    • 时钟源选择:RTC的时钟源可以是LSE(外部低速晶振)、LSI(内部低速振荡器)或HSE(外部高速晶振)先择完时钟信号后要等待时钟信号标志位RCC_IT_HSIRDY置1才能进行后续的RTC时钟选择

    • 写保护:在修改RTC寄存器之前,必须解除写保护。

    • 寄存器同步:在读取RTC寄存器之前,需要等待同步完成也就是需要调用时钟同步等待函数,同时还要调用等待函数等待上一步操作完成,防止出现数据同步的BUG.

4. RTC 配置及使用方法

4.1 使用 STM32 标准库(HAL 或 StdPeriph)的基本流程

  1. 使能 RTC 时钟

    • 通过 RCC 相关函数使能 RTC 及其备用域时钟。通常需要先使能 PWR 和 BKP 时钟,然后解除备份域的写保护。
  2. 配置时钟源

    • 选择 LSE 或 LSI 作为 RTC 的时钟源,并等待时钟稳定。
  3. 初始化 RTC

    • 配置 RTC 的时间、日期、闹钟和校准参数。使用对应的库函数初始化 RTC 模块以以及配置PRL(重装载计数器),DIV(余数计数器),CNT(32位计数器),ALR(32闹钟计数器)等相关参数
  4. 配置中断或唤醒

    • 根据应用需求,配置 RTC 的唤醒中断或闹钟中断。
4.2 示例代码(基于 STM32 标准外设库)

下面是一个简单的 RTC 初始化示例代码,展示如何配置 RTC,设置时间并使能闹钟中断。注意:不同的 STM32 系列可能在 RTC 配置上略有不同,具体请参考相应的数据手册和库文件。

#include "stm32f10x.h"void RTC_Config(void) {RTC_InitTypeDef RTC_InitStructure;RTC_TimeTypeDef RTC_TimeStructure;RTC_DateTypeDef RTC_DateStructure;// 使能 PWR 时钟并允许访问备份寄存器RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);PWR_BackupAccessCmd(ENABLE);// 使能 LSE 时钟RCC_LSEConfig(RCC_LSE_ON);while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);// 将 RTC 时钟源设置为 LSERCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);// 使能 RTC 时钟RCC_RTCCLKCmd(ENABLE);// 等待 RTC 寄存器同步RTC_WaitForSynchro();// 配置 RTC 时钟RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;RTC_InitStructure.RTC_AsynchPrediv = 0x7F;   // 异步预分频值RTC_InitStructure.RTC_SynchPrediv = 0x00FF;    // 同步预分频值,根据LSE 32.768kHz来计算if (RTC_Init(&RTC_InitStructure) == ERROR) {// 初始化失败处理while (1);}// 设置时间:例如 12:34:56RTC_TimeStructure.RTC_Hours = 12;RTC_TimeStructure.RTC_Minutes = 34;RTC_TimeStructure.RTC_Seconds = 56;RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);// 设置日期:例如 2025-03-02,星期一RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Monday;RTC_DateStructure.RTC_Month = RTC_Month_March;RTC_DateStructure.RTC_Date = 2;RTC_DateStructure.RTC_Year = 25;RTC_SetDate(RTC_Format_BIN, &RTC_DateStructure);
}int main(void) {SystemInit();RTC_Config();while(1) {// 在这里可以添加代码读取 RTC 时间、日期,并显示或其他操作}
}

5. RTC 在低功耗模式下的应用

  • 待机模式(Standby Mode):在待机模式下,RTC 是唯一保持运行的外设,用于计时、闹钟唤醒等。
  • 唤醒中断:RTC 可以配置为在特定时间触发唤醒中断,从低功耗模式中唤醒系统继续运行。

6. 参考与扩展

  • 参考 STM32 数据手册:详细了解 RTC 模块的寄存器配置、时钟分频值、闹钟设置等。
  • STM32 HAL 库:新版 STM32 的 HAL 库也提供了 RTC 配置函数,可以参考 HAL_RTC_Init()、HAL_RTC_SetTime()、HAL_RTC_SetDate() 等函数进行配置。

总结

  • RTC 模块 提供准确的时间和日期管理,并能在低功耗模式下持续运行。
  • RTC 使用 外部低速晶振(LSE)内部低速振荡器(LSI) 作为时钟源,并具有备份域,能在系统断电时保持时间信息。
  • 通过配置预分频器和同步预分频器,可以根据所选时钟源实现准确的时间计数。
  • RTC 可以配置闹钟和唤醒中断,适用于定时任务和低功耗系统唤醒。

项目1:使用BKP外设进行数据读写操作,以及在VCC掉电后由VBTA提供备用电源防止数据不丢失

操作:1使能BKP和PWR的时钟

2使能PWR_CR 的DPB位开启BKP的数据读写

3对BKP内部备份数据寄存器进行写入数据并读取数据

4分别观察在VCC掉电后BKP的数据情况以及BVAT掉电后的数据情况

int main(void){OLED_Init();key_Init();OLED_ShowString (1,1,"w:");OLED_ShowString (2,1,"R:");  //开启pwr和bkp的时钟APB1RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR| RCC_APB1Periph_BKP,ENABLE);PWR_BackupAccessCmd(ENABLE);//BKP_WriteBackupRegister(BKP_DR1,0x1234);OLED_ShowHexNum (1,1,BKP_ReadBackupRegister(BKP_DR1),4);

通过按键来优先实现BKP对数据的读写操作

 //开启pwr和bkp的时钟APB1RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR| RCC_APB1Periph_BKP,ENABLE);PWR_BackupAccessCmd(ENABLE);while(1){keynumber = Get_keynum();if(keynumber==1){arrayWrite[0]++;arrayWrite[1]++;BKP_WriteBackupRegister(BKP_DR1,arrayWrite[0]);BKP_WriteBackupRegister(BKP_DR2, arrayWrite[1]);OLED_ShowHexNum (1,3,arrayWrite[0],4);OLED_ShowHexNum (1,8,arrayWrite[1],4);}arrayRead[0]= BKP_ReadBackupRegister(BKP_DR1);arrayRead[1]= BKP_ReadBackupRegister(BKP_DR2);OLED_ShowHexNum (2,3,arrayRead[0],4);OLED_ShowHexNum (2,8,arrayRead[1],4);}}

项目二:利用RTC外设进行时间计时

操作:1开启PWR和BKP的时钟并同时设置PWR_CR的DBP寄存器开启对BKP对RTC的访问

2开启时钟源(主要是外部低速时钟LSE,有时作为备用也可调用内部低速时钟LSI)最后还需要等待RCC_LSERDY标志位置1即时钟启动完成

3进行RTC时钟选择,并进行时钟使能,

4等待时钟同步和上次一次操作完成

5 设置分频值(分频系数是32768-1)自动进入计数配置模式和闹钟配置模式

6设置CNT的初始值

7设置日次传入参数计算秒数最终读取数组中的日期

int main(void){OLED_Init();Rtc_Config();OLED_ShowString (1,1,"Data:xxxx-xx-xx");OLED_ShowString (2,1,"Time:xxxx-xx-xx");OLED_ShowString (3,1,"Cnt:xxxx-xx-xx");while(1){myRTC_ReadTime();OLED_ShowNum (1,6,MyRtc_Time [0],4);OLED_ShowNum (1,6,MyRtc_Time [1],2);OLED_ShowNum (1,6,MyRtc_Time [2],2);OLED_ShowNum (1,6,MyRtc_Time [3],2);OLED_ShowNum (1,6,MyRtc_Time [4],2);OLED_ShowNum (1,6,MyRtc_Time [5],2);OLED_ShowNum (3,6,RTC_GetCounter (),10);}}#include "stm32f10x.h"                  // Device head
#include "rtc.h"
#include <time.h>
uint16_t MyRtc_Time[]={2023,1,1,23,59,55};
void  Rtc_Config()
{//开启pwr和bkp的时钟APB1RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR| RCC_APB1Periph_BKP,ENABLE);PWR_BackupAccessCmd(ENABLE);//开启BKP和RTC的访问RCC_LSEConfig(RCC_LSE_ON);while(	RCC_GetITStatus(RCC_IT_HSIRDY)!=SET);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);RCC_RTCCLKCmd(ENABLE );RTC_WaitForSynchro();RTC_WaitForLastTask();RTC_SetPrescaler(32768-1);RTC_WaitForLastTask();RTC_SetCounter(1672588795);//设置初始时间也就是CNT的值}
void RTC_Set_time()
{time_t  time_cnt;struct tm time_data;time_data.tm_year =MyRtc_Time [0]-1900;time_data.tm_mon =MyRtc_Time  [1]-1;time_data.tm_mday  =MyRtc_Time[2];time_data.tm_hour =MyRtc_Time [3];time_data.tm_min  =MyRtc_Time [4];time_data.tm_sec  =MyRtc_Time [5];time_cnt=mktime (&time_data);RTC_SetCounter (time_cnt );RTC_WaitForLastTask();
}
void myRTC_ReadTime()
{time_t time_cnt;struct tm time_data;time_cnt=	RTC_GetCounter();time_data=*localtime (&time_cnt);MyRtc_Time [0]=      time_data.tm_year+1900;MyRtc_Time[1]=     time_data.tm_mon+1;MyRtc_Time[2]=      time_data.tm_mday;MyRtc_Time [3]=    time_data.tm_hour;MyRtc_Time [4]=    time_data.tm_min;MyRtc_Time [5]=    time_data.tm_sec;}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统安全】任务1:操作系统部署

目录 一、VMware Workstation Pro 17 部署 二、VMware Workstation 联网方式 三、VMware 虚拟机安装流程 四、操作系统介绍 五、Kali 操作系统安装 六、Windows 系统安装 七、Windows 系统网络配置 八、Linux 网络配置 CSDN 原创主页&#xff1a;不羁https://blog.csd…

JavaScript读取当前URL字符串中参数的两种方法

方法1 使用location.search属性&#xff0c;location.search属性会返回URL的问号后面的参数字符串 const querystr window.location.search; const params new URLSearchParams(querystr); //例如&#xff1a;URL为 index.html?Id123&Nametest //要获取参数名Id的值…

DeepSeek-进阶版部署(Linux+GPU)

前面几个小节讲解的Win和Linux部署DeepSeek的比较简单的方法&#xff0c;而且采用的模型也是最小的&#xff0c;作为测试体验使用是没问题的。如果要在生产环境使用还是需要用到GPU来实现&#xff0c;下面我将以有一台带上GPU显卡的Linux机器来部署DeepSeek。这里还只是先体验单…

MySQL的安装与建表

目录 一&#xff0c;MySQL 安装部署 1.1 版本及下载 1.2安装过程 二&#xff0c;数据库的建立 1&#xff0c;employees 表的建立 2&#xff0c;orders表的建立​ 3&#xff0c;involces表的建立 一&#xff0c;MySQL 安装部署 1.1 版本及下载 MySQL官网地址&#xff1a…

Spring 框架学习

技术体系结构 总体技术体系 单一架构 一个项目&#xff0c;一个工程&#xff0c;导出为一个 war 包&#xff0c;在一个 Tomcat 上运行&#xff0c;也叫 all in one。 单一架构&#xff0c;项目主要应用技术框架为&#xff1a;Spring、SpringMVC 、Mybatis。 分布式架构 一个…

G-Star 公益行起航,挥动开源技术点亮公益!

公益组织&#xff0c;一直是社会温暖的传递者&#xff0c;但在数字化浪潮中&#xff0c;也面临着诸多比大众想象中复杂的挑战&#xff1a;项目管理如何更高效&#xff1f;志愿者管理又该如何创新&#xff1f;宣传推广怎么才能更有影响力&#xff1f;内部管理和技术支持又该如何…

STM32-Unix时间戳

一&#xff1a;什么是时间戳 Unix时间戳&#xff08;Unix Timestamp&#xff09;是一个计数器数值&#xff0c;这个数值表示的是一个从1970年1月1日0时0分0秒开始到现在所经过的秒数&#xff0c;不考虑闰秒。 时间戳存储在一个秒计数器里&#xff0c;秒计数器为32位/64位的整…

zsh: command not found: adb 报错问题解决

哈喽小伙伴们大家好&#xff0c;我是小李&#xff0c;今天&#xff0c;我满怀信心想要在本地跑一下pda,然而&#xff0c; what? 居然报错了&#xff01;&#xff01;别逗我啊&#xff01; 好吧&#xff0c;究其原因&#xff1a;没有配置好sdk 那就配呗。 首先&#xff0c;…

嵌入式八股C语言---面向对象篇

面向对象与面向过程 面向过程 就是把整个业务逻辑分成多个步骤,每步或每一个功能都可以使用一个函数来实现面向对象 对象是类的实例化,此时一个类就内部有属性和相应的方法 封装 在C语言里实现封装就是实现一个结构体,里面包括的成员变量和函数指针,然后在构造函数中,为结构体…

Linux_17进程控制

前提回顾&#xff1a; 页表可以将无序的物理地址映射为有序的; 通过进程地址空间&#xff0c;避免将内存直接暴漏给操作系统&#xff1b; cr3寄存器存放的有当前运行进程的页表的物理地址&#xff1b; 一、查看命令行参数和环境变量的地址 因为命令行参数和环境变量都是字符…

NVIDIA k8s-device-plugin源码分析与安装部署

在《kubernetes Device Plugin原理与源码分析》一文中&#xff0c;我们从源码层面了解了kubelet侧关于device plugin逻辑的实现逻辑&#xff0c;本文以nvidia管理GPU的开源github项目k8s-device-plugin为例&#xff0c;来看看设备插件侧的实现示例。 一、Kubernetes Device Pl…

MySql索引下推(ICP)是什么?有什么用?

目录 基本介绍为什么需要索引下推&#xff1f;未引入ICP&#xff08;x&#xff09;引入ICP&#xff08;√&#xff09; 如何指导sql优化适用场景sql优化 基本介绍 索引下推&#xff08;Index Condition Pushdown, ICP&#xff09;&#xff0c;是MySQL5.6 引入的优化技术&#…

用户可免费体验!国家超算互联网平台上线阿里开源推理模型接口服

近日&#xff0c;国家超算互联网平台上线阿里巴巴开源推理模型QwQ-32B API接口服务&#xff0c;现在用户可获得免费的100万Tokens。基于国产深算智能加速卡以及全国一体化算力网&#xff0c;平台支持海量用户便捷调用QwQ-32B、DeepSeek-R1等国产开源大模型的接口服务。 了解QwQ…

大数据学习(63)- Zookeeper详解

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91e; &#x1f…

【蓝桥杯python研究生组备赛】003 贪心

题目1 股票买卖 给定一个长度为 N 的数组&#xff0c;数组中的第 i 个数字表示一个给定股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;。 注意&#xff1a;你不能同时参与多笔交易&…

mmdet3d.models.utils的clip_sigmoid理解

Sigmoid 函数 标准的 sigmoid 函数定义为&#xff1a; 容易得出结论&#xff1a; 取值范围(0, 1) clip_sigmoid 是在标准的 sigmoid 函数基础上进行 裁剪&#xff08;clip&#xff09;&#xff0c;即对 sigmoid 输出的结果加以限制&#xff0c;避免其超出特定范围。 import …

侯捷 C++ 课程学习笔记:进阶语法之lambda表达式(二)

侯捷 C 课程学习笔记&#xff1a;进阶语法之lambda表达式&#xff08;二&#xff09; 一、捕获范围界定 1. 局部变量与函数参数 ​非静态局部变量&#xff1a;Lambda 所在作用域内定义的局部变量&#xff08;如函数内部的 int x&#xff09;会被完整复制其当前值。捕获后外部变…

有必要使用 Oracle 向量数据库吗?

向量数据库最主要的特点是让传统的只能基于具体值/关键字的数据检索&#xff0c;进化到了可以直接基于语义的数据检索。这在AI时代至关重要&#xff01; 回到标题问题&#xff1a;是否有必要使用 Oracle 向量数据库&#xff1f; 这实际还要取决于你的具体应用需求。 客观来讲…

论文解读 | AAAI'25 CoRA:基于大型语言模型权重的协作信息感知用于推荐

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 个人信息 作者&#xff1a;刘禹廷&#xff0c;东北大学博士生 内容简介 将协作信息融入大型语言模型&#xff08;LLMs&#xff09;是一种有前景的适应推荐任务的技…