STM32快速复习(九)RTC时钟模块
文章目录
- 前言
- 一、RTC是什么?RTC的工作原理?
- 二、库函数以及示例
- 1.标准库函数
- 2.示例代码
- 总结
前言
STM32 的实时时钟(RTC)是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC 模块和时钟配置系统 (RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域 (BKP) 的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护。
unix时间戳: Unix 时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。
STM32相较于51的外接时钟寄存器DS1302,STM32内部计时是没有年月日,时分秒寄存器的。STM32是利用单独的秒寄存器,以1970年1月1日为0,进行每秒自增的定时器计数。
当前为1723138563秒,转换后再加上1970年就是当前时间
闰秒:由于地球自转的影响,每天有一定的计数误差,闰秒规定,当误差大于0.9秒。当前计数分钟会出现61秒,然后下一分钟再从0开始计数。
这样减少了硬件的负担,但是增加软件转换的麻烦。于是STM32定义了time.h 头文件。专门用于转换时间。
(BKP)备份寄存器是42个16位的寄存器(中容量,小容量为10个16位的寄存器,20字节),可用来存储84个字节的用户应用程序数据。他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位。 此外,BKP控制寄存器用来管理侵入检测和RTC校准功能。 复位后,对备份寄存器和RTC的访问被禁止,并且备份域被保护以防止可能存在的意外的写操作。
一、RTC是什么?RTC的工作原理?
RTC(Real Time Clock):实时时钟,是指可以像时钟一様输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器(BKP)。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。 STM32 的实时时钟(RTC)是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
TIPS:RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护
下图中RTC数据有三条,RTC_Second(秒中断)、RTC_Overflow(溢出事件)和RTC_Alarm(闹钟中断),以及最下方的WKUP(唤醒,常用于PA0引脚),用来进行中断控制,增加了闹钟和休眠唤醒等功能。
RTC_PRL:计数目标(写入n,就是n+1分频);
RTC_DIV:自减计数器,每来一个输入时钟,DIV的值自减一次,减到0后再来一个时钟,从PRL获取到重装值继续自减;
RTC_CNT:Unix时间戳的秒计数器;
RTC_ALR:闹钟寄存器, 当CNT=ALR时会产生RTC_Alarm闹钟信号,就能进入右边的中断系统;同时也可以让STM32退出待机模式;
中断:RTC_Second,秒中断:开启后每秒进一次RTC中断;RTC_Overflow,溢出中断:CNT溢出;RTC_Alarm,闹钟中断:CNT=ALR时会触发中断,同时也可以让STM32退出待机模式;
图中浅灰色的部分都是属于备份域的,在VDD掉电时可在VBAT的驱动下继续运行.这部分仅包括RTC的分频器,计数器,和闹钟控制器.若VDD电源有效,RTC可以触发RTC_Second(秒中断)、RTC_Overflow(溢出事件)和RTC_Alarm(闹钟中断).从结构图可以看到到,其中的定时器溢出事件无法被配置为中断.如果STM32原本处于待机状态,可由闹钟事件或WKUP事件(外部唤醒事件,属于EXTI模块,不属于RTC)使它退出待机模式.闹钟事件是在计数器RTC_CNT的值等于闹钟寄存器RTC_ALR的值时触发的.
因为RTC的寄存器是属于备份域,所以它的所有寄存器都是16位的.它的计数RTC_CNT的32位由RTC_CNTL和RTC_CNTH两个寄存器组成,分别保存计数值的低16位和高16位.在配置RTC模块的时钟时,把输入的32768Hz的RTCCLK进行32768分频得到实际驱动计数器的时钟TR_CLK = RTCCLK/37768 = 1Hz,计时周期为1秒,计时器在TR_CLK的驱动下计数,即每秒计数器RTC_CNT的值加1(常用)
RTC只是一个时钟,但与RTC相连的有两个系统时钟,一个是APB1接口的PCLK1另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核,由一系列可编程计数器组成,这部分又再细分为两个组件:预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。
电路图简化:
流程(会按照流程写出代码即可):
1. 使能电源时钟和备份区域时钟
2. 取消备份区写保护
3. 复位备份区域,开启外部低速振荡器
4. 选择 RTC 时钟,并使能
5. 设置 RTC 的分频,以及配置 RTC 时钟
6. 更新配置,设置 RTC 中断分组
7. 编写中断服务函数
RTC 相关的库函数在文件 stm32f10x_rtc.c 和 stm32f10x_rtc.h 文件中, BKP 相关的库函数在
文件 stm32f10x_bkp.c 和文件 stm32f10x_bkp.h 文件中
二、库函数以及示例
1.标准库函数
1、RTC时钟源和时钟操作函数;
void RCC_RTCCLKConfig(uint32_t CLKSource);//时钟源选择;
void RCC_RTCCLKCmd(FunctionalState NewState);//时钟使能;
2、RTC初始化函数
ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct);
trypedef struct
{
uint32_t RTC_HourFormat;//小时格式:24/12
uint32_t RTC_AsynchPrediv;//异步分频系数
uint32_t RTC_SynchPrediv;//同步分频系数;
}RTC_InitTypeDef;
3、日历配置相关函数
ErrorStatus RTC_SetTime(uint32_t RTC_Format,RTC_TimeTypeDef* RTC_TimeStruct);数值当前时间
void RTC_GetTime(uint32_t RTC_Format,RTC_TimeTypeDef* RTC_TimeStruct);
ErrorStatus RTC_SetDate(uint32_t RTC_Format,RTC_Dae TypeDef* RTC_DataStruct);
void RTC_GetDate(uint32_t RTC_Format,RTC_Date TypeDef* RTC_DateStruct);
uint32_t RTC_GetSubSecond(void);
4、RTC闹钟相关函数
ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm,FunctionalState NewState);
void RTC_SetAlarm();
void RTC_GetAlarm();
void RTC_AlarmSubSecondConfig();
uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm);
5、RTC周期唤醒相关函数:
void RTC_WakeUpClockConfig();
void RTC_SetWakeUpCounter();
uint32_t RTC_GetWakeUpCounter(void);
RTC_WakeUpCmd(DISABLE);//关闭WAKEUP
6、RTC中断配置以及状态相关函数
void RTC_ITConfig();
FlagStatus RTC_GetFlgStatus(uint32_t RTC_FLAG);
void RTC_ClearFlag(uint32_t RTC_FLAG);
ITStatus RTC_GetITStatus(uint32_t RTC_IT);
void RTC_ClearITPendingBit();
7、RTC相关约束函数
void RTC_WriteProtectionCmd();//取消写保护
ErrorStatus RTC_EnterInitNode();//进入配hi模式,RTC_ISR_INITF位设置位1
void RTC_ExitInitMode(void);//退出初始化模式
8、其他函数
uint32_t RTC_ReadBackupRegister();
void RTC_WriteBackupRegister();
void RTC_ITConfig();
RTC_ITConfig 使能或者失能指定的 RTC 中断
RTC_EnterConfigMode 进入 RTC 配置模式
RTC_ExitConfigMode 退出 RTC 配置模式
RTC_GetCounter 获取 RTC 计数器的值
RTC_SetCounter 设置 RTC 计数器的值
RTC_SetPrescaler 设置 RTC 预分频的值
RTC_SetAlarm 设置 RTC 闹钟的值
RTC_GetDivider 获取 RTC 预分频分频因子的值
RTC_WaitForLastTask 等待最近一次对 RTC 寄存器的写操作完成
RTC_WaitForSynchro 等待 RTC 寄存器(RTC_CNT, RTC_ALR and RTC_PRL)与 RTC 的 APB 时钟同步
RTC_GetFlagStatus 检查指定的 RTC 标志位设置与否
RTC_ClearFlag 清除 RTC 的待处理标志位
RTC_GetITStatus 检查指定的 RTC 中断发生与否
RTC_ClearITPendingBit 清除 RTC 的中断待处理位
-
使能电源时钟和备份区域时钟
前面已经介绍了,我们要访问 RTC 和备份区域就必须先使能电源时钟和备份区域时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); -
取消备份区写保护
要向备份区域写入数据,就要先取消备份区域写保护(写保护在每次硬复位之后被使能),否则是无法向备份区域写入数据的。我们需要用到向备份区域写入一个字节,来标记时钟已经配置过了,这样避免每次复位之后重新配置时钟。 取消备份区域写保护的库函数实现方法是:
PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后备寄存器访问 -
复位备份区域,开启外部低速振荡器
在取消备份区域写保护之后,我们可以先对这个区域复位,以清除前面的设置,当然这个
操作不要每次都执行,因为备份区域的复位将导致之前存在的数据丢失,所以要不要复位,要看情况而定。然后我们使能外部低速振荡器,注意这里一般要先判断 RCC_BDCR 的 LSERDY位来确定低速振荡器已经就绪了才开始下面的操作。
BKP_DeInit();//复位备份区域
RCC_LSEConfig(RCC_LSE_ON);// 开启外部低速振荡器
4.选择 RTC 时钟,并使能。
这里我们将通过 RCC_BDCR 的 RTCSEL 来选择选择外部 LSI 作为 RTC 的时钟。然后通过RTCEN 位使能 RTC 时钟。
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //选择 LSE 作为 RTC 时钟
对于 RTC 时钟的选择,还有 RCC_RTCCLKSource_LSI 和 RCC_RTCCLKSource_HSE_Div128两个,顾名思义,前者为 LSI,后者为 HSE 的 128 分频,这在时钟系统章节有讲解过。使能 RTC 时钟的函数是:
RCC_RTCCLKCmd(ENABLE); //使能 RTC 时钟
5.设置 RTC 的分频,以及配置 RTC 时钟。
在开启了 RTC 时钟之后,我们要做的就是设置 RTC 时钟的分频数,通过 RTC_PRLH 和RTC_PRLL 来设置,然后等待 RTC 寄存器操作完成,并同步之后,设置秒钟中断。然后设置RTC 的允许配置位(RTC_CRH 的 CNF 位), 设置时间(其实就是设置 RTC_CNTH 和 RTC_CNTL两个寄存器)。 下面我们一一这些步骤用到的库函数:在进行 RTC 配置之前首先要打开允许配置位(CNF),库函数是:
RTC_EnterConfigMode();/// 允许配置
在配置完成之后,千万别忘记更新配置同时退出配置模式,函数是:
RTC_ExitConfigMode();//退出配置模式, 更新配置
设置 RTC 时钟分频数, 库函数是:
void RTC_SetPrescaler(uint32_t PrescalerValue);
这个函数只有一个入口参数,就是 RTC 时钟的分频数,很好理解。
然后是设置秒中断允许, RTC 使能中断的函数是:
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);
这个函数的第一个参数是设置秒中断类型,这些通过宏定义定义的。 对于使能秒中断方法是:
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能 RTC 秒中断
下一步便是设置时间了,设置时间实际上就是设置 RTC 的计数值,时间与计数值之间是需要换算的。库函数中设置 RTC 计数值的方法是:
void RTC_SetCounter(uint32_t CounterValue)//最后在配置完成之后
6.更新配置,设置 RTC 中断分组。
在设置完时钟之后,我们将配置更新同时退出配置模式,这里还是通过 RTC_CRH 的 CNF
来实现。
RTC_ExitConfigMode();//退出配置模式,更新配置
在退出配置模式更新配置之后我们在备份区域 BKP_DR1 中写入 0X5050 代表我们已经初始化过时钟了,下次开机(或复位)的时候,先读取 BKP_DR1 的值,然后判断是否是 0X5050 来决定是不是要配置。接着我们配置 RTC 的秒钟中断,并进行分组。
往备份区域写用户数据的函数是:
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);
这个函数的第一个参数就是寄存器的标号了,这个是通过宏定义定义的。 比如我们要往
BKP_DR1 写入 0x5050,方法是:
BKP_WriteBackupRegister(BKP_DR1, 0X5050);
同时,有写便有读,读取备份区域指定寄存器的用户数据的函数是
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);
- 编写中断服务函数
我们要编写中断服务函数,在秒钟中断产生的时候,读取当前的时间值,并显示到
oled 模块上。
2.示例代码
代码如下(示例):
//初始化配置
void MyRTC_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //开启PWR的时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE); //开启BKP的时钟/*备份寄存器访问使能*/PWR_BackupAccessCmd(ENABLE); //使用PWR开启对备份寄存器的访问//通过写入备份寄存器的标志位,判断RTC是否是第一次配置if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5){RCC_LSEConfig(RCC_LSE_ON); //开启LSE时钟while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET); //等待LSE准备就绪RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //选择RTCCLK来源为LSERCC_RTCCLKCmd(ENABLE); //RTCCLK使能RTC_WaitForSynchro(); //等待同步RTC_WaitForLastTask(); //等待上一次操作完成RTC_SetPrescaler(32768 - 1); //设置RTC预分频器,预分频后的计数频率为1HzRTC_WaitForLastTask(); //等待上一次操作完成MyRTC_SetTime(); //设置时间,调用此函数,全局数组里时间值刷新到RTC硬件电路//在备份寄存器写入自己规定的标志位,用于判断RTC是不是第一次执行配置BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else //RTC不是第一次配置{RTC_WaitForSynchro(); //等待同步RTC_WaitForLastTask(); //等待上一次操作完成}
}//设置时间
uint16_t MyRTC_Time[] = {2023, 1, 1, 23, 59, 55};
void MyRTC_SetTime(void)
{time_t time_cnt; //定义秒计数器数据类型struct tm time_date; //定义日期时间数据类型time_date.tm_year = MyRTC_Time[0] - 1900; //将数组的时间赋值给日期时间结构体time_date.tm_mon = MyRTC_Time[1] - 1;time_date.tm_mday = MyRTC_Time[2];time_date.tm_hour = MyRTC_Time[3];time_date.tm_min = MyRTC_Time[4];time_date.tm_sec = MyRTC_Time[5];time_cnt = mktime(&time_date) - 8 * 60 * 60; //调用mktime函数,将日期时间转换为秒计数器格式//- 8 * 60 * 60为东八区的时区调整RTC_SetCounter(time_cnt); //将秒计数器写入到RTC的CNT中RTC_WaitForLastTask(); //等待上一次操作完成
}
江科大STM32例程
#include "stm32f10x.h" // Device header
#include <time.h>uint16_t MyRTC_Time[] = {2023, 1, 1, 23, 59, 55};void MyRTC_SetTime(void);void MyRTC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);PWR_BackupAccessCmd(ENABLE);if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5){BKP_DeInit();RCC_LSEConfig(RCC_LSE_ON);while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);RCC_RTCCLKCmd(ENABLE);RTC_WaitForSynchro();RTC_WaitForLastTask();RTC_SetPrescaler(32767);RTC_WaitForLastTask();MyRTC_SetTime();BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{RTC_WaitForSynchro();RTC_WaitForLastTask();}
}/*
void MyRTC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);PWR_BackupAccessCmd(ENABLE);if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5){BKP_DeInit();RCC_LSICmd(ENABLE);while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);RCC_RTCCLKCmd(ENABLE);RTC_WaitForSynchro();RTC_WaitForLastTask();RTC_SetPrescaler(40000 - 1);RTC_WaitForLastTask();MyRTC_SetTime();BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{RCC_LSICmd(ENABLE);while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);RCC_RTCCLKCmd(ENABLE);RTC_WaitForSynchro();RTC_WaitForLastTask();}
}*/void MyRTC_SetTime(void)
{time_t time_cnt;struct tm time_date;time_date.tm_year = MyRTC_Time[0] - 1900;time_date.tm_mon = MyRTC_Time[1] - 1;time_date.tm_mday = MyRTC_Time[2];time_date.tm_hour = MyRTC_Time[3];time_date.tm_min = MyRTC_Time[4];time_date.tm_sec = MyRTC_Time[5];time_cnt = mktime(&time_date) - 8 * 60 * 60;RTC_SetCounter(time_cnt);RTC_WaitForLastTask();
}void MyRTC_ReadTime(void)
{time_t time_cnt;struct tm time_date;time_cnt = RTC_GetCounter() + 8 * 60 * 60;time_date = *localtime(&time_cnt);MyRTC_Time[0] = time_date.tm_year + 1900;MyRTC_Time[1] = time_date.tm_mon + 1;MyRTC_Time[2] = time_date.tm_mday;MyRTC_Time[3] = time_date.tm_hour;MyRTC_Time[4] = time_date.tm_min;MyRTC_Time[5] = time_date.tm_sec;
}
总结
RTC的工作流程通常分为初始化和运行两个阶段。在初始化阶段,我们需要配置RTC的时钟源、预分频器、日历寄存器等参数,并启用相应的中断或事件。在运行阶段,RTC会根据预设的时钟源和分频器递增计数器,同时更新日历信息,处理闹钟事件等。通过合理配置和管理,我们可以充分发挥RTC模块的功能和性能。
相关文章:

STM32快速复习(九)RTC时钟模块
文章目录 前言一、RTC是什么?RTC的工作原理?二、库函数以及示例1.标准库函数2.示例代码 总结 前言 STM32 的实时时钟(RTC)是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下…...

Nacos注册中心与OpenFeign远程调用
文章目录 一、注册中心原理二、Nacos注册中心三、服务注册四、服务发现五、OpenFeign 一、注册中心原理 在微服务当中必须有两个角色 服务提供者:提供接口供其它微服务访问 服务消费者:调用其它微服务提供的接口 在大型微服务项目中,服务提供…...

【基础算法总结】双指针
目录 一,双指针算法介绍二,算法原理和代码实现283.移动零1089.复写零202.快乐数11.盛最多水的容器611.有效三角形的个数LRC179.和为s的两个数15.三数之和18.四数之和 三,算法总结 一,双指针算法介绍 双指针算法是基础算法之一&am…...

教你制作一本一对一授权才能阅读的样本册
在这个信息时代,保护个人隐私变得越来越重要。一对一授权阅读机制,正是为了满足这一需求而诞生。今天,就让我来教你如何制作一本只有一对一授权才能阅读的样本册。这不仅适用于保护个人隐私,还能为企业、研究机构等提供安全、高效…...

【DEV工具-IDEA】idea的光标变成黑块了?
项目场景: 解决:windows:按一下insert键。...

没通过算法备案 或许是这几点你没做好
没通过算法备案 或许是这几点你没做好 当企业提交算法备案遭遇“不予通过”时,往往是因为一些看似微小却至关重要的细节未能达到标准。以下是一些常见的原因,希望能为准备备案的企业提供一些预警和指导: ICP备案缺失:互联网信息服…...
力扣172.阶乘后的0
class Solution {public int trailingZeroes(int n) {int ans 0;//本质:每5个数有一个5的倍数,每25个数有一个25的倍数……int num 5;while(n / num ! 0) {ans n/num;num * 5;}return ans;} }...

Oracle 19c数据库:Windows详细安装与配置指南
Oracle 19c的安装和配置是一个相对复杂但系统化的过程,本文演示如何在 Windows 系统下安装 Oracle数据库,安装足够的磁盘空间(一般需要5~6个G,所以选剩余空间大的盘)。以下是一个详细的步骤指南,包括准备工…...

解决职业摔跤手分类问题的算法与实现
解决职业摔跤手分类问题的算法与实现 引言问题定义算法设计二分图判定算法步骤伪代码C语言实现引言 在职业摔跤界,摔跤手通常被分为“娃娃脸”(“好人”)型和“高跟鞋”(“坏人”)型。在任意一对摔跤手之间,都有可能存在竞争关系。本文的目标是设计一个算法,用于判断是…...
微擎框架
微擎框架之——多级查询显示每项个数-Poison-CSDN博客微擎框架之——系统内置分页加载-CSDN博客 微擎-关于安装模块时出现:Could not resolve: www.52xbjs.com (Could not contact DNS servers)-Poison-CSDN博客...
容器化技术在非结构化数据中台的部署研究
随着大数据时代的到来,非结构化数据的处理与管理日益成为企业和组织关注的重点。为应对非结构化数据中台在数据存储、处理及安全性等方面面临的挑战,本研究深入探讨了容器化技术在该领域的部署与应用。研究首先概述了容器化技术的基本概念、特点及其在非…...
RK3399 android7.1 话柄电话功能
实现功能:挂柄接IO口+GND控制话机听筒与系统喇叭的切换(抬起手柄声音由喇叭切换到听筒,挂到磁吸底座喇叭出声) 应用场景: 电子电话班牌,电话机等 硬件接线方式: 电话手柄:听筒接耳机座子<HRP,GND>,麦克风接<MIC+,MIC-> 电话底座:磁吸座子接<IO2,GND&g…...
实习四十:部署project_exam_system项目——及容器的编排
(一)安装docker、编辑daemon.json文件、安装docker-compose编排容器、启动docker 1.环境准备 [rootdocker--1 ~]# rz -E rz waiting to receive. [rootdocker--1 ~]# ls anaconda-ks.cfg docker.sh [rootdocker--1 ~]# source docker.sh [r…...
栈,队列
栈(Stack)和队列(Queue)是两种常用的数据结构,它们在计算机科学中有着广泛的应用。它们的主要区别在于元素的添加和移除方式。 栈(Stack): 栈是一种后进先出(Last In F…...

新增一个数组传递给后端
实现的效果: 页面 <div style"margin-bottom: 10px" v-if"totalPrice"><p style"font-weight: bolder;margin-bottom: 10px">支付计划<el-button type"text" size"small" click"addPayInf…...

Flutter集成Firebase中的Realtime Analytics
实时分析(Realtime Analytics)的功能 实时数据更新:Firebase实时分析提供实时数据更新,让开发者可以实时了解应用程序的使用情况,包括活跃用户数量、事件触发次数等指标自定义事件跟踪:开发者可以通过自定…...

2024国赛数学建模A题B题C题D题E题思路资料模型
开始在本帖实时更新2024国赛数学建模赛题思路代码,文章末尾获取! 持续更新参考思路...

C语言字面量和常量
目录 引言 1. 字面量 1.1 字符字面量 1.2 整型字面量 1.3 浮点字面量 2. 常量 2.1 使用预处理器指令 #define 定义常量 2.1.1 语法格式 2.1.2 使用举例 2.2 使用 const 关键字定义常量 2.3 使用 #define 和 const 定义常量的区别 引言 看了一些博文,有的文…...

视频结构化从入门到精通——行为分析类应用
行为分析类应用 1. 认识行为分析 监控/判断视频画面中目标的运动过程、携带属性等。从数据中自动识别、跟踪和理解人类或物体行为。 1. 车的行为分析应用 车辆行为分析主要用于监控和管理车辆的动态行为,广泛应用于智能交通、城市管理和安全监控。关键应用包括&…...
Redis的KeyExpirationEventMessageListener键过期监听器
MessageListener通过监听key过期的Redis keyspace通知,然后通过ApplicationEventPublisher发布RedisKeyExpiredEvent事件的模式进行事件监听和广播。 redis.conf地址:https://github.com/redis/redis/blob/unstable/redis.conf Redis官方地址࿱…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...

[拓扑优化] 1.概述
常见的拓扑优化方法有:均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有:有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...