第十三章 RTC 实时时钟

 第十三章 RTC 实时时钟

目录

 第十三章 RTC 实时时钟

1 RTC简介

1.1 主要特性

2 功能描述

2.1 概述

2.2 复位过程

2.3 读RTC寄存器

2.4 配置RTC寄存器

2.5 RTC标志的设置

3 RTC寄存器描述

3.1 RTC控制寄存器高位(RTC_CRH)

3.2 RTC控制寄存器低位(RTC_CRL)

3.3 RTC预分频装载寄存器(RTC_PRLH/RTC_PRLL)

3.4 RTC预分频器余数寄存器(RTC_DIVH/RTC_DIVL)

3.5 RTC计数器寄存器(RTC_CNTH/RTC_CNTL)

3.6 RTC闹钟寄存器(RTC_ALRH/RTC_ALRL)

3.7 RTC寄存器映像

4 程序设计

4.1 RTC_Calendar例程

4.2 RTC_LSICalib例程

5 下载验证

5.1 RTC_Calendar例程

5.2 RTC_LSICalib例程


本章分为如下几个小节:

1 RTC简介

2 功能描述

3 RTC寄存器描述

4 程序设计

5 下载验证

1 RTC简介

        实时时钟是一个独立的定时器。RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。

        RTC 模块和时钟配置系统(RCC_BDCR 寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC 的设置和时间维持不变。系统复位后,对后备寄存器和 RTC 的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。

执行以下操作将使能对后备寄存器和 RTC 的访问:

  • 设置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位,使能电源和后备接口时钟
  • 设置寄存器 PWR_CR 的 DBP 位,使能对后备寄存器和 RTC 的访问。

1.1 主要特性

W55MH32的RTC的主要特性如下:

  • 可编程的预分频系数:分频系数最高为 220。
  • 32 位的可编程计数器,可用于较长时间段的测量。
  • 2 个分离的时钟:用于 APB1 接口的 PCLK1 和 RTC 时钟(RTC 时钟的频率必须小于 PCLK1 时钟频率的四分之一以上)。
  • 可以选择以下三种 RTC 的时钟源:
    • HSE 时钟除以 128;
    • LSE 振荡器时钟;
    • LSI 振荡器时钟(详见 6.2.8 节 RTC 时钟)。
  • 2 个独立的复位类型:
    • APB1 接口由系统复位;
    • RTC 核心(预分频器、闹钟、计数器和分频器)只能由后备域复位(详见 6.1.3 节)。
  • 3 个专门的可屏蔽中断:
    • 闹钟中断,用来产生一个软件可编程的闹钟中断。
    • 秒中断,用来产生一个可编程的周期性中断信号(最长可达 1 秒)。
    • 溢出中断,指示内部可编程计数器溢出并回转为 0 的状态。

2 功能描述

2.1 概述

        RTC 由两个主要部分组成(参见下图)。第一部分(APB1 接口)用来和 APB1 总线相连。此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总线时钟驱动,用来与 APB1 总线接口。

        另一部分(RTC 核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是 RTC 的预分频模块,它可编程产生最长为 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个TR_CLK 周期中 RTC 产生一个中断(秒中断)。第二个模块是一个 32 位的可编程计数器,可被初始化为当前的系统时间。系统时间按 TR_CLK 周期累加并与存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。

简化的 RTC 框图

2.2 复位过程

        除了 RTC_PRL、RTC_ALR、RTC_CNT 和 RTC_DIV 寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。

2.3 读RTC寄存器

        RTC 核完全独立于 RTCAPB1 接口。

        软件通过 APB1 接口访问 RTC 的预分频值、计数器值和闹钟值。但是,相关的可读寄存器只在与RTCAPB1 时钟进行重新同步的 RTC 时钟的上升沿被更新。RTC 标志也是如此的。这意味着,如果 APB1 接口曾经被关闭,而读操作又是在刚刚重新开启 APB1 之后,则在第一次的内部寄存器更新之前,从 APB1 上读出的 RTC 寄存器数值可能被破坏了(通常读到 0)。下述几种情况下能够发生这种情形:

发生系统复位或电源复位

系统刚从待机模式唤醒(参见第 18.3节:低功耗模式)。

系统刚从停机模式唤醒(参见第 18.3节:低功耗模式)。

        所有以上情况中,APB1 接口被禁止时(复位、无时钟或断电)RTC 核仍保持运行状态。

        因此,若在读取 RTC 寄存器时,RTC 的 APB1 接口曾经处于禁止状态,则软件首先必须等待RTC_CRL 寄存器中的 RSF 位(寄存器同步标志)被硬件置'1')。

        注: RTC 的 APB1 接口不受 WFI 和 WFE 等低功耗模式的影响。

2.4 配置RTC寄存器

        必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入 RTC_PRL、RTC_CNT、RTC_ALR 寄存器。

        另外,对 RTC 任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询 RTC_CR寄存器中的 RTOFF 状态位,判断 RTC 寄存器是否处于更新中。仅当 RTOFF 状态位是'1'时,才可以写入 RTC 寄存器。

配置过程:

1. 查询 RTOFF 位,直到 RTOFF 的值变为'1'

2. 置 CNF 值为 1,进入配置模式

3. 对一个或多个 RTC 寄存器进行写操作

4. 清除 CNF 标志位,退出配置模式

5. 查询 RTOFF,直至 RTOFF 位变为'1'以确认写操作已经完成。仅当 CNF 标志位被清除时,写操作才能进行,这个过程至少需要 3 个 RTCCLK 周期。

2.5 RTC标志的设置

        在每一个 RTC 核心的时钟周期中,更改 RTC 计数器之前设置 RTC 秒标志(SECF)。在计数器到达0x0000 之前的最后一个 RTC 时钟周期中,设置 RTC 溢出标志(OWF)。

        在计数器的值到达闹钟寄存器的值加 1(RTC_ALR+1)之前的 RTC 时钟周期中,设置 RTC_Alarm 和RTC 闹钟标志(ALRF)。对 RTC 闹钟的写操作必须使用下述过程之一与 RTC 秒标志同步:

        使用 RTC 闹钟中断,并在中断处理程序中修改 RTC 闹钟和/或 RTC 计数器。

        等待 RTC 控制寄存器中的 SECF 位被设置,再更改 RTC 闹钟和/或 RTC 计数器。

RTC 秒和闹钟波形图示例,PR=0003,ALARM=00004

RTC 溢出波形图示例,PR=0003

3 RTC寄存器描述

3.1 RTC控制寄存器高位(RTC_CRH)

偏移地址:0x00

复位值:0x0000

        这些位用来屏蔽中断请求。注意:系统复位后所有的中断被屏蔽,因此可通过写 RTC 寄存器来确保在初始化后没有挂起的中断请求。当外设正在完成前一次写操作时(标志位 RTOFF=0),不能对RTC_CRH 寄存器进行写操作。RTC 功能由这个控制寄存器控制。

3.2 RTC控制寄存器低位(RTC_CRL)

偏移地址:0x00

复位值:0x0000

注:1.任何标志位都将保持挂起状态,直到适当的 RTC_CR 请求位被软件复位,表示所请求的中断已经被接受。

2.在复位时禁止所有中断,无挂起的中断请求,可以对 RTC 寄存器进行写操作。

3.当 APB1 时钟不运行时,OWF、ALRF、SECF 和 RSF 位不被更新。

4.OWF、ALRF、SECF 和 RSF 位只能由硬件置位,由软件来清零。

5.若 ALRF=1 且 ALRIE=1,则允许产生 RTC 全局中断。如果在 EXTI 控制器中允许产生 EXTI 线 17 中断,则允许产生 RTC 全局中断和 RTC 闹钟中断。

6.若 ALRF=1,如果在 EXTI 控制器中设置了 EXTI 线 17 的中断模式,则允许产生 RTC 闹钟中断;如果在 EXTI 控制器中设置了 EXTI 线 17 的事件模式,则这条线上会产生一个脉冲(不会产生 RTC闹钟中断)。

3.3 RTC预分频装载寄存器(RTC_PRLH/RTC_PRLL)

        预分频装载寄存器用来保存 RTC 预分频器的周期计数值。它们受 RTC_CR 寄存器的 RTOFF 位保护,仅当 RTOFF 值为'1'时允许进行写操作。

RTC 预分频装载寄存器高位(RTC_PRLH)

偏移地址:0x08

复位值:0x0000

RTC 预分频装载寄存器低位(RTC_PRLL)

偏移地址:0x0C

复位值:0x8000

        注: 如果输入时钟频率(fRTCCLK)为 32.768 千赫,则在此寄存器中写入 7FFFh 以获得 1 秒的信号周期

3.4 RTC预分频器余数寄存器(RTC_DIVH/RTC_DIVL)

        在 TR_CLK 的每个周期里,RTC 预分频器中计数器的值都会被重新设置为 RTC_PRL 寄存器的值。用户可通过读取 RTC_DIV 寄存器,以获得预分频计数器的当前值,而不停止分频计数器的工作,从而获得精确的时间测量。此寄存器是只读寄存器,其值在 RTC_PRL 或 RTC_CNT 寄存器中的值发生改变后,由硬件重新装载。

RTC 预分频器余数寄存器高位(RTC_DIVH)

偏移地址:0x10

复位值:0x0000

RTC 预分频器余数寄存器低位(RTC_DIVL)

偏移地址:0x14

复位值:0x8000

3.5 RTC计数器寄存器(RTC_CNTH/RTC_CNTL)

        RTC 核有一个 32 位可编程的计数器,可通过两个 16 位的寄存器访问。计数器以预分频器产生的TR_CLK时间基准为参考进行计数。RTC_CNT寄存器用来存放计数器的计数值。他们受 RTC_CR的位RTOFF写保护,仅当RTOFF值为'1'时,允许写操作。在高或低寄存器(RTC_CNTH或RTC_CNTL)上的写操作,能够直接装载到相应的可编程计数器,并且重新装载 RTC 预分频器。当进行读操作时,直接返回计数器内的计数值(系统时间)。

RTC 计数器寄存器高位(RTC_CNTH)

偏移地址:0x18

复位值:0x0000

RTC 计数器寄存器低位(RTC_CNTL)

偏移地址:0x1C

复位值:0x0000

3.6 RTC闹钟寄存器(RTC_ALRH/RTC_ALRL)

        当可编程计数器的值与 RTC_ALR 中的 32 位值相等时,即触发一个闹钟事件,并且产生 RTC 闹钟中断。此寄存器受 RTC_CR 寄存器里的 RTOFF 位写保护,仅当 RTOFF 值为'1'时,允许写操作。

RTC 闹钟寄存器高位(RTC_ALRH)

偏移地址:0x20

复位值:0xFFFF

RTC 闹钟寄存器低位(RTC_ALRL)

偏移地址:0x24

复位值:0xFFFF

3.7 RTC寄存器映像

RTC-寄存器映像和复位值

4 程序设计

4.1 RTC_Calendar例程

1.初始化部分:延时初始化:调用delay_init()函数,虽未展示其具体实现,但为程序提供时间相关基础功能。

  • 时钟配置:RCC_ClkConfiguration()函数对系统时钟进行配置。先复位 RCC,开启 HSE 并等待其就绪,配置 PLL 为 HSE 经 1 分频后输入,9 倍频输出,使能 PLL 并等待其就绪,选择 PLLCLK 作为系统时钟源,同时设置 HCLK、PCLK1 和 PCLK2 的分频因子,还开启 LSI 和 HSI。
  • 串口初始化:UART_Configuration()函数配置 USART1 串口。使能 USART1 和 GPIOA 时钟,将 PA9 配置为复用推挽输出(TX),PA10 配置为浮空输入(RX),设置波特率为 115200,数据位 8 位,停止位 1 位,无校验,无硬件流控制,工作模式为收发模式,最后使能串口。
  • NVIC 配置:NVIC_Configuration()函数设置 NVIC 优先级分组为 1,使能 RTC 中断,设置其抢占优先级为 1,子优先级为 0。
  • RTC 配置:RTC_Configuration()函数配置 RTC。使能 PWR 和 BKP 时钟,允许访问备份区域,对 BKP 进行初始化,开启 LSI 并等待其就绪,选择 LSI 作为 RTC 时钟源,使能 RTC 时钟并等待同步,设置 RTC 秒中断,设置预分频器为 32767,使 RTC 周期为 1 秒。

2.主循环部分:在main()函数中,先进行延时、时钟配置,接着配置串口,输出 “RTC Calendar Test.” 及系统时钟频率信息。检查 BKP 寄存器值判断 RTC 是否已配置,若未配置则进行 RTC 配置并设置时间,若已配置则判断复位类型并根据情况处理。最后调用Time_Show()函数进入一个循环,当TimeDisplay为 1 时显示当前时间。

3.时间调整与显示部分:时间调整:Time_Adjust()函数调用Time_Regulate()函数获取用户通过串口输入的时分秒,然后设置 RTC 计数器。

// 时间调整函数(通过串口输入设置时间)
void Time_Adjust(void)
{RTC_WaitForLastTask();RTC_SetCounter(Time_Regulate()); // 调用输入函数获取时间并设置RTC计数器RTC_WaitForLastTask();
}
// 时间输入函数(串口交互获取时分秒)
uint32_t Time_Regulate(void)
{uint32_t Tmp_HH, Tmp_MM, Tmp_SS;// 输入小时(0-23)printf("\r\n  Please Set Hours");while ((Tmp_HH = USART_Scanf(23)) == 0xFF);// 输入分钟(0-59)printf("\r\n  Please Set Minutes");while ((Tmp_MM = USART_Scanf(59)) == 0xFF);// 输入秒(0-59)printf("\r\n  Please Set Seconds");while ((Tmp_SS = USART_Scanf(59)) == 0xFF);return (Tmp_HH * 3600 + Tmp_MM * 60 + Tmp_SS); // 返回总秒数
}
// 时间显示函数(实时打印时间)
void Time_Show(void)
{printf("\n\r");while (1){if (TimeDisplay == 1) // TimeDisplay由RTC中断触发置1{Time_Display(RTC_GetCounter()); // 转换并显示时间TimeDisplay = 0;}}
}
// 时间格式化显示
void Time_Display(uint32_t TimeVar)
{uint32_t THH = TimeVar / 3600;uint32_t TMM = (TimeVar % 3600) / 60;uint32_t TSS = TimeVar % 60;// 计数器溢出处理(约24小时归零)if (RTC_GetCounter() == 0x0001517F) {RTC_SetCounter(0);RTC_WaitForLastTask();}printf("Time: %02d:%02d:%02d\n", THH, TMM, TSS);
}

        时间显示:Time_Show()函数进入一个循环,当TimeDisplay为 1 时,调用Time_Display()函数获取 RTC 计数器的值并转换为时、分、秒格式进行显示。同时,Time_Display()函数还会在 RTC 计数器达到特定值(0x0001517F)时将其重置为 0。

4.串口输入处理部分:USART_Scanf()函数用于从串口接收用户输入的数字,检查输入是否为有效数字,若无效则提示用户重新输入,直到输入有效数字。

4.2 RTC_LSICalib例程

1.初始化部分:延时初始化:调用delay_init()函数,虽未给出其具体实现,但为程序提供时间相关的基础功能。

// 1. 延时初始化(依赖delay.h实现)
delay_init();// 1.a 串口初始化
void UART_Configuration(uint32_t bound)
{// 使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);// 配置TX/RX引脚GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;  // PA9-TXGPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;  // PA10-RXGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置串口参数USART_InitStructure.USART_BaudRate = bound;  // 115200bpsUSART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);
}// 1.b RTC配置
void RTC_Configuration(void)
{// 使能电源和备份域时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);PWR_BackupAccessCmd(ENABLE);BKP_DeInit();  // 复位备份域// 配置RTC时钟源(LSI)RCC_LSICmd(ENABLE);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);RCC_RTCCLKCmd(ENABLE);RTC_WaitForSynchro();  // 等待RTC寄存器同步RTC_ITConfig(RTC_IT_SEC, ENABLE);  // 使能秒中断RTC_SetPrescaler(40000);  // 预设预分频值(假设LSI=40kHz)// 配置RTC输出BKP_TamperPinCmd(DISABLE);BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);
}// 1.c 定时器配置(TIM5用于测量LSI频率)
void TIM_Configuration(void)
{// 使能时钟和引脚重映射RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE);// 配置TIM5时基TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_Period = 0xFFFF;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);// 配置TIM5通道4为输入捕获模式TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM_ICInitStructure.TIM_ICFilter = 0;TIM_ICInit(TIM5, &TIM_ICInitStructure);// 使能TIM5和捕获中断TIM_Cmd(TIM5, ENABLE);TIM5->SR = 0;  // 清除中断标志TIM_ITConfig(TIM5, TIM_IT_CC4, ENABLE);
}// 1.d NVIC中断配置
void NVIC_Configuration(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  // 优先级分组1// 配置RTC中断(最高优先级)NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 配置TIM5中断(次高优先级)NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}

        串口初始化:UART_Configuration()函数配置 USART1 串口。使能 USART1 和 GPIOA 时钟,将 PA9 配置为复用推挽输出(用于 TX 发送),PA10 配置为浮空输入(用于 RX 接收)。设置串口波特率为 115200,数据位 8 位,停止位 1 位,无校验位,无硬件流控制,工作模式为同时接收和发送,并最终使能串口。

        RTC 配置:RTC_Configuration()函数对 RTC 进行配置。使能 PWR 和 BKP 时钟,允许访问备份区域,对 BKP 进行初始化。开启 LSI,选择 LSI 作为 RTC 时钟源,使能 RTC 时钟并等待同步,设置 RTC 秒中断,设置预分频器为 40000,禁用 BKP 篡改引脚,配置 RTC 输出为秒信号。

        定时器配置:TIM_Configuration()函数对 TIM5 进行配置。使能 AFIO 和 TIM5 时钟,重映射 TIM5 通道 4 到 LSI。设置 TIM5 的预分频器为 0,计数模式为向上计数,周期为 0xFFFF,时钟分频为 1。配置 TIM5 通道 4 为输入捕获模式,上升沿触发,直接映射到 TI,不分频,无滤波。使能 TIM5,清除状态寄存器,使能 TIM5 通道 4 捕获中断。

        NVIC 配置:NVIC_Configuration()函数设置 NVIC 优先级分组为 1。使能 RTC 中断,设置其抢占优先级为 0,子优先级为 0;使能 TIM5 中断,设置子优先级为 2。

2.主循环部分:在main()函数中,先进行延时初始化,接着配置串口,输出 “RTC LSI Calib Test.” 及系统时钟频率信息。然后进行 RTC、TIM5 配置和 NVIC 配置。等待OperationComplete变为 2,这意味着 TIM5 测量操作完成。当OperationComplete为 2 时,计算 LSI 的实际频率,并根据该频率设置 RTC 的预分频器,最后进入无限循环while(1)。

int main(void)
{// 系统初始化delay_init();UART_Configuration(115200);printf("RTC LSI Calib Test.\n");RCC_GetClocksFreq(&clocks);printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);// 外设初始化RTC_Configuration();TIM_Configuration();NVIC_Configuration();// 2. 等待TIM5测量完成(OperationComplete=2)while (OperationComplete != 2);// 计算LSI实际频率并校准RTCif (PeriodValue != 0){// LSI频率 = (2*PCLK1)/PeriodValueLsiFreq = (uint32_t)((uint32_t)(clocks.PCLK1_Frequency * 2) / (uint32_t)PeriodValue);}printf("LsiFreq: %d Hz\n", LsiFreq);// 根据测量结果校准RTC预分频器RTC_SetPrescaler(LsiFreq - 1);RTC_WaitForLastTask();// 无限循环while (1);
}

3.辅助函数部分:IncrementVar_OperationComplete()函数使OperationComplete变量自增,并返回自增前的值。

// 3.a 递增OperationComplete并返回旧值
uint32_t IncrementVar_OperationComplete(void)
{OperationComplete++;return (uint32_t)(OperationComplete - 1);
}// 3.b 获取OperationComplete值
uint32_t GetVar_OperationComplete(void)
{return (uint32_t)OperationComplete;
}// 3.c 设置PeriodValue值
void SetVar_PeriodValue(uint32_t Value)
{PeriodValue = (uint32_t)(Value);
}

GetVar_OperationComplete()函数返回OperationComplete变量的值。

SetVar_PeriodValue()函数设置PeriodValue变量的值。

5 下载验证

5.1 RTC_Calendar例程

5.2 RTC_LSICalib例程

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

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

相关文章

618来了,推荐京东云服务器

2核2G3M,49元/1年,348元/3年 2核4G5M,149元/1年,518元/3年 4核8G5M,368元/1年,1468元/3年 8核16G5M,1258元/1年,3498元/3年 8核32G10M,1498元/1年,4268元/3年 活动地址:https://3.cn/2hT-F6AX

数据库逻辑删除,唯一性约束究极解决方案

文章目录 一、写在前面二、解决方案1、业务逻辑层面控制2、物理删除数据归档3、is_delete !0的都认为是删除(推荐)4、MySQL 函数索引(表达式索引)(需 MySQL 8.0)(推荐)5、部分索引&a…

3-存储系统

一-基本概念 二-主存储器 三-主存储器与CPU的连接 四-外部存储器 五-高速缓冲存储器 六-虚拟存储器

华为0528笔试

第三题 题目 给定一个二维数组 mountainMap 表示一座山的地图,数组中的每个元素 mountainMap[x][y] 代表坐标 (x, y) 处山的高度。登山员从山底出发,爬到山峰。 山底的含义:mountainMap中高度为0的坐标点。 山峰的含义:mountain…

Redis的过期策略和淘汰策略

Redis的过期策略和淘汰策略 想象一下周末的大型超市:生鲜区的酸奶贴着"今日特价"标签,促销员定时检查这些商品的保质期;而仓库管理员正根据"先进先出"原则整理货架,确保商品不会过期积压。这种高效的商品管理…

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …

【HarmonyOS 5】 影视与直播详以及 开发案例

&#x1f3a5; ‌一、超高清低延迟直播‌ ‌4K/8K硬解能力‌&#xff1a;通过鸿蒙媒体引擎实现15Mbps码率视频流稳定解码&#xff0c;华为Pura X实测端到端延迟<80ms‌分布式渲染‌&#xff1a;支持手机拍摄→智慧屏导播→平板监看的工作流协同&#xff0c;设备间传输延迟&…

Tunna工具实战:基于HTTP隧道的RDP端口转发技术

工具概述 Tunna是一款利用HTTP/HTTPS隧道进行TCP通信的渗透测试工具&#xff0c;由SECFORCE团队开发并开源。该工具主要应用于需要绕过防火墙限制的场景&#xff0c;通过Webshell实现内网服务的端口转发&#xff0c;特别适合在仅开放80/443端口的环境中建立TCP连接。 项目地址…

c# Autorest解析

AutoRest 工具生成用于访问 RESTful Web 服务的客户端库。AutoRest 的输入是使用 OpenAPI 规范格式描述 REST API 的规范。OpenAPI(f.k.a Swagger)规范代码生成器。支持 C#、PowerShell、Go、Java、Node.js、TypeScript、Python。 安装 AutoRest 在 Windows、MacOS 或 Linux …

高中数学联赛模拟试题精选学数学系列第24套几何题

⊙ O 1 \odot O_1 ⊙O1​ 和 ⊙ O 2 \odot O_2 ⊙O2​ 交于 A A A, B B B. Y Y Y 是 ⊙ O 1 \odot O_1 ⊙O1​ 上一点, Z Z Z 是 ⊙ O 2 \odot O_2 ⊙O2​ 上一点&#xff0c; Y Z YZ YZ 通过 A A A. 过 Y Y Y 的 ⊙ O 1 \odot O_1 ⊙O1​ 的切线和过 Z Z Z 的 ⊙…

【QT】INI格式文件读写类IniApi封装

【QT】INI文件读写类IniApi封装 前言实现INI文件写入方法INI文件读取方法 测试 前言 INI格式文件是一种纯文本格式&#xff0c;使用方括[]定义节&#xff08;Section&#xff09;&#xff0c;每个节下包含键值对&#xff0c;如下图所示。该格式文件简单易读易编辑。而且在所有…

ABAP设计模式之---“童子军法则(The Boy Scout Rule)”

法则介绍 The Boy Scout Rule&#xff0c;中文一般翻译为“童子军法则”&#xff0c;是一个简单却非常有意义的软件开发原则&#xff0c;它最早由软件开发大师 Robert C. Martin (Uncle Bob) 在他的《Clean Code》一书中提出。 这条法则的核心思想非常简单&#xff1a; “确保…

BaikalDB 架构演进实录:打造融合向量化与 MPP 的 HTAP 查询引擎

导读 BaikalDB作为服务百度商业产品的分布式存储系统&#xff0c;支撑了整个广告库海量物料的存储和OLTP事务处理。随着数据不断增长&#xff0c;离线计算时效性和资源需求压力突显&#xff0c;基于同一份数据进行OLAP处理也更为经济便捷&#xff0c;BaikalDB如何在OLTP系统内…

【抖音小程序】通用交易系统-下单问题整理

在通用交易系统中&#xff0c;支付流程如下 1、服务端-预下单&#xff1a;生成参数与签名信息&#xff08;此过程不需要与抖音平台对接&#xff09; 参考 生成下单参数与签名_抖音开放平台 2、小程序用户端&#xff1a;根据返回的参数与签名&#xff0c;拉起抖音支付&#x…

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…

EurekaServer 工作原理

一、核心工作流程 二、核心组件解析 1. 自动配置引擎 入口&#xff1a;EnableEurekaServer 引入 EurekaServerMarkerConfiguration&#xff0c;创建标记Bean Marker触发条件&#xff1a;EurekaServerAutoConfiguration 检测到 Marker 存在时激活关键Bean初始化&#xff1a; …

Playwright 与 Selenium:自动化测试的两大主流工具对比

《Playwright 与 Selenium&#xff1a;自动化测试的两大主流工具对比》 *Playwright 和 Selenium 是自动化测试领域的两大主流工具&#xff0c;二者在架构设计、功能特性和适用场景上存在显著差异&#xff0c;以下是核心对比&#xff1a; 一、架构与设计理念 维度Playwright…

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

R语言速释制剂QBD解决方案之二

影响含量均一性的显著因子&#xff08;%RSD&#xff09; 数据分析表明含量均一性的弯曲性不显著。如半正态图&#xff08;图12&#xff09;所示&#xff0c;影响含量均一性的显著因子为A&#xff08;原料药粒径&#xff09;和C&#xff08;MCC/Lactose&#xff09;。 mod2 <…

大模型原理、架构与落地

近年来&#xff0c;大模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;在人工智能领域迅猛发展&#xff0c;从GPT-3到GPT-4、Claude、Gemini、文心一言、GLM等模型相继发布&#xff0c;大模型已逐渐走出实验室&#xff0c;迈向产业落地。本文将从技术原理、…