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

STM32中的RTC(实时时钟)详解

前言:为什么需要RTC?

在嵌入式系统中,时间记录是一项基础且关键的功能。想象一下:智能家居设备需要按时间触发开关灯,工业仪表需要记录传感器数据的采集时刻,物联网终端需要同步服务器时间戳……这些场景都离不开实时时钟(RTC)

STM32的RTC外设本质是一个独立运行的定时器,但与普通定时器相比,它有三个核心优势:

  • 独立供电:即使主电源掉电,也能通过备用电池维持运行,确保时间不丢失
  • 日历功能:直接支持年/月/日/时/分/秒记录,无需软件额外换算
  • 低功耗特性:工作电流极低(仅几微安),配合备用电池可维持数年运行

本文将从硬件原理到软件实战,全面讲解STM32 RTC的工作机制、配置方法和高级应用,帮助大家彻底掌握这一核心外设。

一、RTC核心原理:独立运行的"时间管家"

1.1 RTC的基本概念

RTC(Real-Time Clock)即实时时钟,其核心功能是持续跟踪时间,并提供与时间相关的服务(如日历、闹钟)。与系统时钟(如SYSCLK)相比,RTC的最大特点是:

  • 独立于主系统:拥有专属的低功耗时钟源和供电回路
  • 掉电不丢失:主电源断开后,由备用电源(VBAT引脚)供电,时间继续运行
  • 时间连续性:从断电到重新上电,时间无缝衔接,不会重置

1.2 RTC的硬件组成

STM32的RTC模块主要由以下部分组成(以STM32F103为例):

  • 时钟源:支持3种时钟输入(LSE、LSI、HSE_RTC),其中LSE(外部低速晶振,32.768kHz)是最常用的选择(精度高、功耗低)
  • 预分频器:将时钟源分频至1Hz,作为秒计数基准
  • 计数器:包括一个32位的秒计数器(RTC_CNT)和两个16位的预分频寄存器(RTC_PRLH/RTC_PRLL)
  • 日历寄存器:存储年、月、日、时、分、秒等信息(部分型号需通过计数器换算)
  • 闹钟模块:支持设置闹钟时间,当RTC时间与闹钟时间匹配时触发中断或唤醒
  • 备份寄存器(BKP):共10个16位寄存器,用于存储用户数据(如最后一次设置的时间),由VBAT供电,掉电不丢失

1.3 独立供电机制

RTC的独立供电是其核心特性,硬件上通过VBAT引脚实现:

  • 正常工作时,主电源(VDD)为系统供电,同时通过内部二极管为VBAT引脚的备用电源充电(如CR2032纽扣电池)
  • 当主电源掉电(VDD < VBAT),自动切换到备用电源供电,RTC和BKP寄存器继续工作
  • 重新上电后,自动切换回主电源,RTC时间保持连续

硬件设计注意:VBAT引脚需外接备用电源(推荐3V纽扣电池),并串联一个10kΩ限流电阻和0.1μF滤波电容,防止电压波动影响RTC稳定性。

二、RTC时钟源:选择与配置

RTC的精度和稳定性很大程度上取决于时钟源,STM32提供三种可选时钟源:

2.1 时钟源对比

时钟源频率精度功耗适用场景
LSE(外部)32.768kHz高(±20ppm)低(≈1μA)对时间精度要求高的场景(推荐)
LSI(内部)≈40kHz低(±5%)中(≈10μA)无外部晶振,精度要求低的场景
HSE_RTCHSE分频需与主时钟同步的场景

为什么32.768kHz是RTC专用频率?
因为32768 = 2^15,通过15次分频可精确得到1Hz的秒脉冲(32768 / 32768 = 1Hz),无需复杂计算,这是电子时钟的标准频率。

2.2 时钟源配置步骤

以最常用的LSE为例,配置步骤如下:

  1. 使能备份域时钟:RTC和BKP属于备份域,需先使能PWR和BKP时钟
  2. 解锁备份域:备份域默认锁定,需通过PWR寄存器解锁
  3. 启动LSE:使能外部低速晶振,等待稳定
  4. 选择RTC时钟源:通过RCC寄存器配置RTC时钟为LSE

代码实现(HAL库):

// 1. 使能PWR和BKP时钟
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_RCC_BKP_CLK_ENABLE();// 2. 解锁备份域(PWR_CR寄存器的DBP位)
HAL_PWR_EnableBkUpAccess();// 3. 启动LSE并等待稳定
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{Error_Handler(); // LSE启动失败(可能晶振未接或损坏)
}// 4. 配置RTC时钟源为LSE
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{Error_Handler();
}

三、RTC日历功能:从秒计数器到年月日

RTC的核心功能是记录日历时间,但其底层本质是一个32位秒计数器(RTC_CNT),从某个基准时间(如2000年1月1日00:00:00)开始累加秒数。我们需要通过软件将秒数转换为年/月/日/时/分/秒。

3.1 日历时间的表示方法

在STM32中,日历时间通常用结构体表示:

typedef struct
{uint8_t Year;   // 年(0-99,代表2000-2099)uint8_t Month;  // 月(1-12)uint8_t Date;   // 日(1-31)uint8_t Hour;   // 时(0-23)uint8_t Minute; // 分(0-59)uint8_t Second; // 秒(0-59)uint8_t WeekDay;// 星期(1-7,1=周一)
} RTC_DateTypeDef;

3.2 秒计数器与日历的转换

(1)从日历到秒数(设置时间)

当用户设置时间(如2023年10月1日12:00:00)时,需转换为秒计数器的值:

  1. 计算从基准时间到目标时间的总天数(考虑闰年、每月天数)
  2. 总秒数 = 总天数×86400 + 小时×3600 + 分钟×60 + 秒
(2)从秒数到日历(读取时间)

读取RTC_CNT的值后,反向转换为日历:

  1. 总天数 = 总秒数 / 86400,剩余秒数 = 总秒数 % 86400
  2. 从基准时间开始累加总天数,计算年/月/日
  3. 剩余秒数转换为小时/分钟/秒

3.3 闰年与每月天数计算

转换的核心是处理闰年和每月天数,规则如下:

  • 闰年判断:能被4整除且不能被100整除,或能被400整除
  • 每月天数:1/3/5/7/8/10/12月31天,4/6/9/11月30天,2月平年28天、闰年29天

示例代码(判断闰年):

static uint8_t IsLeapYear(uint16_t year)
{// 年份以2000为基准,实际年份=2000+yearyear += 2000;if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))return 1; // 闰年elsereturn 0; // 平年
}

示例代码(获取某月天数):

static uint8_t GetDaysInMonth(uint8_t month, uint8_t isLeapYear)
{const uint8_t daysInMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};if(month == 2 && isLeapYear)return 29;elsereturn daysInMonth[month-1];
}

3.4 HAL库中的日历配置

HAL库封装了日历配置函数,无需手动计算秒数:

// 初始化RTC
RTC_HandleTypeDef hrtc;
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24; // 24小时制
hrtc.Init.AsynchPrediv = 0x7F; // 异步预分频值(LSE=32768Hz时,0x7F=127)
hrtc.Init.SynchPrediv = 0xFF;  // 同步预分频值(0xFF=255),总分频=128×256=32768
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{Error_Handler();
}// 设置时间(12:30:00)
RTC_TimeTypeDef sTime = {0};
sTime.Hours = 12;
sTime.Minutes = 30;
sTime.Seconds = 0;
sTime.TimeFormat = RTC_HOURFORMAT12_AM; // 若用24小时制,此参数无效
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{Error_Handler();
}// 设置日期(2023年10月1日,周日)
RTC_DateTypeDef sDate = {0};
sDate.WeekDay = RTC_WEEKDAY_SUNDAY;
sDate.Month = RTC_MONTH_OCTOBER;
sDate.Date = 1;
sDate.Year = 23; // 2023年
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{Error_Handler();
}

注意:HAL库中AsynchPredivSynchPrediv的和需满足:(AsynchPrediv + 1) × (SynchPrediv + 1) = 时钟源频率(LSE=32768时,128×256=32768)。

四、RTC闹钟功能:定时唤醒与中断

RTC的闹钟功能允许设置一个特定时间,当RTC时间与闹钟时间匹配时,触发中断或唤醒信号,适用于定时任务(如每天8点采集数据)或低功耗唤醒。

4.1 闹钟的工作机制

STM32的RTC通常支持1~2个闹钟(如STM32F103有ALRMA和ALRMB),每个闹钟可独立配置:

  • 匹配条件:可设置匹配年、月、日、时、分、秒中的部分字段(如仅匹配时/分/秒,实现每天同一时间触发)
  • 触发输出:可产生中断(RTC_Alarm_IRQn)或唤醒信号(用于低功耗模式唤醒)

4.2 闹钟配置参数

以ALRMA为例,关键配置参数包括:

  • RTC_AlarmTime:闹钟时间(时/分/秒)
  • RTC_AlarmDateWeekDay:闹钟日期或星期(若设置为星期,则每周触发)
  • RTC_AlarmMask:屏蔽不需要匹配的字段(如屏蔽年/月/日,仅匹配时/分/秒)

4.3 闹钟中断与低功耗唤醒

(1)闹钟中断配置
  1. 配置闹钟时间和匹配条件
  2. 使能RTC闹钟中断(通过NVIC配置)
  3. 在中断服务程序中处理闹钟事件
(2)低功耗唤醒

当系统进入停机模式(Stop Mode)时,RTC闹钟可将其唤醒:

  1. 配置闹钟为唤醒源
  2. 进入停机模式前使能RTC唤醒功能
  3. 闹钟触发时,系统从停机模式唤醒,执行中断服务程序后继续运行

4.4 闹钟配置示例代码

// 配置闹钟A:每天12:30:05触发
void RTC_AlarmConfig(void)
{RTC_AlarmTypeDef sAlarm = {0};// 禁用闹钟A(配置前需先禁用)HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);// 配置闹钟时间sAlarm.AlarmTime.Hours = 12;sAlarm.AlarmTime.Minutes = 30;sAlarm.AlarmTime.Seconds = 5;sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;// 配置日期/星期匹配(此处屏蔽日期,即每天触发)sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;sAlarm.AlarmDateWeekDay = 1; // 日期(因屏蔽,实际无效)sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY; // 屏蔽日期匹配// 使能闹钟Aif (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}// 配置NVIC中断HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}// 闹钟中断服务程序
void RTC_Alarm_IRQHandler(void)
{HAL_RTC_AlarmIRQHandler(&hrtc);
}// 闹钟回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{// 闹钟触发,执行任务(如翻转LED)HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);printf("Alarm triggered!\r\n");
}

关键参数说明RTC_AlarmMask的取值决定匹配精度:

  • RTC_ALARMMASK_NONE:完全匹配(年/月/日/时/分/秒)
  • RTC_ALARMMASK_DATEWEEKDAY:屏蔽日期,每天同一时间触发
  • RTC_ALARMMASK_HOURS:屏蔽日期和小时,每天每分钟匹配秒时触发

五、备份寄存器(BKP):掉电不丢失的数据存储

RTC模块附带的备份寄存器(BKP)用于存储用户数据,由VBAT供电,主电源掉电后数据不丢失,常见用途包括:

  • 存储RTC的基准时间(如最后一次同步的NTP时间)
  • 记录设备运行状态(如开机次数、故障码)
  • 保存用户配置参数(如闹钟设置)

5.1 BKP的基本特性

  • 数量:STM32F103有10个16位寄存器(BKP_DR1~BKP_DR10)
  • 访问权限:需先解锁备份域(同RTC)
  • 写保护:可通过软件设置写保护,防止误修改

5.2 BKP读写示例

// 写入BKP数据(DR1)
void BKP_WriteData(uint16_t data)
{// 解锁备份域(已在RTC初始化时完成)// HAL_PWR_EnableBkUpAccess();BKP->DR1 = data; // 写入数据到DR1
}// 读取BKP数据(DR1)
uint16_t BKP_ReadData(void)
{return BKP->DR1; // 从DR1读取数据
}// 应用示例:记录开机次数
void RecordBootCount(void)
{uint16_t bootCount = BKP_ReadData();bootCount++; // 次数+1BKP_WriteData(bootCount); // 保存printf("Boot count: %d\r\n", bootCount);
}

注意:BKP寄存器复位后仍保留数据,只有VBAT掉电才会重置,因此适合存储需要长期保存的数据。

六、RTC低功耗设计:延长备用电源寿命

RTC的低功耗特性是其核心优势之一,合理设计可显著延长备用电池寿命(如CR2032电池可支持数年)。

6.1 影响功耗的因素

  • 时钟源:LSE(1μA)比LSI(10μA)更省电
  • 工作模式:RTC在停机模式下功耗最低
  • 外围电路:VBAT引脚的限流电阻和滤波电容会增加漏电,需选择低漏电器件

6.2 低功耗配置技巧

  1. 选择LSE时钟源:相比LSI,功耗降低90%
  2. 关闭不必要的功能:如未使用闹钟,禁用闹钟模块
  3. 优化VBAT电路
    • 限流电阻选择10kΩ(太小增加功耗,太大影响充电)
    • 滤波电容选择0.1μF陶瓷电容(低漏电)
    • 备用电池选择CR2032(容量220mAh,适合长期供电)
  4. 进入停机模式:系统空闲时进入停机模式,仅RTC运行

6.3 停机模式与RTC唤醒示例

// 进入停机模式,等待RTC闹钟唤醒
void EnterStopMode(void)
{// 配置RTC闹钟为唤醒源(已在闹钟配置中完成)// 关闭所有不必要的外设时钟__HAL_RCC_GPIOA_CLK_DISABLE();__HAL_RCC_GPIOB_CLK_DISABLE();// ...(其他外设)// 进入停机模式HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);// 唤醒后重新配置系统时钟(停机模式会关闭主时钟)SystemClock_Config();
}// 主循环中调用
while (1)
{// 执行任务...// 任务完成后进入停机模式,等待闹钟唤醒EnterStopMode();
}

唤醒后时钟配置:停机模式会关闭PLL和HSE,唤醒后需重新初始化系统时钟(调用SystemClock_Config)。

七、RTC常见问题与解决方案

7.1 时间不准(走时偏快/偏慢)

原因

  • LSE晶振精度不足(劣质晶振或未加负载电容)
  • 温度变化导致晶振频率偏移
  • 未进行RTC校准

解决方案

  1. 选用高精度32.768kHz晶振(如EPSON、Abracon品牌),并匹配12.5pF负载电容
  2. 进行RTC校准:通过RTC的校准寄存器(RTC_CALIBR)微调频率
    // 校准示例:每32秒增加1个脉冲(补偿偏慢)
    RTC->CALIBR = RTC_CALIBR_PLUS | 0x1F;
    
  3. 定期通过NTP或GPS同步时间(联网设备)

7.2 掉电后时间丢失

原因

  • VBAT引脚未接备用电池或电池电量耗尽
  • 备份域未解锁,导致RTC配置未保存
  • 硬件电路问题(如VBAT引脚短路)

解决方案

  1. 检查VBAT电路:用万用表测量VBAT引脚电压(应为3V左右)
  2. 确认初始化时已调用HAL_PWR_EnableBkUpAccess()解锁备份域
  3. 检查BKP寄存器数据:若BKP数据也丢失,说明VBAT供电中断

7.3 闹钟不触发

原因

  • 闹钟时间设置错误(如设置为过去的时间)
  • 闹钟中断未使能(NVIC配置错误)
  • 闹钟掩码设置不当(匹配条件未满足)

解决方案

  1. 读取当前RTC时间,确认闹钟时间在未来
  2. 检查NVIC配置:HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn)是否调用
  3. 简化闹钟掩码:先测试RTC_ALARMMASK_NONE(完全匹配),再逐步调整

7.4 初始化失败(HAL_RTC_Init返回错误)

原因

  • 备份域未解锁
  • LSE启动失败(晶振未接或损坏)
  • 时钟源配置错误

解决方案

  1. 确保HAL_PWR_EnableBkUpAccess()在RTC初始化前调用
  2. 检查LSE晶振焊接:用示波器测量晶振引脚是否有正弦波(幅度约0.5V峰峰值)
  3. 若LSE无法启动,临时改用LSI时钟源排查问题:
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
    

八、RTC实战项目:多功能时钟系统

下面结合前面的知识,实现一个包含日历显示、闹钟提醒和低功耗功能的时钟系统。

8.1 硬件设计

  • 主控制器:STM32F103C8T6
  • 显示模块:OLED12864(I2C接口)
  • 输入模块:4个按键(设置时间、设置闹钟、加、减)
  • 电源:USB供电(5V)+ CR2032备用电池(VBAT引脚)
  • 指示:LED指示灯(闹钟触发时闪烁)

8.2 软件设计框架

// main.c
int main(void)
{// 初始化HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init(); // OLED初始化MX_USART1_UART_Init(); // 调试串口MX_RTC_Init(); // RTC初始化BKP_Init(); // 备份寄存器初始化// 检查是否首次上电(BKP_DR1为0则是首次)if (BKP_ReadData() == 0){// 首次上电,设置初始时间(2023-10-01 00:00:00)RTC_SetTime(0, 0, 0);RTC_SetDate(23, 10, 1, RTC_WEEKDAY_SUNDAY);BKP_WriteData(1); // 标记为已设置}// 配置闹钟(每天8:00:00)RTC_AlarmConfig(8, 0, 0);// 主循环while (1){// 读取当前时间RTC_DateTypeDef date;RTC_TimeTypeDef time;HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);// 在OLED上显示OLED_DisplayTime(date, time);// 按键处理(设置时间/闹钟)Key_Process();// 无操作时进入低功耗if (Key_IdleTime() > 5000) // 5秒无操作{EnterStopMode();}HAL_Delay(100);}
}

8.3 关键功能模块

(1)OLED显示时间
void OLED_DisplayTime(RTC_DateTypeDef date, RTC_TimeTypeDef time)
{char buf[32];// 显示日期:2023-10-01 Sunsprintf(buf, "20%02d-%02d-%02d ", date.Year, date.Month, date.Date);OLED_ShowString(0, 0, buf);// 显示星期const char* weekday[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};OLED_ShowString(80, 0, (char*)weekday[date.WeekDay-1]);// 显示时间:12:30:05sprintf(buf, "%02d:%02d:%02d", time.Hours, time.Minutes, time.Seconds);OLED_ShowString(0, 2, buf);
}
(2)按键处理(设置时间)
void Key_Process(void)
{if (Key_Pressed(KEY_SET)) // 设置键按下{// 进入时间设置模式,通过加减键调整RTC_EnterSetMode();}
}void RTC_EnterSetMode(void)
{// 禁用闹钟,防止设置时触发HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);// 循环调整时间(省略具体逻辑,通过按键增减时分秒)// ...// 退出时保存设置HAL_RTC_SetTime(&hrtc, &newTime, RTC_FORMAT_BIN);HAL_RTC_SetDate(&hrtc, &newDate, RTC_FORMAT_BIN);// 重新使能闹钟RTC_AlarmConfig();
}

九、总结与扩展

RTC作为STM32的核心外设,其独立供电、日历记录和低功耗唤醒功能使其在嵌入式系统中不可或缺。本文从原理到实战,详细讲解了:

  • RTC的独立供电机制与硬件设计
  • 日历时间的设置与读取(秒计数器与日历转换)
  • 闹钟功能的配置与中断处理
  • 备份寄存器的掉电数据存储
  • 低功耗模式下的RTC唤醒应用

扩展学习

  • RTC校准:深入研究RTC_CALIBR寄存器,实现高精度时间同步
  • 多闹钟管理:在支持双闹钟的型号上实现多任务定时(如ALRMA用于每日任务,ALRMB用于每周任务)
  • 与NTP服务器同步:通过网络获取标准时间,自动校准RTC(适用于物联网设备)

掌握RTC的使用,不仅能实现基础的时间记录,更能为低功耗系统设计和定时任务调度提供核心支撑,是嵌入式工程师必备技能。

附录:RTC相关寄存器速查表

寄存器功能关键位/字段
RTC_CRH控制寄存器高位ALRAE(闹钟A使能)、CNF(配置模式)
RTC_CRL控制寄存器低位RTOFF(寄存器同步标志)、ALRAF(闹钟A标志)
RTC_PRLH/PRLL预分频装载寄存器16位预分频值
RTC_CNT计数器寄存器32位秒计数
RTC_ALRH/ALRL闹钟寄存器闹钟时间值
BKP_DRx备份数据寄存器16位用户数据
RCC_CSR控制/状态寄存器LSERDY(LSE就绪标志)
PWR_CR电源控制寄存器DBP(备份域访问使能)

(注:具体寄存器定义请参考对应型号的《参考手册》)

http://www.xdnf.cn/news/15376.html

相关文章:

  • 客户资源被挖?营销方案泄露?企业经营信息保护避坑指南
  • YOLOv8
  • Win11怎样进入WinRE恢复环境
  • 介绍几个电机驱动芯片(TC1508S、DRV8848)
  • TensorBoard
  • 【QT】多线程相关教程
  • 【面试八股文】2025最新软件测试面试
  • 股票的k线
  • React useState原理解密:从源码到实战
  • 苍穹外卖-day06
  • JavaScript代码段注入:动态抓取DOM元素的原理与实践
  • 巅峰对决:文心4.5 vs DeepSeek R1 vs 通义Qwen3.0——国产大模型技术路线与场景能力深度横评
  • Python-魔术方法-创建、初始化与销毁-hash-bool-可视化-运算符重载-容器和大小-可调用对象-上下文管理-反射-描述器-二分-学习笔记
  • 代码训练LeetCode(46)旋转图像
  • Java应用全链路故障排查实战指南:从系统资源到JVM深度诊断
  • 基于定制开发开源AI智能名片S2B2C商城小程序的社群游戏定制策略研究
  • 不止于监控:深入剖析OpenTelemetry的可观察性生态体系
  • 江协科技STM32入门教程——通信接口
  • Web安全-Linux基础-02-系统基础命令
  • QCustomPlot绘制交互图
  • VUE3 el-table 主子表 显示
  • 【极客日常】后端任务动态注入执行策略的一种技术实现
  • 解决bash终端的路径名称乱码问题
  • Spring之【写一个简单的IOC容器EasySpring】
  • 批量自动运行多个 Jupyter Notebook 文件的方法!!!
  • 创建Spring Boot项目
  • 基于 Redisson 实现分布式系统下的接口限流
  • 网络安全初级第一次作业
  • MacOS环境下运行EasySearch报错无法信任Java包的解决方案
  • ServiceNow Portal前端页面实战讲解