当前位置: 首页 > news >正文

细说STM32F407单片机RTC的基本原理及闹钟和周期唤醒功能的使用方法

目录

一、RTC基础知识

1、 RTC的功能

2、RTC工作原理

(1)RTC的时钟信号源

(2)预分频器

(3)实时时钟和日历数据

(4)周期性自动唤醒

(5)可编程闹钟

(6)时间戳

(7)入侵检测

(8)数字校准

(9)RTC参考时钟检测

3、RTC的中断和复用引脚

二、RTC的HAL基础驱动

1、RTC初始化

2、读取和设置日期

3、读取和设置时间

4、二进制数与BCD码之间的转换

5、判断函数

三、周期唤醒和闹钟

1、周期唤醒相关HAL函数

(1)宏函数

(2)周期唤醒定时器

(3)周期唤醒中断回调函数

2、闹钟相关HAL函数

四、案例:闹钟及周期唤醒功能的用法

1、工程简介

2、项目配置

(1)时钟、DEBUG、CodeGenerator

(2) RTC

1)RTC模式设置

2)RTC基本参数设置

3)闹钟定时设置

4)周期唤醒设置

(3)USART6

(4) NVIC

3、软件设计

(1)main.c

(2)rtc.c

4、运行与调试


        实时时钟(Real-Time Clock,RTC)是由时钟信号驱动的日历时钟,提供日期和时间数据。STM32F407上有一个RTC,可以由备用电源VBAT供电,从而提供不间断的日期时间数据。它还有两个可编程闹钟,一个周期唤醒单元,使用RTC可以实现一些时间日历相关的应用。

一、RTC基础知识

1、 RTC的功能

        STM32F407有一个片上RTC,它可以由内部或外部时钟信号驱动,提供日历时间数据,它内部维护一个日历,能自动确定每个月的天数,能自动处理闰年情况,还可以设定夏令时补偿。RTC能提供BCD或二进制的秒、分钟、小时(12或24小时制)、星期几、曰期、月份、年份数据,还可以提供二进制的亚秒数据。

        RTC及其时钟都使用备用存储区域,而备用存储区域使用VBAT备用电源(一般用纽扣电池作为VBAT电源),所以即使主电源断电或系统复位也不影响RTC的工作。

        RTC有两个可编程闹钟,可以设定任意组合和重复性的闹钟;有一个周期唤醒单元,可以作为一个普通定时器使用;还具有时间戳和入侵检测功能。

2、RTC工作原理

        RTC的结构所示,从几个方面对RTC的工作原理和特性进行说明。

 

(1)RTC的时钟信号源

        从上图,RTC可以从3个时钟信号中选择一个作为RTC的时钟信号源。

  • LSI,MCU内部的32kHz时钟信号。
  • LSE,MCU外接的32.768kHz时钟信号。
  • HSE_RTC,HSE经过2到31分频后的时钟信号。

        如果MCU有外接的32.768kHz晶振,一般选择LSE作为RTC的时钟源,因为32.768kHz经过多次2分频后,可以得到精确的1Hz时钟信号。

(2)预分频器

        RTC的时钟源信号经过精密校准后就是时钟信号RTCCLK,RTCCLK依次要经过一个7位的异步预分频器(最高为128分频)和一个15位的同步预分频器(默认为256分频)。

        如果选用32.768kHz的LSE时钟源作为RTCCLK,经过异步预分频器128分频后的信号ck_apre是256Hz。256Hz的时钟信号再经过同步预分频器256分频后得到1Hz时钟信号ck_spre这个1Hz信号可以用于更新日历,也可以作为周期唤醒单元的时钟源

        ck_apre和ck_spre经过一个选择器后,可以选择其中一个时钟信号作为RTC_CALIB时钟信号,这个时钟信号再经过输出控制选择,可以输出到复用引脚RTC_AF1,也就是可以向外部提供一个256Hz或1Hz的时钟信号。

(3)实时时钟和日历数据

        上图中,有3个影子寄存器,RTC_SSR对应亚秒数据,RTC_TR对应于时间,RTC_DR对应于日期。影子寄存器就是内部亚秒计数器、日历时间计数器的数值暂存寄存器,系统每隔两个RTCCLK周期就将当前的日历值复制到影子寄存器。当程序读取日期时间数据时,读取的是影子寄存器的内容,而不会影响日历计数器的工作。

(4)周期性自动唤醒

        RTC内有一个16位自动重载递减计数器,可以产生周期性的唤醒中断,16位寄存器RTC_WUTR存储用于设置定时周期的自动重载值。周期唤醒定时器的输入时钟有如下两个来源。

  • 同步预分频器输出的ck_spre时钟信号,通常是1Hz。
  • RTCCLK经过2、4、8或16分频后的时钟信号。

        一般可以在周期性唤醒中断里读取RTC当前时间,例如,设置周期唤醒时钟源为1Hz的ck_spre信号,且每秒中断一次。唤醒中断产生事件信号WUTF,这个信号可以配置输出到复用引脚RTC_AF1。

(5)可编程闹钟

        RTC有2个可编程闹钟,即闹钟A和闹钟B。闹钟的时间和重复方式是可以设置的,闹钟触发时可以产生事件信号ALRAF和ALRBF。这两个信号和周期唤醒事件信号WUTF一起经过一个选择器,可以选择其中一个信号作为输出信号RTC_ALARM,再通过输出控制可以输出到复用引脚RTC_AF1。

(6)时间戳

        时间戳(timestamp)就是某个外部事件(上跳沿或下跳沿变化)发生时刻的日历时间,例如,行车记录仪在发生碰撞时保存的发生碰撞时刻的RTC日期时间数据就是时间戳。

        启用RTC的时间戳功能,可以选择复用引脚RTC_AF1或RTC_AF2作为事件源RTC_TS,监测其上跳沿或下跳沿变化。当复用引脚上发生事件时,RTC就将当前的日期时间数据记录到时间戳寄存器,还会产生时间戳事件信号TSF,响应此事件中断就可以读取出时间戳寄存器的委据。如果检测到入侵事件,也可以记录时间戳数据。

(7)入侵检测

        入侵检测(tamper[ˈtæmpər] detection)输入信号源有两个,即RTC_TAMP1和RTC_TAMP2,这两个信号源可以映射到复用引脚RTC_AF1和RTC_AF2。可以配置为边沿检测或带滤波的电平检测。STM32F407上有20个32位备份寄存器,这些备份寄存器是在备份域中的,由备用电源VBAT供电。在系统主电源关闭或复位时,备份寄存器的数据不会丢失,所以可以用于保存用户定义数据。当检测到入侵事件发生时,MCU就会复位这20个备份寄存器的内容。检测到入侵事件时,MCU会产生中断事件信号,同时还会记录时间戳数据。

(8)数字校准

        RTC内部有粗略数字校准和精密数字校准。粗略数字校准需要使用异步预分频器的256Hz时钟信号,校准周期为64min。精密数字校准需要使用同步预分频器输出的1Hz时钟信号,默误模式下校准周期为32s。

        用户可以选择256Hz或1Hz数字校准时钟信号作为校准时钟输出信号RTC_CALIB,通过输出控制可以输出到复用引脚RTC_AF1。

(9)RTC参考时钟检测

        RTC的日历更新可以与一个参考时钟信号RTC_REFIN(通常为50Hz或60Hz)同步,RTC_REFIN使用引脚PB15。参考时钟信号RTC_REFIN的精度应该高于32.768kHz的LSE时钟。启用RTC_REFIN检测时,日历仍然由LSE提供时钟,而RTC_REFIN用于补偿不准确的日历更新频率。

3、RTC的中断和复用引脚

        一般的外设只有一个中断号,一个中断号有多个中断事件源,例如,通用定时器,虽然有多个中断事件源,但只有一个中断号。但是RTC有3个中断号,每个中断号有对应的ISR,如下表所示:

中断号

中断名称

说明

ISR

2

TAMP_STAMP

连接到EXTI 21线的RTC入侵和时间戳中断

TAMP_STAMP_IRQHandler()

3

RTC_WKUP

连接到EXTI22线的RTC唤醒中断

RTC_WKUP_IRQHandler()

41

RTC_Alarm

连接到EXTI17线的RTC闹钟(A和B)中断

RTC_Alarm_IRQHandler()

        RTC的这3个中断号各对应1个到3个中断事件源,例如,RTC_WKUP中断只有1个中断事件源,即周期唤醒中断事件,RTC_Alarm中断有2个中断事件源,即闹钟A中断事件和闹钟B中断事件,而TAMP_STAMP有3个中断事件源。

        在HAL驱动程序中,每个中断事件都对应有表示中断事件类型的宏,每个中断事件对应一个回调函数。中断名称、中断事件类型和回调函数的对应关系如下表所示。基于这个表,在处理某个中断事件时,就只需重新实现其回调函数即可。

中断名称

中断事件源

中断事件类型

输出或输入
引脚

回调函数

RTC_Alarm

闹钟A

RTC_IT_ALRA

RTC AF1

HAL_RTC_AlarmAEventCallback()

闹钟B

RTC_IT_ALRB

RTC AF1

HAL_RTCEx_AlarmBEventCallback()

RTC_WKUP

周期唤醒

RTC_IT_WUT

RTC AF1

HAL_RTCEx_WakeUpTimerEventCallback()

TAMP_STAMP

时间戳

RTC_IT_TS

RTC_AF1或
RTC AF2

HAL_RTCEx_TimeStampEventCallback()

入侵检测1

RTC_IT_TAMP1

RTC AF1


RTC AF2

HAL_RTCEx_Tamper1EventCallback()

入侵检测2

RTC_IT_TAMP2

RTC AF1


RTC AF2

HAL_RTCEx_Tamper2EventCallback()

         其中,“中断事件类型”一列中是HAL库中定义的宏,实际上是各中断事件在RTC控制寄存器(RTC_CR)中的中断使能控制位的掩码。这些中断事件类型的宏定义如下: 

#define RTC_IT_TS		0x00008000U
#define RTC_IT_WUT		0x00004000U
#define RTC_IT_ALRB		0x00002000U
#define RTC_IT_ALRA		0x00001000U
#define RTC_IT_TAMP		0x00000004U	/*仅用于使能Tamper中断*/
#define RTC_IT_TAMP1	0x00020000U
#define RTC_IT_TAMP2	0x00040000U

        某些中断事件产生的信号可以选择输出到RTC的复用引脚,某些事件需要外部输入信号。其中,闹钟A、闹钟B和周期唤醒中断的信号可以选择输出到复用引脚RTC_AF1,时间戳事件检测一般使用RTC_AF1作为输入引脚,入侵检测可以使用RTC_AF1或RTC_AF2作为输入引脚。对于STM32F407xx,复用引脚RTC_AF1是引脚PC13,RTC_AF2是引脚PI8。只有176个引脚的MCU上才有PI8,所以,STM32F407ZG上没有RTC_AF2,只有RTC_AF1。

        复用引脚除了可以作为闹钟A、闹钟B和周期唤醒中断信号的输出引脚外,还可以作为两个预分频器时钟的输出引脚,用于输出256Hz或1Hz的时钟信号。

二、RTC的HAL基础驱动

        RTC的HAL驱动程序头文件有两个,即stm32f4xx_hal_rtc.h和stm32f4xx_hal_rtc_ex.h针对RTC、闹钟、周期唤醒、入侵检测分别有一组函数和定义

        RTC的一些通用基础函数如下表所示,包括RTC初始化函数、读取日期和时间的函数设置日期和时间的函数、BCD码与二进制之间转换的函数,以及一些判断函数。

函数名

功能描述

HAL_RTC_Init()

RTC初始化

HAL_RTC_MspInit()

RTC初始化的MSP弱函数,在HAL RTC_Init()中被调用。重新实现的这个函数一般用于RTC中断的设置

HAL_RTC_GetDate()

获取RTC当前日期,返回的日期数据是RTC_DateTypeDef类型结构体

HAL_RTC_SetDate()

设置RTC日期

HAL_RTC_GetTime()

获取RTC当前时间,返回的时间数据是RTC_TimeTypeDef类型结构体

HAL_RTC_SetTime()

设置RTC时间

HAL_RTC_GetState()

返回RTC当前状态,状态是枚举类型HAL_RTCStateTypeDef

RTC_Bcd2ToByte()

2位BCD码转换为二进制数

RTC_ByteToBcd2()

将二进制数转换为2位BCD码

IS_RTC_YEAR(YEAR)

宏函数,判断参数YEAR是否小于100

IS_RTC_MONTH(MONTH)

宏函数,判断参数MONTH是否在1和12之间

IS_RTC_DATE(DATE)

宏函数,判断参数DATE是否在1和31之间

IS_RTC_WEEKDAY(WEEKDAY)

宏函数,判断参数WEEKDAY是否在宏定义常量RTC_WEEKDAY_
MONDAY到RTC_WEEKDAY_SUNDAY之间

IS_RTC_FORMAT(FORMAT)

宏函数,判断参数FORMAT是否为RTC_FORMAT_BIN或
RTC_FORMAT_BCD

IS_RTC_HOUR_FORMAT(FORMAT)

宏函数,判断参数FORMAT是否为RTC_HOURFORMAT_12
或RTC_HOURFORMAT_24

1、RTC初始化

        RTC初始化函数进行RTC初始化的函数是HAL_RTC_Init(),其原型定义如下:

HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc);

        其中,参数hrtc是RTC外设对象指针,是RTC_HandleTypeDef结构体类型指针。结构体RTC_HandleTypeDef的定义如下:

typedef struct
{RTC_TypeDef *Instance;	            //RTC寄存器基地址RTC_InitTypeDef Init;		        //RTC的参数HAL_LockTypeDef Lock;		        //RTC锁定对象__IO HAL_RTCStateTypeDef State;		//时间通信状态
}RTC_HandleTypeDef;

        其中的成员变量Init存储了RTC的各种参数,是RTC_InitTypeDef结构体类型,其原型定义如下:

typedef struct
{uint32_t HourFormat;		//小时数据格式,12小时制或24小时制uint32_t AsynchPrediv;		//异步预分频器值,范围0x00~0x7E,默认值为127uint32_t SynchPrediv;		//同步预分频器值,范围0x00~0x7FFFU,默认值为255uint32_t OutPut;			//哪个信号被作为RTC输出信号uint32_t OutPutPolarity;	//输出信号的极性,信号有效时的电平uint32_t OutPutType;		//输出引脚模式,开漏输出或推挽输出
}RTC_InitTypeDef;

         其中,小时数据的格式取值可以用如下的宏定义常量:

#define RTC_HOURFORMAT_240x00000000U	//24小时制
#define RTC_HOURFORMAT_120x00000040U	//12小时制

2、读取和设置日期

        读取RTC当前日期的函数是HAL_RTC_GetDate(),其原型定义如下:

HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc,RTC_DateTypeDef *sDate,uint32_t Format);

        返回的日期数据保存在RTC_DateTypeDef类型指针sDate指向的变量里,参数Format表示返回日期数据类型是BCD码或二进制码,可以用下面的宏定义常量作为Format的值。

#define RTC_FORMAT_BIN		0x00000000U	//二进制格式
#define RTC_FORMAT_BCD		0x00000001U	//BCD码格式

        日期数据结构体RTC_DateTypeDef的定义如下:

typedef struct
{uint8_t WeekDay;	//星期几,有表示星期几的宏定义uint8_t Month;	    //月份,有表示月份的宏定义uint8_t Date;		//日期,范围1~31uint8_t Year;		//年,范围0~99,表示2000~2099
}RTC_DateTypeDef;

        设置日期的函数是HAL_RTC_SetDate(),其原型定义如下:

HAL_statusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc,RTC_DateTypeDef *sDate.uint32_t Format);

        参数sDate是需要设置的日期数据指针,参数Format表示数据的格式是BCD码或二进制码。

3、读取和设置时间

        读取时间的函数是HAL_RTC_GetTime(),其原型定义如下:

HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc,RTC_TimeTypeDef *sTime.uint32_t Format);

        返回的时间数据保存在RTC_TimeTypeDef类型指针sTime指向的变量里,参数Format表示返回日期数据类型是BCD码或二进制码。

        时间数据结构体RTC_TimeTypeDef的定义如下:

typedef struct
{uint8_t Hours;		        //小时,范围0~12(12小时制),或0~23(24小时制)uint8_t Minutes;		    //分钟,范围0~59uint8_t Seconds;		    //秒,范围0~59uint8_t TimeFormat;		    //时间格式,AM或PM显示uint32_t SubSeconds;	    //亚秒数据uint32_t SecondFraction;	//秒的小数部分数据uint32_t DayLightSaving;	//夏令时设置uint32_t StoreOperation;	//存储操作定义
}RTC_TimeTypeDef;

        一般情况下,只需关心时间的小时、分钟和秒数据,如果是12小时制,还需要看TimeFormat的值。AM/PM的取值使用如下的宏定义:

#define RTC_HOURFORMAT12_AM	((uint8_t)0x00)	//表示AM
#define RTC_HOURFORMAT12_PM	((uint8_t)0x40)	//表示PM

         设置时间的函数是HAL_RTC_SetTime(),其原型定义如下:

HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc,RTC_TimeTypeDef *sTime,int32_t Format);

        任何时候读取日期和读取时间的函数都必须成对使用,即使读出的日期或时间数据用不上。也就是说,调用HAL_RTC_GetTime()之后,必须调用HAL_RTC_GetDate(),否则不能连续更新日期和时间。因为调用HAL_RTC_GetTime()时会锁定日历影子寄存器的当前值,直到日期数据被读出后才会被解锁。

4、二进制数与BCD码之间的转换

        读取和设置RTC的日期或时间数据时,可以指定数据格式为二进制或BCD码,二进制就是常规的数。BCD(Binary Coded Decimal)码是为便于BCD数码管显示用的编码,它用4位二进制数表示十进制中一个位的数,表示的范围是0~9,百位、十位、个位连续排列。

        读取日期或时间的函数中有个Format参数,可以指定为二进制格式(RTC_FORMAT_BIN)或BCD码格式(RTC_FORMAT_BCD),这两种编码的数据之间可以通过HAL提供的两个函数进行转换。这两个函数的原型定义如下,这两个函数只能转换两位数字的数据

uint8_t RTC_Bcd2TOByte(uint8_t Value)		//两位BCD码转换为二进制数
uint8_t RTC_ByteTOBcd2(uint8_t Value)		//二进制数转换为两位BCD码

5、判断函数

        在文件stm32f4xx_hal_rtc.h中有一些以“IS_RTC_”为前缀的宏函数,这些宏函数主要用于判断参数是否在合理范围之内。部分典型的宏函数定义如下,全部的此类函数定义见文件m32f4xx_hal_rtc.h。

#define IS_RTC_YEAR(YEAR)				((YEAR)<=99U)
#define IS_RTC_MONTH(MONTH)			    (((MONTH)>=1U)&&((MONTH)<=12U))
#define IS_RTC_DATE(DATE)				(((DATE)>=1U)&&((DATE)<=31U))
define IS_RTC_HOUR12(HOUR)				(((HOUR)>0U)&&((HOUR)<=12U))
#define IS_RTC_HOUR24(HOUR)			    ((HOUR)<=23U)
#define IS_RTC_ASYNCH_PREDIV(PREDIV)	((PREDIV)<=0x7FU)
#define IS_RTC_SYNCH_PREDIV(PREDIV)		((PREDIV)<=0x7FFFU)
#define IS_RTC_MINUTES(MINUTES)			((MINUTES)<=59U)
#define IS_RTC_SECONDS(SECONDS)		    ((SECONDS)<=59U)

三、周期唤醒和闹钟

1、周期唤醒相关HAL函数

        周期唤醒就是RTC的一种定时功能,一般为周期唤醒定时器设置1Hz时钟源,每秒或每隔几秒中断一次。使用RTC的周期唤醒功能,可以很方便地设置1s定时中断,与系统时钟频率无关,比用定时器设置1s中断要简单得多。

        RTC周期唤醒中断的相关函数在文件stm32f4xx_hal_rtc_ex.h中定义,常用的函数如下表所示。

函数名

功能描述

__HAL_RTC_WAKEUPTIMER_ENABLE()

开启RTC的周期唤醒单元

__HAL_RTC_WAKEUPTIMER_DISABLE()

停止RTC的周期唤醒单元

__HAL_RTC_WAKEUPTIMER_ENABLE_IT()

允许RTC周期唤醒事件产生硬件中断

__HAL_RTC_WAKEUPTIMER_DISABLE_IT()

禁止RTC周期唤醒事件产生硬件中断

HAL_RTCEx_GetWakeUpTimer()

获取周期唤醒计数器的当前计数值,返回值类型uint32_t

HAL_RTCEx_SetWakeUpTimer()

设置周期唤醒单元的计数周期和时钟信号源,不开启
中断

HAL_RTCEx_SetWakeUpTimer_IT()

设置周期唤醒单元的计数周期和时钟信号源,开启中断

HAL_RTCEx_DeactivateWakeUpTimer()

停止RTC周期唤醒单元及其中断,停止后可用两个宏函数重新启动RTC周期唤醒单元及其中断

HAL_RTCEx_WakeUpTimerIRQHandler()

RTC周期唤醒中断的ISR里调用的通用处理函数

HAL_RTCEx_WakeUpTimerEventCallback()

RTC周期唤醒事件的回调函数

        这些函数都要用到RTC外设对象指针。RTC初始化程序文件rtc.c定义了表示RTC的外设对象变量hrtc。

RTC_HandleTypeDef hrtc;	//RTC外设对象变量

(1)宏函数

        周期唤醒中断事件类型的定义是宏定义RTC_IT_WUT,定义如下:

#define RTC_IT_WUT	0x00004000U	//周期唤醒中断事件类型

        在允许或禁止RTC周期唤醒事件产生硬件中断的宏函数里,会用到这个宏定义,示例如下:

__HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hrtc,RTC_IT_WUT);	//允许RTC周期唤醒事件产生中断
__HAL_RTC_WAKEUPTIMER_DISABLE_IT(&hrtc,RTC_IT_WUT);	//禁止RTC周期唤醒事件产生中断

(2)周期唤醒定时器

        函数HAL_RTCEx_SetWakeUpTimer()设置周期唤醒定时器的定时周期数和时钟信号源,不开启周期唤醒中断,其原型定义如下:

HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef *hrtc,uint32_t WakeUpCounter,uint32_t WakeUpClock)

        其中,参数WakeUpCounter是计数周期值,参数WakeUpClock是时钟信号源,可以使用一组宏定义表示的时钟信号源。

        函数HAL_RTCEx_SetWakeUpTimer_IT()设置周期唤醒定时器的定时周期数和时钟信号源,并开启周期唤醒中断,函数参数形式与HAL_RTCEx_SetWakeUpTimer()的一样。这两个函数在CubeMX生成的RTC初始化函数代码里会被调用。

        函数HAL_RTCEx_DeactivateWakeUpTimer()用于停止RTC周期唤醒单元及其中断,内部调用__HAL_RTC_WAKEUPTIMER_DISABLE()和__HAL_RTC_WAKEUPTIMER_DISABLE_IT()。

(3)周期唤醒中断回调函数

        RTC的周期唤醒中断有独立的中断号,ISR是RTC_WKUP_IRQHandler()。在CubeMX中开启RTC的周期唤醒中断后,在文件stm32f4xx_t.c中自动生成周期唤醒中断的ISR,代码如下:

void RTC_WKUP_IRQHandler(void)
{HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);
}

        其中,函数HAL_RTCEx_WakeUpTimerIRQHandler()是周期唤醒中断的通用处理函数,它内部会调用周期唤醒事件的回调函数HAL_RTCEx_WakeUpTimerEventCallback()。所以,用户要对周期唤醒中断进行处理,只需重新实现这个回调函数即可。

2、闹钟相关HAL函数

        RTC有两个闹钟(某些型号MCU上只有一个),闹钟相关的函数和定义在文件stm32f4xx_rtc.h和stm32f4xx_hal_rtc_ex.h中定义。有些函数需要用一个变量区分是哪个闹钟,文件32f4xx_hal_rtc.h中有如下的宏定义区分闹钟A和闹钟B:

#define RTC_ALARM_ARTC_CR_ALRAE	//表示闹钟A
#define RTC_ALARM_BRTC_CR_ALRBE	//表示闹钟B

        同样,假设在RTC初始化程序文件rtc.c中定义了表示RTC的外设对象变量hrtc。闹钟的相关常用函数如下表所示。

函数名

功能

__HAL_RTC_ALARM_DISABLE_IT()

禁止闹钟A或闹钟B产生硬件中断,例如
__HAL_RTC_ALARM_DISABLE_IT(&hrtc,RTC_ALARM_A)

__HAL_RTC_ALARM_ENABLE_IT()

允许闹钟A或闹钟B产生硬件中断,例如
__HAL_RTC_ALARM_ENABLE_IT(&hrtc,RTC_ALARM_B)

__HAL_RTC_ALARMA_DISABLE()

关闭闹钟A模块,例如__HAL_RTC_ALARMA_DISABLE(&hrtc)

__HAL_RTC_ALARMA_ENABLE()

开启闹钟A模块,例如__HAL_RTC_ALARMA_ENABLE(&hrtc)

__HAL_RTC_ALARMB_DISABLE()

关闭闹钟B模块,例如__HAL_RTC_ALARMB_DISABLE(&hrtc)

__HAL_RTC_ALARMB_ENABLE()

开启闹钟B模块,例如__HAL_RTC_ALARMB_ENABLE(&hrtc)

HAL_RTC_SetAlarm()

设置闹钟A或闹钟B的闹钟参数,不开启闹钟中断

HAL_RTC_SetAlarm_IT()

设置闹钟A或闹钟B的闹钟参数,开启闹钟中断

HAL_RTC_DeactivateAlarm()

停止闹钟A或闹钟B例如
HAL_RTC_DeactivateAlarm(&hrtc,RTC_ALARM_B)

HAL_RTC_GetAlarm()

获取闹钟A或闹钟B的设定时间和掩码

HAL_RTC_AlarmIRQHandler()

闹钟硬件中断ISR里调用的通用处理函数

HAL_RTC_AlarmAEventCallback()

闹钟A中断事件的回调函数

HAL_RTCEx_AlarmBEventCallback()

闹钟B中断事件的回调函数

        函数HAL_RTC_SetAlarm()用于设置闹钟时间和掩码,函数HAL_RTC_GetAlarm()用于获取设置的闹钟时间和掩码,其参数类型与HAL_RTC_SetAlarm()的相同。

        闹钟有一个中断号,ISR是RTC_Alarm_IRQHandler()。函数HAL_RTC_AlarmIRQHandler()是闹钟中断ISR里调用的通用处理函数,文件stm32f4xx_it.c中闹钟中断的ISR代码如下:

void RTC_Alarm_IRQHandler(void)
{HAL_RTC_AlarmIRQHandler(&hrtc);
}

        函数HAL_RTC_AlarmIRQHandler()会根据闹钟事件来源,分别调用闹钟A的中断事件回调函数HAL_RTC_AlarmAEventCallback()或闹钟B的中断事件回调函数HAL_RTCEx_AlarmBEventCallback()。

四、案例:闹钟及周期唤醒功能的用法

1、工程简介

        本实例使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0,使用闹钟A、闹钟B和周期唤醒功能,具有如下功能。

  • 使用32.768kHz的LSE时钟作为RTC的时钟源。
  • 系统复位时初始化RTC日期为2022-2-12,时间为10:10:10。
  • 每秒唤醒一次,在周期唤醒中断里读取当前日期和时间,并在串口助手上显示。
  • 将周期唤醒中断信号WUTF输出到复用引脚RTC_AF1(PC13),用杜邦线连接PC13和LED1的引脚PA6(在CubeMX中不要配置PA6引脚),使其为初姓复位状态,这样,LED1的亮灭由PC13的输出状态控制。
  • 闹钟A设置为在时间xx:16:05触发,其中xx表示任意数字,即在每个小时的16分5秒时刻触发闹钟A。对闹钟A中断次数计数,并在串口助手上显示。
  • 闹钟B设置为在时间xx:x:30触发,即在每分钟的30秒时刻触发闹钟B。对闹钟B中断次数计数,并在串口助手上显示。

2、项目配置

(1)时钟、DEBUG、CodeGenerator

        HSE,外部晶振,HCLK=168MHz;

        LSE,外部晶振,32.768kHz,LSE to RTC;

        DEBUG,serial wire;

        选中,CodeGenerator;

(2) RTC

1)RTC模式设置

        启用时钟源和日历,Alarm A和Alarm B是闹钟A和闹钟B,它们旁边的下拉列表框里都有3个选项。

  • Disable,禁用闹钟。
  • Internal Alarm,内部闹钟功能。
  • Routed to AF1,闹钟事件信号输出到复用引脚RTC_AF1,也就是引脚PC13。

        WakeUp是周期唤醒功能,它旁边的下拉列表框里有3个选项。

  • Disable,禁用周期唤醒功能。
  • Internal WakeUp,内部周期唤醒。
  • Routed to AF1,周期唤醒事件信号输出到复用引脚RTC_AF1。

        本例,将闹钟A和闹钟B都设置为Internal Alarm,将周期唤醒WakeUp设置为Routed to AF1,也就是将周期唤醒事件信号输出到复用引脚RTC_AF1。

        闹钟A、闹钟B和周期唤醒都可产生中断,且中断事件信号都可以输出到复用引脚RTC_AF1,但是只能选择其中一个信号输出到RTC_AF1。有一个信号占用RTC_AF1引脚后,其他使用RTC_AF1引脚的功能就不能使用了。(Timestamp Routed to AF1(时间戳)、Tamper1 Routed to AF1(入侵检测)、Calibration(校准时钟)等功能都用紫色底色标识,并且不能配置了。)

        特别地,Reference clock detection是参考时钟检测功能,如果勾选此项,就会使引脚PB15作为RTC_REFIN引脚,这个引脚需要接一个50Hz或60Hz的精密时钟信号,用于对RTC日历的1Hz更新频率进行精确补偿。某些GPS模块可以配置输出025Hz至10MHz的时钟脉冲信号,在使用GPS模块的应用中,就可以配置GPS模块输出50Hz信号,作为RTC的参考时钟源。

2RTC基本参数设置

        在RTC的配置界面对RTC的参数进行设置。设置预分频器、初始日期和时间等基本参数。        

        General分组里有以下通用参数。

  • Hour Format,小时格式,可以选择12小时制或24小时制。
  • Asynchronous Predivider value,异步预分频器值。设置范围为0~127,对应分频系数是1~128。当RTCCLK为32.768kHz时,128分频后就是256Hz。
  • Synchronous Predivider value,同步预分频器值。设置范围为0~32767,对应分频系数是1~32768。256分频后就是1Hz。
  • Output Polarity,输出极性。闹钟A、闹钟B、周期唤醒中断事件信号有效时的输出极性,可设置为高电平或低电平。这里设置为低电平,因为配置周期唤醒模块的事件信号WUTF输出到复用引脚RTC_AF1,而RTC_AF1连接LED1的引脚PA6,当RTC_AF1输出为低电平时LED1点亮。
  • Output Type,输出类型。复用引脚RTC_AF1的输出类型,可选开漏(Opendrain)输出或推挽(Pushpull)输出,这里设置为开漏输出。因为RTC_AF1和PA6都连接到LED1的同一个引脚上,设置为开漏输出更安全。

        Calendar Time分组里有用于设置日历的时间参数和初始化数据的如下参数。

  • Data Format,数据格式,可选择二进制格式或BCD格式,这里选择Binary data format。
  • 初始化时间数据,包括时、分、秒的数据,这里设置为7时15分10秒
  • Day Light Saving:value of hour adjustment,夏令时设置,这里设置为DaylightsavingNone,即不使用夏令时。
  • Store Operation,存储操作,表示是否已经对夏令时设置做修改。设置为StoreoperatioReset表示未修改夏令时,设置为Storeoperation Set表示已修改。用户可以在Calendar Date分组里设置日历初始化日期数据,包括年、月、日、星期几,其中,年的设置范围是0~99,表示2000~2099年。这里设置初始化日期为2025年2月12日,星期三

3闹钟定时设置

        在RTC的模式设置里启用闹钟A和闹钟B后,就会在参数配置部分看到闹钟的设置。闹钟A和闹钟B的设置方法是完全一样的,闹钟的触发时间可以设置为日期(天或星期几)、时、分、秒、亚秒的任意组合,只需设置相应的日期时间和屏蔽即可。本例中,设置RTC的初始时间为715分10秒,闹钟A设置为在时间xx:16:05触发,即每个小时的16分5秒时刻触发。闹钟A的设置主要是闹钟日期时间设置和屏蔽设置,对应的闹钟参数的意义和设置如下表所示。

参数

意义

取值示例

数据范围

Hours

8

0~23

Minutes

16

0~59

Seconds

5

0~59

Sub Seconds

亚秒

0

0~59

Alarm Mask Date Week day

屏蔽日期

Enable

设置为Enable表示屏蔽,即闹钟与日期数据无关,设置为Disable表示日期数据参与比对

Alarm Mask Hours

屏蔽小时

Enable

设置为Enable表示屏蔽,即闹钟与小时数据无关,设置为Disable表示小时数据参与比对

Alarm Mask Minutes

屏蔽分钟

Disable

设置为Enable表示屏蔽,即闹钟与分钟数据无关,设置为Disable表示分钟数据参与比对

Alarm Mask Seconds

屏蔽秒

Disable

设置为Enable表示屏蔽,即闹钟与秒数据无关,设置为Disable表示秒数据参与比对

Alarm Sub Second Mask

屏蔽亚秒

All Alarm SS fields are masked

设置为All Alarm SS fields are masked表示屏蔽,闹钟与亚秒数据无关,设置为其他选项时,用于亚秒数据比对

Alarm Date Week Day Sel

日期形式

Date

有Date和Weekday两种选项。
选项Date表示用1~31日表示日期选择Weekday表示用Monday到Sunday表示星期几

Alarm Date

日 期

3

1~31或Monday到Sunday

        对于闹钟A,只有Alarm Mask Minutes和Alarm Mask Seconds设置为Disable,所以闹钟A的定时是xx:16:05,与小时、日期数据无关。

        同样,对于闹钟B,只有Alarm Mask Seconds设置为Disable,所以闹钟B的定时是xx:xx:30,即每分钟的第30秒触发闹钟B。

4)周期唤醒设置

        周期唤醒的参数设置如图11-7所示,只有两个参数需要设置。

        Wake Up Clock,周期唤醒的时钟源。周期唤醒的时钟源可以来自同步预分频器的1Hz信号,也可以来自RTCCLK经过2、4、8、16分频的信号。若RTCCLK是32.768kHz,则这个参数各选项的意义如下。

  • RTCCLK/16,16分频信号,即2.048kHz。
  • RTCCLK/8,8分频信号,即4.096kHz。
  • RTCCLK/4,4分频信号,即8.192kHz。
  • RTCCLK/2,2分频信号,即16.384kHz。
  • 1 Hz,来自ck_spre的1Hz信号。
  • 1Hz with 1 bit added to Wake Up Counter,来自ck_spre的1Hz信号,将Wake Up Counter(唤醒计数器)的值加2¹⁶。

        Wake Up Counter,唤醒计数器的重载值,设定值的范围是0~65535。表示周期唤醒计数器的计数值达到这个值时,就触发一次WakeUp中断。如果这个值设置为0,则每个时钟周期中断1次。例如,选择周期唤醒时钟源为1Hz信号时,若设置此值为0,则每1秒发生一次唤醒中断;若设置为1,则每2秒发生一次唤醒中断。

        本例选择周期唤醒单元的时钟源为1Hz信号,唤醒计数器的重载值为0,所以每1秒会发生一次唤醒中断。在此中断处理程序里,读取RTC当前时间并在串口助手上显示,就可以看到时间是每秒刷新一次。

(3)USART6

        使用管脚PG9、PG14,所有参数默认;

(4) NVIC

        在NVIC组件的配置界面里设置RTC的中断。

3、软件设计

(1)main.c

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
// 菜单设计
/* USER CODE BEGIN 2 */printf("Demo11_1_RTC_Alarm:RTC and Alarm.\r\n");printf("Alarm A(xx:16:05) trigger: 0.\r\n");printf("Alarm B(xx:xx:30) trigger: 0.\r\n\r\n");
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
//串口打印
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

        main()函数在外设初始化部分调用了MX_RTC_Init(对RTC进行初始化,包括周期唤醒和钟的初始化,为RTC选择LSE作为时钟源是在函数SystemClock_Config()里实现的。RTC初始化完成后,就自动开启周期唤醒和闹钟功能。

        在串口助手上显示几条菜单信息后,程序就进入了while死循环,此后,程序的运行由中断驱动。

(2)rtc.c

/* USER CODE BEGIN 0 */
#include <stdio.h>uint16_t triggerCntA=0;	//闹钟A触发次数
uint16_t triggerCntB=0;	//闹钟B触发次数
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
/* 周期唤醒中断回调函数 */
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{RTC_TimeTypeDef sTime;RTC_DateTypeDef sDate;if (HAL_RTC_GetTime(hrtc,&sTime,RTC_FORMAT_BIN) == HAL_OK){HAL_RTC_GetDate(hrtc,&sDate,RTC_FORMAT_BIN);//调用HAL_RTC_GetTime()之后必须调用HAL_RTC_GetDate()以解锁数据,才能连续更新日期和时间//调用HAL_RTC_GetTime()时会将日历影子寄存器的当前值锁定,直到日期数据被读出//所以,即使不使用日期数据,也需要调用HAL_RTC_GetDate()读取//* @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values//* in the higher-order calendar shadow registers to ensure consistency between the time and date values.//* Reading RTC current time locks the values in calendar shadow registers until current date is read.//显示日期(年月日)char str[40];sprintf(str,"RTC Date= %4d-%2d-%2d",2000+sDate.Year,sDate.Month,sDate.Date);printf(" %s.\r\n",str);//显示时间hh:mm:sssprintf(str,"RTC Time = %2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);printf(" %s.\r\n",str);}
}/* 闹钟A中断的回调函数 */
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{triggerCntA++;	//闹钟A触发计数printf("Alarm A(xx:16:05) trigger: %d\r\n",triggerCntA);
}/* 闹钟B中断的回调函数 */
void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{triggerCntB++;	//闹钟B触发计数printf("Alarm B(xx:xx:30) trigger: %d\r\n",triggerCntB);
}
/* USER CODE END 1 */

        闹钟A和闹钟B共用EXTI线17中断,周期唤醒使用EXTI线22中断,在中断响应程序文件stm32f4xx_it.c自动生成了相应的ISR代码。要实现闹钟A、闹钟B、周期唤醒中断的处理,只需重新实现3个回调函数即可。

        文件rtc.c里包含重新实现了这3个回调函数,重新实现的回调函数无须在头文件里声明函数原型。

        在文件rtc.c中定义了两个uint16_t类型的全局变量,即triggerCntA和triggerCntB,用于记录闹钟A和闹钟B发生中断的次数。

        周期唤醒中断的回调函数是HAL_RTCEx_WakeUpTimerEventCallback(),唤醒中断每秒触发一次。中断回调函数里用HAL_RTC_GetTime()读取RTC的当前时间,再使用HAL_RTC_GetDate()读取当前日期,然后在串口助手上显示。

        调用HAL_RTC_GetTime()之后必须调用HAL_RTC_GetDate()以解锁数据,才能连续更新日期和时间。因为调用HAL_RTC_GetTime()时会锁定日历影子寄存器的当前值,直到日期数据被读出,所以即使不使用日期数据,也需要调用HAL_RTC_GetDate()读取日期数据。另外,因为还设置了将周期唤醒中断信号输出到复用引脚RTC_AF1(引脚PC13),并且用杜邦线连接了PC13与LED1的引脚PA6,所以程序运行时,可以看到LED1每秒会闪亮一下,这是因为RTC_AF1输出了一个低电平信号,只是这个信号持续时间比较短,LED1只是一闪即灭。

        闹钟A的中断回调函数是HAL_RTC_AlarmAEventCallback()。闹钟A在xx:16:05时刻触发,中断回调函数在串口助手上显示信息,并且显示中断发生的次数。因RTC的初始时间设为7:15:10,因此很快就会到7:16:05,就会触发一次闹钟A中断,在串口助手上就会看到显示的闹钟A的中断信息。闹钟A实际上每隔一小时触发一次。

        闹钟B的中断回调函数是HAL_RTCEx_AlarmBEventCallback()。闹钟B在xx:xx:30时刻触发,中断回调函数在串口助手上显示信息并且显示中断发生的次数。闹钟B触发周期是1分钟,可以在串口助手上看到闹钟B的中断次数每分钟增加一次。

4、运行与调试

 

 

相关文章:

细说STM32F407单片机RTC的基本原理及闹钟和周期唤醒功能的使用方法

目录 一、RTC基础知识 1、 RTC的功能 2、RTC工作原理 &#xff08;1&#xff09;RTC的时钟信号源 &#xff08;2&#xff09;预分频器 &#xff08;3&#xff09;实时时钟和日历数据 &#xff08;4&#xff09;周期性自动唤醒 &#xff08;5&#xff09;可编程闹钟 &a…...

ES用脚本更新异常

因为需要向原有的es结构中增加一个检索字段&#xff0c;但因为历史es数据都没有该字段&#xff0c;需要批量刷新es的该字段&#xff0c;本地使用了脚本的方式进行刷新&#xff0c;在测试环境测试&#xff0c;出现了以下错误&#xff1a; 500 Internal Server Error: [{"e…...

Navicat导入海量Excel数据到数据库(简易介绍)

目录 前言正文 前言 此处主要作为科普帖进行记录 原先Java处理海量数据的导入时&#xff0c;由于接口超时&#xff0c;数据处理不过来&#xff0c;后续转为Navicat Navicat 是一款功能强大的数据库管理工具&#xff0c;支持多种数据库系统&#xff08;如 MySQL、PostgreSQL、…...

C++学习

C对C语言的加强 1.命名空间&#xff08;namespace&#xff09; 为了避免&#xff0c;在大规模程序的设计中&#xff0c;以及在程序员使用各种各样的C库时&#xff0c;这些标识符的命名发送冲突。 标准C引入了关键字namespace&#xff0c;可以更好地控制标识符的作用域。 st…...

Linux Mem -- Where the mte store and check in the real hardware platform

目录 1 前言 2 MTE tag分类 3 Address tag 4 Memory tag 5 Tag Check 6 Cortex-A710 和 CI-700 系统示例&#xff1a; 1 前言 ARM的MTE允许分配、设置、比较一个 4bit的allocation tag 为16字节粒度的物理地址。当对MTE有一定了解后&#xff0c;应该会产生如下疑问&#…...

老牌软件,如今依旧坚挺

今天给大家介绍一个非常好用的老牌电脑清理软件&#xff0c;这个软件好多年之前就有人使用了。 今天找出来之后&#xff0c;发现还是那么的好用&#xff0c;功能非常强大。 Red Button 电脑清理软件 软件是绿色版&#xff0c;无需安装&#xff0c;打开这个图标就能直接使用了…...

springboot整合modbus实现通讯

springboot整合modbus4j实现tcp通讯 前言 本文基于springboot和modbus4j进行简单封装&#xff0c;达到开箱即用的目的&#xff0c;目前本方案仅实现了tcp通讯。代码会放在最后&#xff0c;按照使用方法操作后就可以直接使用 介绍 在使用本方案之前&#xff0c;有必要对modb…...

【java面试】线程篇

1.什么是线程&#xff1f; 线程是操作系统能够进行运算调度的最小单位&#xff0c;它被包含在进程之中&#xff0c;是进程中的实际运作单位。 2.线程和进程有什么区别&#xff1f; 线程是进程的子集&#xff0c;一个进程可以有很多线程&#xff0c;每条线程并行执行不同的任…...

DeepSeek官方发布R1模型推荐设置

今年以来&#xff0c;DeepSeek便在AI领域独占鳌头&#xff0c;热度一骑绝尘。其官方App更是创造了惊人纪录&#xff0c;成为史上最快突破3000万日活的应用&#xff0c;这一成绩无疑彰显了它在大众中的超高人气与强大吸引力。一时间&#xff0c;各大AI及云服务厂商纷纷投身其中&…...

Vue CLI 配置与插件

Vue CLI 配置与插件 今天我们来聊聊 Vue CLI 的配置与插件。随着项目复杂度的增加&#xff0c;合理配置 Vue CLI 可以帮助我们更高效地管理项目&#xff0c;同时利用插件机制快速集成各种功能。下面我就和大家详细介绍如何配置 Vue CLI&#xff0c;以及如何使用和开发插件&…...

Spring Boot (maven)分页3.0版本 通用版

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…...

pip 与 conda 的故事

pip 换源 pip 官方源 -i https://pypi.python.org/simple pip 清华源 -i https://pypi.tuna.tsinghua.edu.cn/simple pip 阿里源 -i https://mirrors.aliyun.com/pypi/simple PyTorch 安装 pip3 install torch torchvision torchaudio pip3 install torch torchvision torchaud…...

清华大学KVCache.AI团队联合趋境科技联合的KTransformers开源项目为什么那么厉害

KTransformers是一个由清华大学KVAV.AI团队开发的开源项目&#xff0c;旨在优化大语言模型&#xff08;LLM&#xff09;的推理性能&#xff0c;特别是在有限显存资源下运行大型模型。以下是KTransformers的详细介绍&#xff1a; 1. 核心特点 高性能优化&#xff1a;KTransfor…...

DeepSeek 遭 DDoS 攻击背后:DDoS 攻击的 “千层套路” 与安全防御 “金钟罩”_deepseek ddos

当算力博弈升级为网络战争&#xff1a;拆解DDoS攻击背后的技术攻防战——从DeepSeek遇袭看全球网络安全新趋势 在数字化浪潮席卷全球的当下&#xff0c;网络已然成为人类社会运转的关键基础设施&#xff0c;深刻融入经济、生活、政务等各个领域。从金融交易的实时清算&#xf…...

4090单卡挑战DeepSeek r1 671b:尝试量化后的心得的分享

引言&#xff1a; 最近&#xff0c;DeepSeek-R1在完全开源的背景下&#xff0c;与OpenAI的O1推理模型展开了激烈竞争&#xff0c;引发了广泛关注。为了让更多本地用户能够运行DeepSeek&#xff0c;我们成功将R1 671B参数模型从720GB压缩至131GB&#xff0c;减少了80%&#xff…...

【动态路由】系统Web URL资源整合系列(后端技术实现)【apisix实现】

需求说明 软件功能需求&#xff1a;反向代理功能&#xff08;描述&#xff1a;apollo、eureka控、apisix、sentinel、普米、kibana、timetask、grafana、hbase、skywalking-ui、pinpoint、cmak界面、kafka-map、nacos、gateway、elasticsearch、 oa-portal 业务应用等多个web资…...

【Elasticsearch】通过运行时字段在查询阶段动态覆盖索引字段

在 Elasticsearch 中&#xff0c;Override field values at query time是指通过运行时字段&#xff08;runtime fields&#xff09;在查询阶段动态覆盖索引字段的值&#xff0c;而无需修改原始索引数据。这种功能特别适用于以下场景&#xff1a; 1. 动态修改字段值&#xff1a…...

【stm32】定时器

stm32f4xx&#xff1a; APB2 ----> TIM1,TIM8,TIM9,TIM10,TIM11 APB1 ----> TIM2,TIM3,TIM4,TIM5,TIM6,TIM7,TIM12,TIM13,TIM14 一、定时器介绍 1、基本定时器 1.1、TIM6 和 TIM7 的主要特性 ● 16 位自动重载递增计数器 ● 16 位可编程…...

滑动窗口算法篇:连续子区间与子串问题

1.滑动窗口原理 那么一谈到子区间的问题&#xff0c;我们可能会想到我们可以用我们的前缀和来应用子区间问题&#xff0c;但是这里对于子区间乃至子串问题&#xff0c;我们也可以尝试往滑动窗口的思路方向去进行一个尝试&#xff0c;那么说那么半天&#xff0c;滑动窗口是什么…...

华三交换机-链路聚合配置案例

目录 1.链路聚合简述:2.链路聚合的作用:3.链路聚合的模式:4.网络拓扑:5.实验需求:6.网络配置&#xff1a;6.1 链路聚合配置(静态聚合)6.1.1 链路聚合配置:6.1.2 查看链路聚合状态: 6.2 链路聚合配置(动态聚合)6.2.1 链路聚合配置:6.2.2 查看链路聚合状态: 7.网络连通性测试:(接…...

Qwen2-VL 的重大省级,Qwen 发布新旗舰视觉语言模型 Qwen2.5-VL

Qwen2.5-VL 是 Qwen 的新旗舰视觉语言模型&#xff0c;也是上一代 Qwen2-VL 的重大飞跃。 Qwen2.5-VL主要特点 视觉理解事物&#xff1a;Qwen2.5-VL不仅能够熟练识别花、鸟、鱼、昆虫等常见物体&#xff0c;而且还能够分析图像中的文本、图表、图标、图形和布局。 代理性&…...

关系数据库标准语言SQL

1.SOL称为结构化查询语言&#xff0c;它是由1974年由Boyce和Chamberlin提出的&#xff0c;1975年至1979年IBM公司的San Jose Research Laboratory研制了关系数据库管理系统的原型系统SystemR,并实现了这种语言。 2.SQL(Structured Ouery Language)称为结构化查询语言 3.SQL数…...

mysql8.0使用MGR实现高可用与利用MySQL Router构建读写分离MGR集群

MGR是MySQL Group Replication的缩写&#xff0c;即MySQL组复制。 在以往&#xff0c;我们一般是利用MySQL的主从复制或半同步复制来提供高可用解决方案&#xff0c;但这存在以下几个比较严重的问题&#xff1a; 主从复制间容易发生复制延迟&#xff0c;尤其是在5.6以前的版本…...

《AI大模型开发笔记》MoE模型技术对比(Mixtral,Qwen2-MoE,DeepSeek-v3)

MoE模型技术对比(Mixtral,Qwen2-MoE,DeepSeek-v3) MoE(混合专家)大模型进入爆发期!本期我们对比三大开源MoE LLM:Mixtral、Qwen2-MoE 和最新爆火的 DeepSeek-V3。从 2023 年 Mixtral 开启风潮,到 2024 年 DeepSeek-V3 让全球瞩目,MoE 模型到底经历了怎样的进化? De…...

Vue.js 组件开发深入解析:Vue 2 vs Vue 3

Vue.js 是一个渐进式框架&#xff0c;旨在通过声明式渲染和组件化开发来提高开发效率和可维护性。组件是 Vue 应用的基本组成部分&#xff0c;几乎所有的功能都可以通过组件来实现。随着 Vue 3 的发布&#xff0c;Vue.js 引入了许多新的特性&#xff0c;使得组件的开发变得更加…...

DeepSeek大模型一键部署解决方案:全平台多机分布式推理与国产硬件优化异构计算私有部署

DeepSeek R1 走红后&#xff0c;私有部署需求也随之增长&#xff0c;各种私有部署教程层出不穷。大部分教程只是简单地使用 Ollama、LM Studio 单机运行量化蒸馏模型&#xff0c;无法满足复杂场景需求。一些操作配置也过于繁琐&#xff0c;有的需要手动下载并合并分片模型文件&…...

多个用户如何共用一根网线传输数据

前置知识 一、电信号 网线&#xff08;如以太网线&#xff09;中传输的信号主要是 电信号&#xff0c;它携带着数字信息。这些信号用于在计算机和其他网络设备之间传输数据。下面是一些关于网线传输信号的详细信息&#xff1a; 1. 电信号传输 在以太网中&#xff0c;数据是…...

DeepSeek官方推荐的AI集成系统

DeepSeek模型虽然强大先进&#xff0c;但是模型相当于大脑&#xff0c;再聪明的大脑如果没有输入输出以及执行工具也白搭&#xff0c;所以需要有配套工具才能让模型发挥最大的作用。下面是一个典型AI Agent架构图&#xff0c;包含核心组件与数据流转关系&#xff1a; #mermaid-…...

el-select 添加icon

Element-ui-plus 新版本&#xff1a;Select 选择器 | Element Plus 要实现如上的效果 &#xff0c;要用到具名插槽 prefix&#xff0c;看代码&#xff1a; <template><el-dialog ref"dialogRef" v-model"dialogVisible" :title"title"…...

Qt的QPushButton样式设置

在Qt中&#xff0c;可以通过样式表&#xff08;QSS&#xff09;为QPushButton设置丰富的样式。以下是常见样式设置方法的详细说明&#xff1a; 1. 基础样式 // 设置背景色、文字颜色、圆角边框 button->setStyleSheet("QPushButton {"" background-color…...

Java函数计算冷启动从8s到800ms的优化实录

在函数计算场景中,冷启动性能对用户体验至关重要。本文将分享如何将 Java 函数计算的冷启动时间从 8 秒优化到 800 毫秒,包括具体的技术手段和代码示例。 一、背景介绍 函数计算是一种事件驱动的计算服务,用户只需上传代码,无需管理服务器。但在实际使用中,函数计算的冷…...

通过例子学 rust 个人精简版 1-1

1-1 Hello World fn main() {println!("Hello World!");// 动手试一试println!("Im a Rustacean!"); }Hello World! Im a Rustacean!要点1 &#xff1a;println 自带换行符 注释 fn main() {let x 5 /* 90 */ 5;println!("Is x 10 or 100? x …...

STM32、GD32驱动TM1640原理图、源码分享

一、原理图分享 二、源码分享 /************************************************* * copyright: * author:Xupeng * date:2024-07-18 * description: **************************************************/ #include "smg.h"#define DBG_TAG "smg&…...

Centos安装php-8.0.24.tar

查看系统环境 cat /etc/redhat-release 预先安装必要的依赖 yum install -y \ wget \ gcc \ gcc-c \ autoconf \ automake \ libtool \ make \ libxml2 \ libxml2-devel \ openssl \ openssl-devel \ sqlite-devel yum update 1、下载解压 cd /data/ wget https:/…...

VNC远程控制Mac

前言 macOS系统自带有VNC远程桌面&#xff0c;我们可以在控制端上安装配置VNC客户端&#xff0c;以此来实现远程控制macOS。但通常需要在不同网络下进行远程控制&#xff0c;为此&#xff0c;我们可以在macOS被控端上使用cpolar做内网穿透&#xff0c;映射VNC默认端口5…...

基于大数据的北京市天气数据分析系统的设计与实现

【Flask】基于Flask的北京市天气数据分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python和Flask框架&#xff0c;结合Pandas、NumPy等数据处理库及Echarts进…...

20250214在ubuntu20.04下使用obs studio录制外挂的1080p的USB摄像头【下载安装】

20250214在ubuntu20.04下使用obs studio录制外挂的1080p的USB摄像头 2025/2/14 9:10 缘起&#xff1a;笔记本电脑在ubuntu20.04下使用Guvcview录制自带的摄像头&#xff0c;各种问题。 1、降帧率。WIN10/11自带的相机应用可以满速30fps&#xff0c;马上重启到ubuntu20.04&#…...

OpenEuler学习笔记(三十):在OpenEuler上搭建3D建模环境

在OpenEuler上搭建3D建模环境&#xff0c;通常可以选择一些常见的3D建模软件&#xff0c;如Blender、FreeCAD等。以下以搭建Blender和FreeCAD这两款软件的使用环境为例&#xff0c;为你详细介绍搭建步骤。 搭建Blender 3D建模环境 1. 更新系统软件包 首先&#xff0c;确保系…...

Deepseek R1模型本地化部署+API接口调用详细教程:释放AI生产力

文章目录 前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装ollama2部署DeepSeek R1模型删除已存在模型&#xff0c;以7b模型为例 三、DeepSeek API接口调用Cline配置 前言 随着最近人工智能 DeepSeek 的爆火&#xff0c;越来越多的技术大佬们开始关注如…...

Ubuntu添加桌面快捷方式

以idea为例 一. 背景 在ubuntu中&#xff0c;很多时候是自己解压的文件并没有桌面快捷方式&#xff0c;需要自己找到对应的目录的执行文件手动打开&#xff0c;很麻烦 而只需要在 /usr/share/applications 中创建自定义的desktop文件就能自动复制到桌面 二. 添加方法 创建desk…...

教程:使用 Vue 3 和 arco 实现表格合并

1. 功能概述 本教程将介绍如何使用 Vue 3 和 arco 组件库实现表格合并功能。具体来说&#xff0c;我们会根据表格数据中的某个字段&#xff08;如 type&#xff09;对表格的某一列&#xff08;如入库类型列&#xff09;进行合并&#xff0c;同时将质检说明列合并为一列。 2. …...

【MySQL数据库】Ubuntu下的mysql

目录 1&#xff0c;安装mysql数据库 2&#xff0c;mysql默认安装路径 3&#xff0c;my.cnf配置文件? 4&#xff0c;mysql运用的相关指令及说明 5&#xff0c;数据库、表的备份和恢复 mysql是一套给我们提供数据存取的&#xff0c;更加有利于管理数据的服务的网络程序。下…...

Java实现MinIO上传PDF文件并配置浏览器在线打开而非下载

在Minio中上传PDF文件后&#xff0c;通常文件的访问方式&#xff08;即URL&#xff09;是配置为允许下载文件的&#xff0c;因为大多数Web服务器和存储服务默认将PDF文件视为应下载的内容类型&#xff08;Content-Type: application/pdf&#xff09;。但是&#xff0c;如果你想…...

CSV格式和普通EXCEL格式文件的区别

CSV 文件&#xff08;.csv&#xff09; 普通的 Excel 文件&#xff08;.xlsx 或 .xls) 主要体现在 文件格式、数据存储、功能支持 等方面: 文件格式 比较项CSV 文件 (.csv)Excel 文件 (.xlsx/.xls)文件类型纯文本文件二进制或 XML 格式数据分隔逗号&#xff08;,&#xff09…...

安卓基础(持续更新的笔记)

为什么要这样&#xff1a; // 创建请求体RequestBody body RequestBody.create(MediaType.parse("application/json; charsetutf-8"),jsonObject.toString()); jsonObject 就包含了一个 JSON 数据&#xff0c;它其实就是&#xff1a; {"name": "张…...

大模型Deepseek的使用_基于阿里云百炼和Chatbox

目录 前言1. 云服务商2. ChatBox参考 前言 上篇博文中探索了&#xff08;本地&#xff09;部署大语言模型&#xff0c;适合微调、数据高隐私性等场景。随着Deepseek-R1的发布&#xff0c;大语言模型的可及性得到极大提升&#xff0c;应用场景不断增加&#xff0c;对高可用的方…...

数学建模基础训练-1:概念解析

文章目录 数学建模基础训练-1&#xff1a;概念解析问题一&#xff1a;如何找到“概念”&#xff1f;问题二&#xff1a;如何全面理解概念的基础含义&#xff1f;问题三&#xff1a;如何深刻理解概念并作出创新点发掘&#xff1f;实际举例问题一 :研究并给出寒假开学某大学返校交…...

【mybatis】基本操作:详解Spring通过注解和XML的方式来操作mybatis

mybatis 的常用配置 配置数据库连接 #驱动类名称 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver #数据库连接的url spring.datasource.urljdbc:mysql://127.0.0.1:3306/mybatis_test characterEncodingutf8&useSSLfalse #连接数据库的名 spring.datasourc…...

联邦学习中的“参数聚合“机制详解:医疗数据隐私保护的技术实现路径

一、技术原理&#xff1a;参数聚合的数学本质 1.1 核心数学公式 联邦平均算法&#xff08;FedAvg&#xff09;&#xff1a; \theta_{global}^{t1} \sum_{k1}^K \frac{n_k}{N} \theta_k^t其中&#xff1a; K K K&#xff1a;参与本轮训练的客户端数量 n k n_k nk​&#xff…...

LVS 负载均衡集群(NAT模式)

一、环境准备 四台主机&#xff08;一台 LVS、两台 RS、一台客户端&#xff09; 注意每个虚拟机都需要关闭防火墙和 selinux 1.1.LVS 主机 LVS 主机&#xff08;两块网卡&#xff09; 第一块&#xff1a;NAT模式&#xff08;内网&#xff09; 第二块&#xff1a;添加网卡&am…...