爆肝9万字,我已从小白晋升ARM嵌入式工程师!带你从零熟悉常用的M4嵌入式功能,建议收藏(含码源)(4)

本文涉及的产品
云防火墙,500元 1000GB
简介: 什么是实时时钟?实时时钟RTC是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可以供应时钟日历的功能。

6.4 实例代码

#include "tim4.h"                  // Device header
#include "stdio.h" 
void TIM4_Init(u16 psc,u16 arr)
{
  TIM_TimeBaseInitTypeDef tim4;
  NVIC_InitTypeDef NVIC_tim4;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);  //使能定时器4时钟
  tim4.TIM_ClockDivision=TIM_CKD_DIV1;
  tim4.TIM_CounterMode=TIM_CounterMode_Down;
  tim4.TIM_Period=arr;
  tim4.TIM_Prescaler=psc-1;
  tim4.TIM_RepetitionCounter=0;
  TIM_TimeBaseInit(TIM4, &tim4);   //初始化定时器4的配置
  TIM_ITConfig(TIM4,TIM_IT_Update, ENABLE);  //使能更新中断
  NVIC_tim4.NVIC_IRQChannel=TIM4_IRQn;   //设置的NVIC优先级的中断编号
  NVIC_tim4.NVIC_IRQChannelCmd=ENABLE;
  NVIC_tim4.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级
  NVIC_tim4.NVIC_IRQChannelSubPriority=0;     //响应优先级
  NVIC_Init(&NVIC_tim4);
  TIM_Cmd(TIM4, ENABLE);
}
//中断服务函数
void TIM4_IRQHandler(void)
{
  TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除更新中断
  printf("1S时间到\r\n");
} 

7.RTC实时时钟

7.1 简介

 什么是实时时钟?实时时钟RTC是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可以供应时钟日历的功能。修改计数器的数值可以重新设置当前的时间和日期。RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或待机模式唤醒以后,RTC的设置和事件维持不变。RTC由自带的电源引脚VBat供电,VBat可以和蓄电池相互连接,也可以和外部的3.3V电源引脚相连接或保持断开!

 PS:RTC是一个系统定时器中独立出来的设备,用于设置系统时钟,提供报警器或周期性的定时器。

7.2 STM32F4系列RTC特点

  • 包含里秒、秒,分钟、小时( 12/24 小时制)、星期儿,日期、月份和年份的日历。
  • 软件可编程的夏令时补偿。
  • 两个具有中断功能的可编程网钟。可通过任意日历字段的组合驱动闹钟。
  • 自动唤醒单元,可周期性地生成标志以触发自动唤醒中断。
  • 参考时钟检测:可使用更加精确的第二时钟源(50 Hz或60 Hz)来提高日历的精确度。
  • 利用亚秒级移位特性与外部时钟实现精确同步。
  • 可屏蔽中断/事件:
  •     一闹钟A;
  •    --闹钟B
  •    唤醒中断
  •    -时间戳
  •   一入侵检测
  • 数字校准电路(周期性计数器调整)
  • 一精度为5ppa
  • -精度为0. 95 ppa,在数秒钟的校准窗口中获取
  • 用于事件保存的时间戳功能( 1个事件)
  • 入侵检测:
  • 一2个带可能置过速器和内部上拉的入侵事件
  • 20个备份寄存器80字节) .发生入侵检测事件时,将复位备份寄存器
  • 复用功能输出 (RTC_OUT),可选择以下两个输出之一:
  • — RTC_CALIB : 512 Hz 或 1 Hz 时钟输出( LSE 频率为 32.768 kHz) 。

可通过将 RTC_CR 寄存器中的 COE[23] 位置 1 来使能此输出。该输出可连接到器

件 RTC_AF1 功能。

— RTC_ALARM (闹钟 A 、闹钟 B 或唤醒)。

可通过配置 RTC_CR 寄存器的 OSEL[1:0] 位选择此输出。该输出可连接到器件

RTC_AF1 功能。

  • RTC 复用功能输入:

— RTC_TS:时间戳事件检测。该输入可连接到器件RTC_AF1 RTC_AF2 功能。

— RTC_TAMP1 : TAMPER1 事件检测。该输入可连接到器件 RTC_AF1 和 RTC_AF2

功能。

— RTC_TAMP2 : TAMPER2 事件检测。

— RTC_REFIN :参考时钟输入(通常为市电, 50 Hz 或 60 Hz )。

2345_image_file_copy_71.jpg

RTC框架图

7.3 RTC 初始化和配置

7.3.1 寄存器访问

 RTC 寄存器为32 位寄存器。除了当BYPSHAD=0 时对日历影子寄存器执行的读访问之外,APB 接口会在访问RTC 寄存器时引入2 个等待周期。

7.3.2 寄存器写保护

   系统复位后,可通过 PWR 电源控制寄存器 (PWR_CR) 的 DBP 位保护 RTC 寄存器以防止非正常的写访问。必须将 DBP 位置 1 才能使能 RTC 寄存器的写访问。

上电复位后,所有 RTC 寄存器均受到写保护。通过向写保护寄存器 (RTC_WPR) 写入一个密钥来使能对 RTC 寄存器的写操作。

要解锁所有 RTC 寄存器( RTC_ISR[13:8] 、 RTC_TAFCR 和 RTC_BKPxR 除外)的写保护,需要执行以下步骤:

1. 将“0xCA ”写入 RTC_WPR 寄存器。

2. 将“0x53 ”写入 RTC_WPR 寄存器。

写入一个错误的关键字会再次激活写保护。

保护机制不受系统复位影响

7.3.3 日历初始化和配置

要编程包括时间格式和预分频器配置在内的初始时间和日期日历值,需按照以下顺序操作:

  • RTC_ISR 寄存器中的 INIT 位置 1 以进入初始化模式。在此模式下,日历计数器将停       止工作并且其值可更新。
  • 轮询 RTC_ISR 寄存器中的 INITF 位。当 INITF 1 时进入初始化阶段模式。大约需要

      2 RTCCLK 时钟周期(由于时钟同步)。

  • 要为日历计数器生成 1 Hz 时钟,应首先编程 RTC_PRER 寄存器中的同步预分频系数,

      然后编程异步预分频系数。即使只需要更改这两个字段中之一,也必须对RTC_PRER

       寄存器执行两次单独的写访问。

  • 在影子寄存器(RTC_TR RTC_DR)中加载初始时间和日期值,然后通过 RTC_CR

       寄存器中的FMT 位配置时间格式(12 24 小时制)。

  • 通过清零 INIT 位退出初始化模式。随后,自动加载实际日历计数器值,在 4 RTCCLK

       时钟周期后重新开始计数。

当初始化序列完成之后,日历开始计数。

7.3.4 夏令时

可通过RTC_CR 寄存器的SUB1HADD1H BKP 位管理夏令时。 利用 SUB1H ADD1H,软件只需单次操作便可在日历中减去或增加一个小时,无需执行整个初始化步骤。 此外,软件还可以使用 BKP 位来记录是否曾经执行过此操作。

7.4 RTC 相关寄存器

7.4.1 RTC 时间寄存器(RTC_TR)

2345_image_file_copy_72.jpg

位 31-24 保留

位 23 保留,必须保持复位值。

位 22 PM:AM/PM 符号 (AM/PM notation)

0AM 24 小时制

1PM

位 21:20 HT[1:0]:小时的十位(BCD 格式)(Hour tens in BCD format)

位 16:16 HU[3:0]:小时的个位(BCD 格式)(Hour units in BCD format)

位 15 保留,必须保持复位值。

位 14:12 MNT[2:0]:分钟的十位(BCD 格式)(Minute tens in BCD format)

位 11:8 MNU[3:0]:分钟的个位(BCD 格式)(Minute units in BCD format)

位 7 保留,必须保持复位值。

位 6:4 ST[2:0]:秒的十位(BCD 格式)(Second tens in BCD format)

位 3:0 SU[3:0]:秒的个位(BCD 格式)(Second units in BCD format)

7.4.2 RTC日期寄存器(RTC_DR)

2345_image_file_copy_73.jpg

位 31-24 保留

位 23:20 YT[3:0]:年份的十位(BCD 格式)(Year tens in BCD format)

位 19:16 YU[3:0]:年份的个位(BCD 格式)(Year units in BCD format)

位 15:13 WDU[2:0]:星期几的个位 (Week day units)

000:禁止

001:星期一

...

111:星期日

位 12 MT:月份的十位(BCD 格式)(Month tens in BCD format)

位 11:8 MU:月份的个位(BCD 格式)(Month units in BCD format)

位 7:6 保留,必须保持复位值。

位 5:4 DT[1:0]:日期的十位(BCD 格式)(Date tens in BCD format)

位 3:0 DU[3:0]:日期的个位(BCD 格式)(Date units in BCD format)

7.4.3 RTC控制寄存器

2345_image_file_copy_74.jpg

位 31:24 保留,必须保持复位值

位 23 COE:校准输出使能 (Calibration output enable)

该位使能RTC_CALIB 输出

0:禁止校准输出

1:使能校准输出

位 22:21 OSEL[1:0]:输出选择 (Output selection)

这些位用于选择要连接到RTC_ALARM 输出的标志

00:禁止输出

01:使能闹钟A 输出

10:使能闹钟B 输出

11:使能唤醒输出

位 20 POL:输出极性 (Output polarity)

该位用于配置 RTC_ALARM 输出的极性

0 :当 ALRAF/ALRBF/WUTF 置 1 时(取决于 OSEL[1:0] ),该引脚为高电平

1 :当 ALRAF/ALRBF/WUTF 置 1 时(取决于 OSEL[1:0] ),该引脚为低电平

位 19 COSEL:校准输出选择 (Calibration output selection)

当 COE=1 时,该位可选择 RTC_CALIB 上输出的信号。

0 :校准输出为 512 Hz

1 :校准输出为 1 Hz

在 RTCCLK 为 32.768 kHz 且预分频器为其默认值( PREDIV_A=127 且 PREDIV_S=255)的条件下,这些频率有效。

位 18 BKP:备份 (Backup)

用户可对此位执行写操作以记录是否已对夏令时进行更改。

位 17 SUB1H:减少 1 小时(冬季时间更改)(Subtract 1 hour (winter time change))

当该位在初始化模式以外的模式下置 1 时,如果当前小时不是 0 ,则日历时间将减少 1 小时。此位始终读为 0 。

当前小时为 0 时,将此位置 1 没有任何作用。

0 :无作用。

1 :将当前时间减少 1 小时。这可用于冬季时间更改。

位 16 ADD1H:增加 1 小时(夏季时间更改)(Add 1 hour (summer time change))

当该位在初始化模式以外的模式下置 1 时,日历时间将增加 1 小时。此位始终读为 0 。

0 :无作用。

1:将当前时间增加1 小时。这可用于夏季时间更改

位 15 TSIE:时间戳中断使能 (Timestamp interrupt enable)

0:禁止时间戳中断

1:使能时间戳中断

位 14 WUTIE:使能唤醒定时器使能 (Wakeup timer interrupt enable)

0:禁止唤醒定时器中断

1:使能唤醒定时器中断

位 13 ALRBIE闹钟 B 中断使能 (Alarm B interrupt enable)

0:闹钟B 中断禁止

1:闹钟B 中断使能

位 12 ALRAIE:闹钟 A 中断使能 (Alarm A interrupt enable)

0:禁止闹钟A 中断

1:使能闹钟A 中断

位 11 TSE:时间戳使能 (Time stamp enable)

0:禁止时间戳

1:使能时间戳

位 10 WUTE:唤醒定时器使能 (Wakeup timer enable)

0:禁止唤醒定时器

1:使能唤醒定时器

位 9 ALRBE闹钟 B 使能 (Alarm B enable)

0:禁止闹钟B

1:使能闹钟B

位 8 ALRAE:闹钟 A 使能 (Alarm A enable)

0:禁止闹钟A

1:使能闹钟A

位 7 DCE:粗略数字校准使能 (Coarse digital calibration enable)

0:禁止数字校准

1:使能数字校准

PREDIV_A 必须大于或等于6

位 6 FMT:小时格式 (Hour format)

024 小时/天格式

1AM/PM 小时格式

位 5 BYPSHAD:旁路影子寄存器 (Bypass the shadow registers)

0 :日历值(从 RTC_SSR 、 RTC_TR 和 RTC_DR 读取时)取自影子寄存器,该影子寄存器

每两个 RTCCLK 周期更新一次。

1 :日历值(从 RTC_SSR 、 RTC_TR 和 RTC_DR 读取时)直接取自日历计数器。

注意:如果 APB1 时钟的频率低于 7 倍的 RTCCLK 频率,则必须将 BYPSHAD 置“ 1 ”

位 4 REFCKON:参考时钟检测使能(50 Hz 或 60 Hz)(Reference clock detection enable (50 or60 Hz))

0 :禁止参考时钟检测

1 :使能参考时钟检测

注意:PREDIV_S 必须为0x00FF

位 3 TSEDGE:时间戳事件有效边沿 (Timestamp event active edge)

0 : TIMESTAMP 上升沿生成时间戳事件

1 : TIMESTAMP 下降沿生成时间戳事件

TSEDGE 发生更改时,必须复位 TSE 以避免将 TSF 意外置 1

位 2:0 WUCKSEL[2:0]:唤醒时钟选择 (Wakeup clock selection)

000:选择RTC/16 时钟

001 :选择 RTC/8 时钟

010 :选择 RTC/4 时钟

011 :选择 RTC/2 时钟

10x :选择 ck_spre 时钟(通常为 1 Hz )

11x :选择 ck_spre 时钟(通常为 1 Hz )并将 WUT 计数器值增加 2 16 (见下面的注释)

7.4.4 RTC初始化和状态寄存器(RTC_ISR)

2345_image_file_copy_75.jpg

位 31:17 保留

位 16 RECALPF:重新校准挂起标志 (Recalibration pending Flag)

当软件对 RTC_CALR 寄存器执行写操作时, RECALPF 状态标志将自动置“ 1 ”,指示

RTC_CALR 寄存器已屏蔽。当采用新的校准设置时,该位恢复为“ 0 ”。请参见 动态重校准一节。

位 15 保留,必须保持复位值。

位 14 TAMP2F:TAMPER2 检测标志 (TAMPER2 detection flag)

在入侵输入2 上检测到入侵检测事件时,由硬件将此标志置1

该标志由软件写零清除。

位 13 TAMP1F:入侵检测标志 (Tamper detection flag)

当检测到入侵检测事件时,由硬件将此标志置1

该标志由软件写零清除。

位 12 TSOVF:时间戳溢出标志 (Timestamp overflow flag)

当在TSF 已置1 的情况下发生时间戳事件时,由硬件将此标志置1

该标志由软件写零清除。建议仅在TSF 位清零之后再检查并清零TSOVF 位。否则,如果时间戳事件恰好在清零TSF 位之前刚刚发生,则溢出事件可能会被漏掉。

位 11 TSF:时间戳标志 (Timestamp flag)

发生时间戳事件时,由硬件将此标志置1

该标志由软件写零清除。

位 10 WUTF:唤醒定时器标志 (Wakeup timer flag)

当唤醒自动重载计数器计数到0 时,由硬件将此标志置1

该标志由软件写零清除。

软件必须在 WUTF 再次置 1 的 1.5 个 RTCCLK 周期之前将该标志清零。

位 9 ALRBF:闹钟 B 标志 (Alarm B flag)

当时间 / 日期寄存器( RTC_TR 和 RTC_DR )与闹钟 B 寄存器 (RTC_ALRMBR) 匹配时,由硬件将该标志置 1 。

该标志由软件写零清除。

位 8 ALRAF:闹钟 A 标志 (Alarm A flag)

当时间 / 日期寄存器( RTC_TR 和 RTC_DR )与闹钟 A 寄存器 (RTC_ALRMAR) 匹配时,由硬件将该标志置 1 。

该标志由软件写零清除。

位 7 INIT:初始化模式 (Initialization mode)

0:自由运行模式。

1 :初始化模式,用于编程时间和日期寄存器( RTC_TR 和 RTC_DR )以及预分频器寄存器(RTC_PRER) 。计数器停止计数,当 INIT 被复位后,计数器从新值开始计数。

位 6 INITF:初始化标志 (Initialization flag)

当此位置1 时,RTC 处于初始化状态,此时可更新事件、日期和预分频器寄存器。

0:不允许更新日历寄存器。

1:允许更新日历寄存器。

位 5 RSF:寄存器同步标志 (Registers synchronization flag)

每次将日历寄存器的值复制到影子寄存器( RTC_SSRx 、 RTC_TRx 和 RTC_DRx )时,都会由硬件将此位置 1 。在初始化模式下、平移操作挂起时 (SHPF=1) 或在旁路影子寄存器模式 (BYPSHAD=1) 下,该位由硬件清零。该位还可由软件清零。

0 :日历影子寄存器尚未同步

1 :日历影子寄存器已同步

位 4 INITS:初始化状态标志 (Initialization status flag)

当日历年份字段不为0 时(上电复位状态),由硬件将该位置1

0:日历尚未初始化

1:日历已经初始化

位 3 SHPF:平移操作挂起 (Shift operation pending)

0:没有平移操作挂起

1:某个平移操作挂起

只要通过对 RTC_SHIFTR 寄存器执行写操作来启动平移操作,此标志便由硬件置 1 。执行完相应的平移操作后,此标志由硬件清零。对 SHPF 执行写入操作不起作用。

位 2 WUTWF:唤醒定时器写标志 (Wakeup timer write flag)

在 RTC_CR 寄存器中的 WUTE 位置 0 后,当唤醒定时器值可更改时,由硬件将该位置 1 。

0 :不允许更新唤醒定时器配置

1 :允许更新唤醒定时器配置

位 1 ALRBWF:闹钟 B 写标志 (Alarm B write flag)

在 RTC_CR 寄存器中的 ALRBIE 位置 0 之后,当闹钟 B 的值可更改时,由硬件将该位置 1 。

该位在初始化模式下由硬件清零。

0 :不允许更新闹钟 B

1 :允许更新闹钟 B

位 0 ALRAWF:闹钟 A 写标志 (Alarm A write flag)

在 RTC_CR 寄存器中的 ALRAE 位置 0 后,当闹钟 A 的值可更改时,由硬件将该位置 1 。

该位在初始化模式下由硬件清零。

0 :不允许更新闹钟 A

1 :允许更新闹钟 A

7.4.5  RTC预分频寄存器(TRC_PRER)

2345_image_file_copy_76.jpg

位 31:24 保留

位 23 保留,必须保持复位值。

位 22:16 PREDIV_A[6:0]:异步预分频系数 (Asynchronous prescaler factor)

下面是异步分频系数的公式:

ck_apre 频率 = RTCCLK 频率 /(PREDIV_A+1)

注意: PREDIV_A [6:0]= 000000 为禁用值。

位 15 保留,必须保持复位值。

位 14:0 PREDIV_S[14:0]:同步预分频系数 (Synchronous prescaler factor)

下面是同步分频系数的公式:

ck_spre 频率= ck_apre 频率/(PREDIV_S+1)

7.4.6 RTC唤醒定时器寄存器(RTC_WUTR)

2345_image_file_copy_77.jpg 

位 31:16 保留

位 15:0 WUT[15:0]:唤醒自动重载值位 (Wakeup auto-reload value bit)

当使能唤醒定时器时( WUTE 置 1 ),每 (WUT[15:0] + 1) 个 ck_wut 周期将 WUTF 标志置 1

一次。 ck_wut 周期通过 RTC_CR 寄存器的 WUCKSEL[2:0] 位进行选择。

当 WUCKSEL[2] = 1 时,唤醒定时器变为 17 位, WUCKSEL[1] 等效为 WUT[16] ,即要重载到定时器的最高有效位。

注意: WUTF 第一次置 1 发生在 WUTE 置 1 之后 (WUT+1) 个 ck_wut 周期。禁止在

WUCKSEL[2:0]=011(RTCCLK/2) 时将 WUT[15:0] 设置为 0x0000 。

7.4.7 RTC校准寄存器(RTC_CALIBR)

2345_image_file_copy_78.jpg

位 31:8 保留

位 7 DCS:数字校准符号 (Digital calibration sign)

0:正校准:增加日历更新频率

1:负校准:降低日历更新频率

位 6:5 保留,必须保持复位值。

位 4:0 DC[4:0]:数字校准 (Digital calibration)

DCS = 0 (正校准)

00000 : + 0 ppm

00001 : + 4 ppm (舍入值)

00010 : + 8 ppm (舍入值)

..

11111 : + 126 ppm (舍入值)

DCS = 1 (负校准)

00000 :  0 ppm

00001 :  2 ppm (舍入值)

00010 :  4 ppm (舍入值)

..

11111 :  63 ppm (舍入值)

7.4.8 RTC闹钟A寄存器(RTC_ALRMAR)

2345_image_file_copy_79.jpg

 位 31 MSK4:闹钟 A 日期掩码 (Alarm A date mask)

0 :如果日期 / 日匹配,则闹钟 A 置 1

1 :在闹钟 A 比较中,日期 / 日无关

位 30 WDSEL:星期几选择 (Week day selection)

0DU[3:0] 代表日期的个位

1 : DU[3:0] 代表星期几。 DT[1:0] 为无关位。

位 29:28 DT[1:0]:日期的十位(BCD 格式)(Date tens in BCD format)。

位 27:24 DU[3:0]:日期的个位或日(BCD 格式)(Date units or day in BCD format)。

位 23 MSK3:闹钟 A 小时掩码 (Alarm A hours mask)

0:如果小时匹配,则闹钟A 1

1:在闹钟A 比较中,小时无关

位 22 PM:AM/PM 符号 (AM/PM notation)

0 : AM 或 24 小时制

1 : PM

位 21:20 HT[1:0]:小时的十位(BCD 格式)(Hour tens in BCD format)。

位 19:16 HU[3:0]:小时的个位(BCD 格式)(Hour units in BCD format)。

位 15 MSK2:闹钟 A 分钟掩码 (Alarm A minutes mask)

0:如果分钟匹配,则闹钟A 1

1:在闹钟A 比较中,分钟无关

位 14:12 MNT[2:0]:分钟的十位(BCD 格式)(Minute tens in BCD format)。

位 11:8 MNU[3:0]:分钟的个位(BCD 格式)(Minute units in BCD format)。

位 7 MSK1:闹钟 A 秒掩码 (Alarm A seconds mask)

0:如果秒匹配,则闹钟A 1

1:在闹钟A 比较中,秒无关

位 6:4 ST[2:0]:秒的十位(BCD 格式)(Second tens in BCD format)。

位 3:0 SU[3:0]:秒的个位(BCD 格式)(Second units in BCD format)

7.4.9 RTC闹钟B寄存器(RTC_ALRMBR)

2345_image_file_copy_80.jpg

位 31 MSK4:闹钟 B 日期掩码 (Alarm B date mask)

0:如果日期和日匹配,则闹钟B 1

1:在闹钟B 比较中,日期和日无关

位 30 WDSEL:星期几选择 (Week day selection)

0DU[3:0] 代表日期的个位。

1DU[3:0] 代表星期几。DT[1:0] 为无关位。

位 29:28 DT[1:0]:日期的十位(BCD 格式)(Date tens in BCD format)

位 27:24 DU[3:0]:日期个位或日(BCD 格式)(Date units or day in BCD format)

位 23 MSK3:闹钟 B 小时掩码 (Alarm B hours mask)

0:如果小时匹配,则闹钟B 1

1:在闹钟B 比较中,小时无关

位 22 PM:AM/PM 符号 (AM/PM notation)

0AM 24 小时制

1PM

位 21:20 HT[1:0]:小时的十位(BCD 格式)(Hour tens in BCD format)

位 19:16 HU[3:0]:小时的个位(BCD 格式)(Hour units in BCD format)

位 15 MSK2:闹钟 B 分钟掩码 (Alarm B minutes mask)

0:如果分钟匹配,则闹钟B 1

1:在闹钟B 比较中,分钟无关

位 14:12 MNT[2:0]:分钟的十位(BCD 格式)(Minute tens in BCD format)

位 11:8 MNU[3:0]:分钟的个位(BCD 格式)(Minute units in BCD format)

位 7 MSK1:闹钟 B 秒掩码 (Alarm B seconds mask)

0:如果秒匹配,则闹钟B 1

1:在闹钟B 比较中,秒无关

位 6:4 ST[2:0]:秒的十位(BCD 格式)(Second tens in BCD format)

位 3:0 SU[3:0]:秒的个位(BCD 格式)(Second units in BCD format)

7.4.10 RTC写保护寄存器(RTC_WPR)

2345_image_file_copy_81.jpg

 上电后,所有 RTC 寄存器都受到写保护( RTC_ISR[13:8] RTC_TAFCR 和 RTC_BKPxR 除外),必须依次写入: 0XCA 0X53 两关键字到 RTC_WPR 寄存 器,才可以解锁。

位 31:8 保留,必须保持复位值。

位 7:0 KEY:写保护关键字 (Write protection key)

可通过软件对该字节执行写操作。

读取该字节时,始终返回0x00

7.5 实例代码(初始化时间和日期)

#include "rtc.h"                  // Device header
#include "stdio.h" 
void RTC_Time_Init(u16 Year, u16 month, u16 day,u16 hour,u16 minute,u16 second,u16 WeekDay)
{
  RTC_InitTypeDef rtc;
  RTC_TimeTypeDef rtcTime;
  RTC_DateTypeDef rtcDate;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);  //PWR控制写保护的电源/备份区电源
  PWR_BackupAccessCmd(ENABLE);   //使能PWR备份域电源
  PWR_BackupRegulatorCmd(ENABLE);  //使能RTC备份寄存器
  //1、选择RTC时钟源
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);   //RTC选择LSE外部低速时钟
  RCC_RTCCLKCmd(ENABLE);    //使能RTC时钟
  RCC_LSEConfig(RCC_LSE_ON);   //打开LSE时钟
  while(!(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==SET));   //等待LSE时钟精密校准完成
  while(!(RTC_WaitForSynchro() == SUCCESS));   //等待LSE时钟和RTC同步完成
  RTC_WriteProtectionCmd(DISABLE);  //写DISABLE,是失能写保护功能 
  while(!(RTC_EnterInitMode() == SUCCESS) ); //等待进入初始化模式完成
  //初始化RTC
  rtc.RTC_AsynchPrediv= 127;  //异步,寄存器已经+1
  rtc.RTC_HourFormat=RTC_HourFormat_24;   //24小时制
  rtc.RTC_SynchPrediv=255;   //同步,寄存器已经+1
  RTC_Init(&rtc);   //初始化RTC  
  //设置时间
  rtcTime.RTC_Hours=hour;  //时
  rtcTime.RTC_Minutes=minute; //分
  rtcTime.RTC_Seconds=second; //秒
  RTC_SetTime(RTC_Format_BIN, &rtcTime);  
  //设置日期
  rtcDate.RTC_Year=Year;   //年
  rtcDate.RTC_Month=month; //月
  rtcDate.RTC_Date=day;   //日
  rtcDate.RTC_WeekDay=WeekDay;  //星期
  RTC_SetDate(RTC_Format_BIN, &rtcDate);
  RTC_WriteProtectionCmd(ENABLE);  //开启写保护功能
}

2345_image_file_copy_82.jpg

7.6 代码实现(RTC备份区--复位不修改时间)

#include "rtc.h"                  // Device header
#include "stdio.h" 
void RTC_Time_Init(u16 Year, u16 month, u16 day,u16 hour,u16 minute,u16 second,u16 WeekDay)
{
  RTC_InitTypeDef rtc;
  RTC_TimeTypeDef rtcTime;
  RTC_DateTypeDef rtcDate;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);  //PWR控制写保护的电源/备份区电源
  PWR_BackupAccessCmd(ENABLE);   //使能PWR备份域电源
  PWR_BackupRegulatorCmd(ENABLE);  //使能RTC备份寄存器
  //1、选择RTC时钟源为LSE
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);   //RTC选择LSE外部低速时钟
  RCC_RTCCLKCmd(ENABLE);    //使能RTC时钟
  //2、打开LSE时钟
  RCC_LSEConfig(RCC_LSE_ON);   
  while(!(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==SET));   //等待LSE时钟校准完成
  while(!(RTC_WaitForSynchro() == SUCCESS));   //等待LSE时钟和RTC进行同步完成
  RTC_WriteProtectionCmd(DISABLE);  //写DISABLE,是失能写保护功能   
  if(RTC_ReadBackupRegister(RTC_BKP_DR0)!=0xaa)  //读备份区,判断是否初始化过
  { 
    while(!(RTC_EnterInitMode() == SUCCESS) ); //使能初始化之前,必须先关闭写保护,等待进入初始化模式完成
    //初始化RTC
    rtc.RTC_AsynchPrediv= 127;  //异步,寄存器已经+1
    rtc.RTC_HourFormat=RTC_HourFormat_24;   //24小时制
    rtc.RTC_SynchPrediv=255;   //同步,寄存器已经+1
    RTC_Init(&rtc);   //初始化RTC    
    //设置时间
    rtcTime.RTC_Hours=hour;  //时
    rtcTime.RTC_Minutes=minute; //分
    rtcTime.RTC_Seconds=second; //秒
    RTC_SetTime(RTC_Format_BIN, &rtcTime);    
    //设置日期
    rtcDate.RTC_Year=Year;   //年
    rtcDate.RTC_Month=month; //月
    rtcDate.RTC_Date=day;   //日
    rtcDate.RTC_WeekDay=WeekDay;  //星期
    RTC_SetDate(RTC_Format_BIN, &rtcDate);
    RTC_WriteBackupRegister(RTC_BKP_DR0, 0xaa);   //写入备份区0xaa,记录已经初始化化过一次了      
  }
  RTC_WriteProtectionCmd(ENABLE);  //开启写保护功能
}

2345_image_file_copy_83.jpg

复位后时间没有改变的;

7.7 代码实现(LCD显示+动态修改RTC时间日期)

#include "rtc.h"                  // Device header
#include "stdio.h" 
void RTC_Time_Init(u16 Year, u16 month, u16 day,u16 hour,u16 minute,u16 second,u16 WeekDay)
{
  RTC_InitTypeDef rtc;
  RTC_TimeTypeDef rtcTime;
  RTC_DateTypeDef rtcDate;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);  //PWR控制写保护的电源/备份区电源
  PWR_BackupAccessCmd(ENABLE);   //使能PWR备份域电源
  PWR_BackupRegulatorCmd(ENABLE);  //使能RTC备份寄存器
  //1、选择RTC时钟源为LSE
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);   //RTC选择LSE外部低速时钟
  RCC_RTCCLKCmd(ENABLE);    //使能RTC时钟
  //2、打开LSE时钟
  RCC_LSEConfig(RCC_LSE_ON);   
  while(!(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==SET));   //等待LSE时钟校准完成
  while(!(RTC_WaitForSynchro() == SUCCESS));   //等待LSE时钟和RTC进行同步完成
  RTC_WriteProtectionCmd(DISABLE);  //写DISABLE,是失能写保护功能   
  if(RTC_ReadBackupRegister(RTC_BKP_DR0)!=0xaa)  //读备份区,判断是否初始化过
  { 
    while(!(RTC_EnterInitMode() == SUCCESS) ); //使能初始化之前,必须先关闭写保护,等待进入初始化模式完成
    //初始化RTC
    rtc.RTC_AsynchPrediv= 127;  //异步,寄存器已经+1
    rtc.RTC_HourFormat=RTC_HourFormat_24;   //24小时制
    rtc.RTC_SynchPrediv=255;   //同步,寄存器已经+1
    RTC_Init(&rtc);   //初始化RTC    
    //设置时间
    rtcTime.RTC_Hours=hour;  //时
    rtcTime.RTC_Minutes=minute; //分
    rtcTime.RTC_Seconds=second; //秒
    RTC_SetTime(RTC_Format_BIN, &rtcTime);    
    //设置日期
    rtcDate.RTC_Year=Year;   //年
    rtcDate.RTC_Month=month; //月
    rtcDate.RTC_Date=day;   //日
    rtcDate.RTC_WeekDay=WeekDay;  //星期
    RTC_SetDate(RTC_Format_BIN, &rtcDate);
    RTC_WriteBackupRegister(RTC_BKP_DR0, 0xaa);   //写入备份区0xaa,记录已经初始化化过一次了      
  }
  RTC_WriteProtectionCmd(ENABLE);  //开启写保护功能
}
void RTC_Set_time(u16 hour,u16 minute,u16 second)
{
  RTC_TimeTypeDef rtcTime;
  RTC_WriteProtectionCmd(DISABLE);  //写DISABLE,是失能写保护功能 
  while(!(RTC_EnterInitMode() == SUCCESS) ); //使能初始化之前,必须先关闭写保护,等待进入初始化模式完成
      //设置时间
  rtcTime.RTC_Hours=hour;  //时
  rtcTime.RTC_Minutes=minute; //分
  rtcTime.RTC_Seconds=second; //秒
  RTC_SetTime(RTC_Format_BIN, &rtcTime);
  RTC_WriteProtectionCmd(ENABLE);  //开启写保护功能  
}
void RTC_Set_date(u16 Year, u16 month, u16 day,u16 WeekDay)
{
  RTC_DateTypeDef rtcDate;
  RTC_WriteProtectionCmd(DISABLE);  //写DISABLE,是失能写保护功能 
  while(!(RTC_EnterInitMode() == SUCCESS) ); //使能初始化之前,必须先关闭写保护,等待进入初始化模式完成
  rtcDate.RTC_Year=Year;   //年
  rtcDate.RTC_Month=month; //月
  rtcDate.RTC_Date=day;   //日
  rtcDate.RTC_WeekDay=WeekDay;  //星期
  RTC_SetDate(RTC_Format_BIN, &rtcDate);
  RTC_WriteProtectionCmd(ENABLE);  //开启写保护功能  
}
相关文章
|
2月前
|
监控 网络协议 安全
验证嵌入式ARM32环境中4G模块的有效方法
验证嵌入式ARM32环境中4G模块的有效方法
100 0
|
3天前
|
存储 Ubuntu 编译器
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(三)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(三)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(三)
|
3天前
|
Ubuntu Unix Linux
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(一)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(一)
|
3天前
|
Linux 编译器 语音技术
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(二)
合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(二)
|
4天前
|
存储 算法 Linux
详细解读ARM嵌入式整理
详细解读ARM嵌入式整理
|
2月前
|
物联网 编译器 测试技术
【嵌入式 交叉编译器】如何在 ARM 架构下选择和使用高版本交叉编译器
【嵌入式 交叉编译器】如何在 ARM 架构下选择和使用高版本交叉编译器
560 7
|
2月前
|
安全 Unix Linux
【ARM】在NUC977上搭建基于boa的嵌入式web服务器
【ARM】在NUC977上搭建基于boa的嵌入式web服务器
|
2月前
|
存储 机器学习/深度学习 人工智能
嵌入式中一文搞懂ARM处理器架构
嵌入式中一文搞懂ARM处理器架构
82 1
|
11月前
|
编译器 C语言
ARM与C语言的混合编程【嵌入式系统】
ARM与C语言的混合编程【嵌入式系统】
99 0
|
11月前
|
存储 芯片
ARM简单程序设计【嵌入式系统】
ARM简单程序设计【嵌入式系统】
124 0