嵌入式里的时间魔法:RTC 与 BKP 深度拆解

文章目录

  • RTC实时时钟与BKP
    • Unix时间戳
    • UTC/GMT
    • 时间戳转换
    • 时间戳转换
    • BKP简介
    • BKP基本结构
        • [1. 电池供电模块(VBAT 输入)](#1. 电池供电模块(VBAT 输入))
        • [2. 侵入检测模块(TAMPER 输入)](#2. 侵入检测模块(TAMPER 输入))
        • [3. 时钟输出模块(RTC 输出)](#3. 时钟输出模块(RTC 输出))
        • [4. 内部寄存器组](#4. 内部寄存器组)
    • RTC简介
    • RTC框图
        • [1. 硬件架构与区域划分](#1. 硬件架构与区域划分)
        • [2. 预分频器与时钟处理](#2. 预分频器与时钟处理)
        • [3. 计数计时与中断逻辑](#3. 计数计时与中断逻辑)
        • [4. 低功耗与待机特性](#4. 低功耗与待机特性)
    • RTC基本结构
    • 硬件电路
        • [1. 备用电池供电电路](#1. 备用电池供电电路)
        • [2. 外部低速晶振(LSE)电路](#2. 外部低速晶振(LSE)电路)
        • [3. 引脚功能与复用](#3. 引脚功能与复用)
        • [4. 硬件设计规范](#4. 硬件设计规范)
    • RTC操作注意事项
        • [1. 使能 BKP 和 RTC 访问(时钟与权限)](#1. 使能 BKP 和 RTC 访问(时钟与权限))
        • [2. 读取 RTC 前等待 RSF(Registers Synchronized Flag) 同步标志](#2. 读取 RTC 前等待 RSF(Registers Synchronized Flag) 同步标志)
        • [3. 写入 RTC 前进入配置模式(CNF 位 Configuration Flag)](#3. 写入 RTC 前进入配置模式(CNF 位 Configuration Flag))
        • [4. 写操作等待 RTOFF(RTC Register Transfer Ongoing Flag) 位(前次写结束)](#4. 写操作等待 RTOFF(RTC Register Transfer Ongoing Flag) 位(前次写结束))
    • [BKP 库函数介绍](#BKP 库函数介绍)
    • 实时时钟

RTC实时时钟与BKP

Unix时间戳

可以使用time.h,头文件中的函数将 时间戳转化为各种类型的时间。

UTC/GMT

UTC(协调世界时)

  1. 定义与计时基准
    • 原子钟(铯 - 133 原子振荡周期) 为计时基础,1 秒定义为 "铯 - 133 原子基态的两个超精细能级之间跃迁所对应的辐射的 9192631770 个周期的持续时间",精度极高(上千万年误差约 1 秒)。
    • 引入 闰秒机制 :当原子钟计时与地球自转(因地球自转变慢导致的计时偏差)相差超过 0.9 秒 时,通过在 UTC 时间中插入或删除 1 秒(如出现 23:59:60 或跳过 23:59:59),消除与地球自转的误差,确保时间与昼夜同步(如 2023 年未添加闰秒,最近一次闰秒为 2016 年 12 月 31 日)。
  2. 与 GMT 的关系
    • GMT(格林尼治标准时间) 是基于地球自转的天文时间 时间长之后会出现误差(以格林尼治天文台为基准),而 UTC 是更严谨的原子时标准
    • 生活场景中可视为等同 :两者在实际应用中(如手机、电脑的时区设置)差异可忽略,例如 东八区时间 既表示为 UTC+8 也表示为 GMT+8,均指比 UTC/GMT 早 8 小时的时间(如北京时间)。

时间戳转换

时间戳转换

BKP简介

  • 含义与用途 :BKP 即 backup registers,是备份寄存器,可存储用户自定义数据。
  • 电源特性 :当 VDD 主电源切断,由 VBAT 备用电池供电,系统唤醒、复位时数据不复位。VDD 供电电压 2.0 - 3.6 伏,VBAT 供电电压 1.8 - 3.6 伏。
  • 引脚定义 :VDD 相关引脚为系统主电源,正常使用时接 3.3 伏电源;VBAT 为备用电池供电引脚,使用 BKP 和 RTC 需接备用电池,电池负极与主电源负极共地。若没有外部电池,建议 VBT 引脚接到 VDD 并连接 100 纳法滤波电容。
  • 额外功能 :Temper 引脚侵入事件可清除备份寄存器内容,用于设备防拆(将该引脚与设备外壳相连当外壳被破坏时,会给引脚一个信号,该引脚将寄存器中数据清空);可输出 RTC 校准时钟、闹钟脉冲或秒脉冲,外部设备可测量校准时钟校准 RTC 误差;存储 RTC 时钟校准计数器,配合校准时钟输出功能校准 RTC。
  • 存储容量 :中容量和小容量设备里为 20 个字节,大容量和互联型设备里为 84 个字节。

BKP基本结构

1. 电池供电模块(VBAT 输入)
  • 电源特性:BKP 位于后备区域,VDD(2.0-3.6V)主电源掉电后,自动切换为 VBAT(1.8-3.6V)备用电池供电,确保数据不丢失(系统复位、唤醒时数据保持)。
  • 电路设计:无外部电池时,VBAT 可接 VDD 并串联 100nF 滤波电容(图中未体现具体电路,但逻辑上支持 VBAT 与 VDD 的电源切换)。
2. 侵入检测模块(TAMPER 输入)
  • 防拆功能:TAMPER 引脚检测到侵入事件(电平跳变)时,自动清除 BKP 数据寄存器内容(图中 "侵入检测" 模块直接对应此功能,用于设备安全防护,如防拆锁设计)。
3. 时钟输出模块(RTC 输出)
  • 功能复用:BKP 可输出 RTC 的校准时钟、闹钟脉冲或秒脉冲(图中 "时钟输出" 模块与会议中 "BKP 额外功能" 的时钟输出特性一致,支持外部设备校准 RTC 误差)。
4. 内部寄存器组
  • 数据寄存器(DRx)
    • 容量差异
      • 中 / 小容量芯片(如 STM32F103C8T6):10 个 16 位寄存器(DR1-DR10),共 20 字节(图中 DR1-DR10 明确标注)。
      • 大容量 / 互联型芯片:42 个 16 位寄存器(DR1-DR42),共 84 字节(图中 "大容量和互联型" 扩展部分,与会议内容匹配)。
    • 存储特性:寄存器数据在 VDD 掉电后由 VBAT 维持,属于掉电保持型存储器。
  • 控制 / 状态 / 校准寄存器
    • 控制寄存器:配置侵入检测使能、时钟输出模式等(如 TAMPER 触发使能)。
    • 状态寄存器:反映侵入事件状态(如 TAMPER 触发标志)。
    • RTC 时钟校准寄存器:存储 RTC 校准计数器,配合时钟输出功能校准 RTC 计时误差(图中单独列出,对应会议中 "存储 RTC 时钟校准计数器" 的描述)。

RTC简介

后面将RTC框图时,会对下面的简介进行一一验证。

RTC时钟源

  • 可以看到RTC时钟选择器 来 进行RTC时钟选择,有三种时钟源。
    • HSE 外部高速时钟 为8Mhz,要产生1hz的频率,要先进行128分频之后才能进行,时钟传输。因为时钟频率太大了。
    • LSE外部低速时钟, 可以说就是为了RTC,设计的时钟,始终频率为32.768KHz,是2的次方倍,后面进行时钟分频好操作。(一般会选择使用)
    • LSI 40Khz,也可是为RTC提供时钟源,但是主要为看门狗外设提供时钟源。

RTC框图

1. 硬件架构与区域划分
  • 后备区域(灰色模块)
    • 包含预分频器(RTC_PRL/RTC_DIV)和计数计时单元(RTC_CNT/RTC_ALR)待机时由 VBAT 供电(持续计时),与 APB1 接口(待机断电)分离,确保主电源掉电后 RTC 独立运行(匹配会议中 "VDD 断电后 VBAT 供电继续走时" 的特性)。
  • APB1 接口 :用于软件配置(如预分频值、闹钟时间),待机时断电(降低功耗)。
2. 预分频器与时钟处理
  • RTCCLK 分频 :通过RTC_PRL(重装值)和RTC_DIV(余数计数)将输入时钟(如 32.768kHz LSE)分频为1Hz(TR_CLK),驱动 32 位计数器(RTC_CNT)递增("20 位可编程预分频器适配输入时钟",实现秒级计时)。
3. 计数计时与中断逻辑
  • 32 位计数器(RTC_CNT) :存储 Unix 秒数,溢出周期约 2106 年 (触发RTC_Overflow中断, "溢出中断" 的硬件源)。
  • 闹钟比较(RTC_ALR) :与 RTC_CNT 匹配时触发RTC_Alarm中断,可以唤醒待机设备 (通过WKP_STDBY逻辑, "闹钟唤醒设备退出待机模式")。
  • 中断使能(RTC_CR)
    • SECIE(秒中断)、OWIE(溢出中断)、ALRIE(闹钟中断)分别控制三类中断,经 NVIC 处理( "中断输出使能和 NVIC 部分" 的硬件实现)。
4. 低功耗与待机特性
  • 后备区域供电:预分频器和计数计时单元在待机时持续供电(VBAT),确保计时不中断;APB1 接口、RTC_CR、NVIC 待机时断电。

RTC基本结构

​ 预分频器中余数寄存器是一个自减设置的,就是来一个时钟就会计数值减一,当当减到0,会产生一个时钟信号向后传递,PRl重装值,设置周期,记满多少次向后产生一个时钟,当余数寄存器减到0,会将重装寄存器中的数据重装到自己的寄存器中,继续计数。

硬件电路

1. 备用电池供电电路
  • 简单连接:VBAT 直接接 3V 纽扣电池(如 CR2032),负极与主电源共地。
  • 推荐连接:通过二极管(D1/D2)隔离主电源(VDD)与备用电池(VBAT),并联 0.1μF 电容(C3)防电流倒灌,确保 VDD 掉电后 VBAT 独立供电(图中推荐电路,"防止电源倒灌,提升可靠性")。
2. 外部低速晶振(LSE)电路
  • 32.768kHz 晶振:连接 OSC32_IN(PC14)和 OSC32_OUT(PC15),两端并联 10pF 电容(C1/C2)到地("LSE 为 RTC 首选时钟源,精度高,主电源掉电后 VBAT 供电持续工作")。
  • 作用:提供 1Hz 秒脉冲(经 15 位自然分频,32768=2^15),驱动 RTC 32 位计数器,实现高精度计时("20 位可编程预分频器适配输入时钟",LSE 无需复杂分频计算)。
3. 引脚功能与复用
  • VBAT 引脚(PC13)
    • 复用为 TAMPER(侵入检测,触发时清除 BKP 数据)、RTC 时钟输出(秒脉冲 / 闹钟信号)或 GPIO("BKP 额外功能" 的硬件载体,如防拆检测、时钟校准输出)。
  • OSC32 引脚(PC14/PC15):专属 RTC 时钟输入,连接 LSE 晶振( LSE 是 RTC 的核心时钟源)。
4. 硬件设计规范
  • 电源滤波:VBAT(0.1μF)、LSE 晶振(10pF)均需滤波电容,抑制电源噪声。
  • 二极管隔离:推荐电路中的 D1/D2(如 1N4148)确保主备电源互不影响,VBAT 在 VDD 掉电后自动接管供电。

RTC操作注意事项

后面进行代码编写时会着重强调。

1. 使能 BKP 和 RTC 访问(时钟与权限)
  • 硬件保护机制
    BKP 和 RTC 位于后备区域,默认受保护(防止误操作)。使能 PWR/BKP 时钟(PWREN/BKPEN)确保模块供电,DBP(Disable Backup Protection)位解锁访问权限,避免非授权代码篡改掉电保持数据(如 BKP 存储的校准参数、RTC 计时状态),保障数据完整性(尤其在主电源掉电后 VBAT 供电的敏感场景)。
2. 读取 RTC 前等待 RSF(Registers Synchronized Flag) 同步标志
  • 时钟域异步性
    RTC(RTCCLK,如 32.768kHz)与 APB1 总线(PCLK1,高频)异步。RSF=1 表示 RTC 寄存器(如 CNT 秒计数)已与 APB1 接口同步,确保读取时数据最新(避免因时钟不同步导致时间戳错误,如读取到未更新的秒数),保证计时精度。
3. 写入 RTC 前进入配置模式(CNF 位 Configuration Flag)
  • 运行时保护
    RTC 正常运行时(CNF=0),计数 / 分频 / 闹钟寄存器为只读(防止运行中误写,如秒计数器递增时写入导致计时混乱)。进入配置模式(CNF=1)后,RTC 暂停计时逻辑("冻结" 时钟),确保写入操作(如设置初始时间、闹钟)的原子性,避免中间状态错误(如预分频值半写入导致频率偏差)。
4. 写操作等待 RTOFF(RTC Register Transfer Ongoing Flag) 位(前次写结束)
  • 寄存器更新时序
    RTC 寄存器属于 RTCCLK 域,写入后需时间同步到硬件(如预分频器重装)。RTOFF=1 表示前次写操作完成(值已生效),避免流水线写操作的竞态条件(如连续写 CNT 和 ALR 时,确保 CNT 先更新,ALR 基于新值比较),保证配置与计时逻辑的一致性,提升系统可靠性(尤其在低功耗场景下,待机唤醒后 RTC 状态恢复的稳定性)。

BKP 库函数介绍

函数名 功能 参数 返回值 说明
BKP_DeInit 恢复 BKP 模块寄存器至复位默认值 初始化前重置配置,确保干净的工作状态
BKP_TamperPinLevelConfig 配置侵入检测引脚的有效触发电平 uint16_t BKP_TamperPinLevel(如 BKP_TamperPinLevel_High/Low 设定侵入检测(Tamper)的触发条件(高 / 低电平)
BKP_TamperPinCmd 使能 / 禁止侵入检测功能 FunctionalState NewStateENABLE/DISABLE 控制是否启用侵入检测(用于系统安全监测)
BKP_ITConfig 使能 / 禁止 BKP 模块的中断 FunctionalState NewState 开启 / 关闭 BKP 相关中断(如侵入检测中断),配合中断处理函数使用
BKP_RTCOutputConfig 配置 RTC_OUT 引脚的输出信号源 uint16_t BKP_RTCOutputSource(如校准时钟、闹钟脉冲、秒脉冲) 将 RTC 时钟信号输出到外部(如示波器、时钟模块),扩展 RTC 功能
BKP_SetRTCCalibrationValue 设置 RTC 校准值 uint8_t CalibrationValue(-128~+127,补偿晶振误差) 调整 RTC 时钟精度,补偿晶振频率偏移
BKP_WriteBackupRegister 写入备份寄存器(掉电保持) uint16_t BKP_DR(寄存器编号,如BKP_DR1),uint16_t Data(16 位数据) 存储关键数据(如系统配置、掉电前状态),主电源掉电后由备用电池保持
BKP_ReadBackupRegister 读取备份寄存器数据 uint16_t BKP_DR uint16_t(寄存器存储的值) 恢复掉电前保存的数据(如系统重启后读取配置)
BKP_GetFlagStatus 获取 BKP 模块的标志位状态 FlagStatusSET/RESET 轮询检查事件(如侵入检测是否触发)
BKP_ClearFlag 清除 BKP 模块的标志位 处理标志位后清除(避免重复响应,如侵入检测标志)
BKP_GetITStatus 获取 BKP 模块的中断状态 ITStatusSET/RESET 检查是否有未处理的中断(用于中断服务函数)
BKP_ClearITPendingBit 清除 BKP 模块的中断挂起位 中断处理后清除挂起位,防止重复进入中断

实时时钟

RCC有关库函数

函数名 功能描述 调用时机 注意事项
RCC_LSE_Configure 配置并启动外部低速时钟(LSE)(如 32.768kHz 晶振)。 初始化 RTC 前,需手动开启 LSE 时钟 LSE 默认关闭,需调用此函数启动;启动后需等待LSE_READY标志位为 1。
RCC_LSI_Command 配置并启动内部低速时钟(LSI)(约 40kHz,用于备份时钟)。 当 LSE 不起振时(如实验调试场景) 可作为 LSE 的替代时钟源,用于应急或测试。
RTC_CLK_Configure 选择 RTC 的时钟源(如 LSE/LSI),配置时钟源数据选择器。 启动 LSE/LSI 后,配置 RTC 时钟源时 需与RTC_CLK_Command配合使用,先配置时钟源,再使能时钟。
RTC_CLK_Command 使能 RTC 时钟(在配置完时钟源后调用)。 配置完RTC_CLK_Configure 必须调用此函数才能激活 RTC 时钟。
RCC_GetFlagStatus 获取时钟标志位状态(如LSE_FLAG),判断时钟是否稳定启动。 调用RCC_LSE_Configure 需循环等待LSE_READY标志位为 1,确保 LSE 时钟稳定工

RTC有关库函数

函数名 功能描述 调用时机 注意事项
模式切换函数
RTC_EnterConfigMode 进入 RTC 配置模式(置CRL寄存器的CNF位为 1)。 需修改 RTC 寄存器(如预分频器、计数器)前 必须先进入配置模式,否则无法写入寄存器!
RTC_ExitConfigMode 退出 RTC 配置模式(清CRL寄存器的CNF位为 0)。 完成 RTC 寄存器配置后 配置完成后需立即退出,避免误操作。
数据操作函数
RTC_GetCounter 读取 RTC 计数器(CNT)的值,即当前时间(单位:秒)。 需要获取实时时间时 直接返回计数器值,需自行转换为时分秒格式。
RTC_SetCounter 设置 RTC 计数器初始值(如设置初始时间)。 初始化 RTC 时配置初始时间 需先进入配置模式(调用RTC_EnterConfigMode)。
RTC_SetPrescaler 配置预分频器(PRL寄存器),设置计数器时钟频率(通常为 1Hz)。 初始化 RTC 时配置分频系数 分频值计算公式:PRL = LSE频率/1Hz - 1(如 LSE=32768Hz 时,PRL=32767)。
RTC_SetAlarm 设置 RTC 闹钟值(ALR寄存器)。 需要配置闹钟功能时 需配合中断配置(RTC_ITConfig)使用。
RTC_GetDivider 读取预分频器余数寄存器(DIV),获取亚秒级精度时间(如毫秒)。 需要更高时间精度时(如调试) CNT计数间隔为 1 秒,DIV寄存器用于记录余数,可计算更细粒度时间。
等待与同步函数
RTC_WaitForLastTask 等待上次 RTC 写操作完成(循环检测RTF标志位)。 每次写操作(如设置计数器、预分频器)后 防止寄存器操作未完成时进行下一次写操作,避免数据错误!
RTC_WaitForSynchro 等待 RTC 时钟同步完成(循环检测RSF标志位)。 配置时钟源或初始化 RTC 时 确保 RTC 时钟与时钟源同步,避免计时误差。
中断与标志位函数
RTC_ITConfig 配置 RTC 中断(如闹钟中断、溢出中断)。 需要启用中断功能时 需结合中断控制器(NVIC)配置。
[其他标志位函数] (如检查同步状态、中断标志等,会议未详细列出,需结合具体寄存器操作) 状态监控或错误处理时 需参考官方库函数文档或寄存器定义。

实时时钟代码编写步骤

配置时钟源 -》选择时钟源信号 -》配置预分频器参数 -》配置计数器等

  • 开启 LSE 时钟 :调用 RCC 里的 LSE config 函数,参数用 RCC LSE on 启动外部 LSE 晶振,通过 while 循环调用 RCC get flag status 函数等待 LSE ready 标志位(等待时钟开启完成)。
  • 选择时钟源 :调用 RCC RTC c LK config 函数,选择 RCC RTCCLK source LSE,再调用 RCC RTC CRK command 函数使能时钟。
  • 等待操作 :调用等待同步和等待上一次写入操作完成的函数,防止时钟不同步造成 bug。
  • 配置预分频器 :调用 RTC set prescaler 函数,分频系数为 32768 - 1,写入后调用 RTC 等待函数确保操作完成,库函数自带进入和退出配置模式代码。
  • 设置初始时间 :调用 RTC set counter 函数,使用 PPT 里 2023 年 1 月 1 日的秒数设定初始时间,写入后调用等待函数。

RTC相关代码

c 复制代码
// MyRTC.c 

#include "stm32f10x.h"                  // Device header
#include <time.h>
//创建一个数组,将要写入的时间存储到数组中,这里设置的为0时区时间
uint16_t Time[] = {2013, 1, 1, 15, 59, 55};
void MyRTC_SetTime(void);

//会出现复位 重新初始化的问题 只要BKP没有掉电就不用初始化
void RTC_Init(void)
{
	//使能部分代码,开启时钟 PWR 和 BKP
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
	//pwr 使能对bkp 和 rtc的数据访问
	PWR_BackupAccessCmd(ENABLE);
	
	if(BKP_ReadBackupRegister(BKP_DR1) != 0xAAaa)
	{
		//使用lse 时钟源 配置
		RCC_LSEConfig(RCC_LSE_ON);
		//开启时钟要等待开启完成 转化完成会置标志位
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);
		//选择时钟源
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
		//开启RTC时钟开关
		RCC_RTCCLKCmd(ENABLE);
		
		//下面对RTC进行操作
		//等待时钟同步
		RTC_WaitForSynchro();
		//每一次进行写操作时,要进行判断上一个字节是否写入完成
		RTC_WaitForLastTask();
		
		//设置分频器数据
		//分频后的频率 = 时钟源频率 / (预分频系数)
		RTC_SetPrescaler(32768 - 1);
		//等待数据写入完成
		RTC_WaitForLastTask();
		
		//设置计数值 这里是初始化所以就是初始值
		MyRTC_SetTime();
		//等待数据写入完成
		RTC_WaitForLastTask();
		
		BKP_WriteBackupRegister(BKP_DR1, 0xAAaa);
	}
	else
	{
		//使用lse 时钟源 配置
		RCC_LSEConfig(RCC_LSE_ON);
		//开启时钟要等待开启完成 转化完成会置标志位
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);
		//选择时钟源
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
		//开启RTC时钟开关
		RCC_RTCCLKCmd(ENABLE);
		
		//下面对RTC进行操作
		//等待时钟同步
		RTC_WaitForSynchro();
		//每一次进行写操作时,要进行判断上一个字节是否写入完成
		RTC_WaitForLastTask();
	}
	
}

//实现写时间的函数
void MyRTC_SetTime(void)
{
	time_t time_cnt;
	struct tm time_data;
	
	//将要设置的时间写入结构体中
	time_data.tm_year = Time[0] - 1900;
	time_data.tm_mon = Time[1] - 1;
	time_data.tm_mday = Time[2];
	time_data.tm_hour = Time[3];
	time_data.tm_min = Time[4];
	time_data.tm_sec = Time[5];
	
	//将结构体中数据转化为时间戳
	time_cnt = mktime(&time_data);
	
	//将获取的秒计数进行 计数器设置
	//设置计数值 这里是初始化所以就是初始值
	RTC_SetCounter(time_cnt);
	//等待数据写入完成
	RTC_WaitForLastTask();
	
}

//实现读取时间函数
//读取秒计数,将秒计数转化为结构体将,结构体中数据按顺序存储到数组中
void MyRTC_GetData(void)
{
	time_t time_cnt;
	struct tm time_data;
	
	//将得到的0时区的时间转化为东8区时间
	time_cnt = RTC_GetCounter() + 8 * 60 * 60;
	
	time_data = *localtime(&time_cnt);
	
	Time[0] = time_data.tm_year + 1900;
	Time[1] = time_data.tm_mon + 1;
	Time[2] = time_data.tm_mday;
	Time[3] = time_data.tm_hour;
	Time[4] = time_data.tm_min;
	Time[5] = time_data.tm_sec;
}

主函数实现代码

c 复制代码
//main.c

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

int main(void)
{
	OLED_Init();
	RTC_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_GetData();							//RTC读取时间,最新的时间存储到MyRTC_Time数组中
		
		OLED_ShowNum(1, 6, Time[0], 4);		//显示MyRTC_Time数组中的时间值,年
		OLED_ShowNum(1, 11, Time[1], 2);		//月
		OLED_ShowNum(1, 14, Time[2], 2);		//日
		OLED_ShowNum(2, 6, Time[3], 2);		//时
		OLED_ShowNum(2, 9, Time[4], 2);		//分
		OLED_ShowNum(2, 12, Time[5], 2);		//秒
		
		OLED_ShowNum(3, 6, RTC_GetCounter(), 10);	//显示32位的秒计数器
		OLED_ShowNum(4, 6, RTC_GetDivider(), 10);	//显示余数寄存器

   }
}
相关推荐
Wallace Zhang4 小时前
STM32F103_Bootloader程序开发11 - 实现 App 安全跳转至 Bootloader
stm32·嵌入式硬件·安全
GodKK老神灭4 小时前
STM32 CCR寄存器
stm32·单片机·嵌入式硬件
杰克逊的日记9 天前
MCU编程
单片机·嵌入式硬件
Python小老六9 天前
单片机测ntc热敏电阻的几种方法(软件)
数据库·单片机·嵌入式硬件
懒惰的bit9 天前
STM32F103C8T6 学习笔记摘要(四)
笔记·stm32·学习
HX科技10 天前
STM32给FPGA的外挂FLASH进行升级
stm32·嵌入式硬件·fpga开发·flash·fpga升级
Suagrhaha10 天前
驱动入门的进一步深入
linux·嵌入式硬件·驱动
国科安芯10 天前
基于ASP4644多通道降压技术在电力监测系统中集成应用与发展前景
嵌入式硬件·硬件架构·硬件工程
Li Zi10 天前
STM32 ADC(DMA)双缓冲采集+串口USART(DMA)直接传输12位原始数据到上位机显示并保存WAV格式音频文件 收藏住绝对实用!!!
经验分享·stm32·单片机·嵌入式硬件
进击的程序汪10 天前
触摸屏(典型 I2C + Input 子系统设备)从设备树解析到触摸事件上报
linux·网络·嵌入式硬件