细说STM32F407单片机RTC的备份寄存器原理及使用方法
目录
一、备份寄存器的功能
二、示例功能
三、项目设置
1、晶振、DEBUG、CodeGenerator、USART6
2、RTC
3、NVIC
4、GPIO 及KEYLED
四、软件设计
1、main.h
2、main.c
3、rtc.c
4、keyled.c、keyled.h
五、运行调试
本实例旨在介绍备份寄存器的作用。本实例继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。本实例将引用本文作者写的其他文章作为参考文献。
参考项目:细说STM32F407单片机RTC的基本原理及闹钟和周期唤醒功能的使用方法-CSDN博客 https://wenchm.blog.csdn.net/article/details/145575366
一、备份寄存器的功能
STM32F407的RTC有20个32位的备份寄存器,寄存器名称为RTC_BKP0R~RTC_BKP19R。这些备份寄存器由备用电源VBAT供电,在系统复位或主电源关闭时,只要VBAT有电,备份寄存器的内容就不会丢失。所以,备份寄存器可以用来存储一些用户数据。
文件stm32f4xx_hal_rtc_ex.h中有读写备份寄存器的功能函数,其原型定义如下:
uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc,uint32_t BackupReg);
void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc,uint32_t BackupReg,uint32_t Data);
其中,参数BackupReg是备份寄存器编号,文stm32f4xx_hal_rtc_ex.h定义了20个备份寄存器编号的宏,定义如下:
#define RTC_BKP_DR0 0x00000000U
#define RTC_BKP_DR1 0x00000001U
/*省略了中间的定义代码*/
#define RTC_BKP_DR18 0x00000012U
#define RTC_BKP_DR19 0x00000013U
RTC也可以由VBAT供电,在系统复位或主电源关闭时,RTC的日历不受影响。但是在参考项目中,因为在系统复位时调用了RTC初始化函数MX_RTC_Init(),而这个函数总是设置RTC的日期和时间,所以复位后,RTC的日期时间又从CubeMX里设置的初始日期时间开始了。
可以使用备份寄存器对参考项目进行修改,使得系统在复位时不再自动设置RTC的初始日期时间,而是由备份寄存器RTC_BKP_DR0的内容决定,而且可以把RTC当前时间保存到备份寄存器。
二、示例功能
本实例,将设计一个示例,演示备份寄存器的使用。示例具有如下的功能和操作流程。
- 在RTC初始化函数MX_RTC_Init()中增加代码,读取备份寄存器RTC_BKP_DR0的内容,如果值为0,就设置RTC为初始时间和日期,如果值为1,就不设置RTC的日期和时间。
- 在程序运行时,可以修改保存到备份寄存器RTC_BKP_DR0的值,可以保存0或1。
- 将RTC当前时间的时、分、秒数据保存到RTC_BKP_DR2到RTC_BKP_DR4的3个寄存器里。RTC_BKP_DR1里的值为1时,表示保存了RTC时间。
- 读取备份寄存器RTC_BKP_DR0到RTC_BKP_DR4的内容,显示到串口助手上。
- 使用RTC周期唤醒中断,唤醒中断周期1s,在唤醒中断里读取时间后在串口助手上显示。本示例还用到4个按键和2个LED,所以继续引用作者发布的其它参考项目中的KEYLED文件中的程序文件。
- 菜单设计:
[S2]KeyUp = Reset RTC time on startup. //按下S2键,用初始时间重置RTC
[S3]KeyDown = Read BKUP registers. //按下S3键,读取备份寄存器
[S4]KeyLeft = Save current time to BKUP. //按下S4键,把当前时间保存到RTC备份寄存器
[S5]KeyRight= Change RTC time from BKUP. //按下S5键,用备份寄存器存储的时间重置RTC时间
三、项目设置
1、晶振、DEBUG、CodeGenerator、USART6
与参考文章相同。
2、RTC
在RTC的模式设置中,启用时钟源和日历,设置WakeUp模式为Internal WakeUp。在参数设置部分,设置数据格式为Binary data format,设置唤醒时钟为1Hz信号,唤醒周期数为0,这样就会每秒产生一次唤醒中断。


3、NVIC
在NVIC中开启周期唤醒中断,设置RTC抢占优先级为1。

4、GPIO 及KEYLED
4个按键和2个LED。引用文件夹KEYLED的方法请参考本文作者发布的其它文章。
| 程序标签 | 板上名称 | 引脚名称 | 引脚功能 | GPIO模式 | 默认电平 | 上拉或下拉 |
| LED1 | D1 | PA6 | GPIO_Output | 推挽输出 | High | 上拉 |
| LED2 | D2 | PA4 | GPIO_Output | 推挽输出 | High | 上拉 |
| KeyRight | S5 | PF6 | GPIO_Input | 输入 | 上拉 | |
| KeyDown | S3 | PD3 | GPIO_Input | 输入 | 上拉 | |
| KeyLeft | S4 | PF7 | GPIO_Input | 输入 | 上拉 | |
| KeyUp | S2 | PA0 | GPIO Input | 输入 | 上拉 |
四、软件设计
1、main.h
/* USER CODE BEGIN Private defines */
void RTC_ToggleReset();
void RTC_SaveToBKUP();
void RTC_LoadFromBKUP();
void RTC_ReadBKUP();
/* USER CODE END Private defines */
2、main.c
/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
RTC_TimeTypeDef sTime; //RTC读取时间和日期的结果数据
RTC_DateTypeDef sDate;uint8_t RTC_isReading=0; //RTC是否正在读日期时间数据
/* USER CODE END PV */
/* USER CODE BEGIN 2 */__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); //禁止RTC周期唤醒printf("Demo11_2_RTC_Backup:Using Backup Registers.\r\n");uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0); //读取备份寄存DR0printf("Reset RTC time on startup: ");if ((iniRTC & 0x01)==0)printf("Yes.\r\n");elseprintf("No.\r\n");/* USER CODE END 2 */
/* Infinite loop *//* USER CODE BEGIN WHILE *///显示菜单,也可以放在USER CODE BEGIN 2里printf("[S2]KeyUp = Reset RTC time on startup(LED2_ON).\r\n");printf("[S3]KeyDown = Read BKUP registers.\r\n");printf("[S4]KeyLeft = Save current time to BKUP.\r\n");printf("[S5]KeyRight= Change RTC time from BKUP.\r\n\r\n");__HAL_RTC_WAKEUPTIMER_ENABLE(&hrtc); //重启RTC周期唤醒while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */KEYS curKey=ScanPressedKey(KEY_WAIT_ALWAYS);switch(curKey){case KEY_UP: //[S2]KeyUp,改变保存到备份寄存器DR0的数值0 or 1RTC_ToggleReset();break;case KEY_DOWN: //[S3]KeyDown,读取5个备份寄存器的数据并显示RTC_ReadBKUP();case KEY_LEFT: //[S4]KeyLeft,将RTC当前时间保存到备份寄存器RTC_SaveToBKUP();break;case KEY_RIGHT: //[S5]KeyRight,从备份寄存器读取时间,改变RTC时间RTC_LoadFromBKUP();break;default:break;}HAL_Delay(300); //消抖}/* USER CODE END 3 */
main()函数里在完成了外设初始化之后,执行__HAL_RTC_WAKEUPTIMER_DISABLE (&hrtc),禁止了RTC周期唤醒单元。在进入while死循环之前,再开启RTC的周期唤醒单元。
调用函数HAL_RTCEx_BKUPRead()读取备份寄存器RTC_BKP_DR0的内容,如果寄存器的值为0,就会在MX_RTC_Init()里用CubeMX设置的初始日期和时间设置RTC的日期时间;如果寄存器的值不为0,在MX_RTC_Init()里就不会设置RTC的日期和时间。后一种情况下,在按复位键[S6]使系统复位时,RTC仍然保持连续的时间,因为RTC工作在备份域,不会在系统复位时复位。
然后,在串口助手上显示了一个模拟菜单。
在while循环里读取按键输入,用4个按键模拟菜单项的选择,按下某个按键后就执行与菜单项对应的功能。按键的响应代码封装为4个函数。
/* USER CODE BEGIN 4 */
//周期唤醒中断回调函数
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{LED1_Toggle();RTC_isReading = 1; //RTC正在读取数据,该变量的作用类似于RTOS中的二值信号量if (HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK){//调用HAL_RTC_GetTime()之后必须调用HAL_RTC_GetDate()以解锁数据,才能连续更新日期和时间HAL_RTC_GetDate(hrtc, &sDate, RTC_FORMAT_BIN);RTC_isReading = 0; //RTC结束了读取数据//显示时间hh:mm:sschar str[40];sprintf(str,"RTC Time = %2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);printf(" %s\r\n",str);}
}/* 翻转保存备份寄存器RTC_BKP_DR0的值 */
void RTC_ToggleReset() //S2
{uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0);iniRTC = !iniRTC;if ((iniRTC & 0x01)==0){ //存储值为0时,用CubeMX中的值复位日期时间printf("Reset RTC time on startup.\r\n");LED2_ON();}else{printf("Not reset RTC time on startup.\r\n");LED2_OFF();}//__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc); //取消写保护HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0, iniRTC); //写入备份寄存器DR0//__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc); //开启写保护
}/* RTC时间保存到备份寄存器 */
void RTC_SaveToBKUP() //S4
{while (RTC_isReading) //如果RTC的WakeUp中断里正在读取数据,就等待其读取完HAL_Delay(1);//__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc); //取消写保护HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1, 0x01); //0x01=保存了时间的标志HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR2, sTime.Hours); //使用全局变量sTime,不再读取当前时间HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, sTime.Minutes);HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, sTime.Seconds);//__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc); //开启写保护char timeStr[30];sprintf(timeStr,"%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds); //转换为字符串,自动添加"\0"printf("Current time %s is saved in BKUP.\r\n",timeStr);
}/* 用保存的时间设置为RTC时间 */
void RTC_LoadFromBKUP() //S5
{uint32_t isTimeSaved = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1); //读取备份寄存DR1if (isTimeSaved){RTC_TimeTypeDef time;time.Hours = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);time.Minutes = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);time.Seconds = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; //这两个参数还是有用的,如果不设置这2个参数,设置的小时数会自动减1time.StoreOperation = RTC_STOREOPERATION_SET;//HAL_Delay(10); //必须加这个延时,否则设置的时间会错乱while(RTC_isReading) //如果RTC正在WakeUp中断里读取数据,就等待其读完HAL_Delay(1);/*函数HAL_RTC_SetTime()内部在修改RTC的寄存器之前,会调用 __HAL_RTC_WRITEPROTECTION_DISABLE()取消写保护,写完之后,会调用 __HAL_RTC_WRITEPROTECTION_ENABLE() 重新开启写保护 */if (HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BIN) == HAL_OK)printf("Load and set BKUP time, success.\r\n");elseprintf("Load and set BKUP time, failure.\r\n");}elseprintf("No BKUP time is saved.\r\n");
}/* 读取5个备份寄存器内容并显示 */
void RTC_ReadBKUP() //S3
{uint32_t regValue;char regStr[40];regValue = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0); //0=系统复位时复位RTC时间sprintf(regStr,"Reset RTC ,BKP_DR0= %lu",regValue); //转换为字符串,自动添加"\0"printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1); //1=有时间数值sprintf(regStr,"Time is saved,BKP_DR1= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2); //Hoursprintf(regStr,"Saved time(Hour) ,BKP_DR2= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3); //Minutesprintf(regStr,"Saved time(Min) , BKP_DR3= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4); //Secondsprintf(regStr,"Saved time(Sec) , BKP_DR4= %lu",regValue);printf(" %s\r\n",regStr);
}//串口打印
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */
回调函数HAL_RTCEx_WakeUpTimerEventCallback()处理RTC周期唤醒中断。
其余的4个函数,是对4个菜单项的响应代码的封装。
3、rtc.c
/* USER CODE BEGIN Check_RTC_BKUP */uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0); //读取备份寄存DR0if ((iniRTC & 0x01)) //非零,无需初始化RTC日期时间{if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,0,RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)Error_Handler();return; //提前退出函数}/* USER CODE END Check_RTC_BKUP */
沙箱中添加的代码就是用函数HAL_RTCEx_BKUPRead()读取备份寄存器RTC_BKP_DR0的内容,如果寄存器的值不为0,就在执行完HAL_RTCEx_SetWakeUpTimer_IT()设置和启动周期唤醒后,退出函数;如果寄存器的值为0,就继续执行函数内后面的代码。
这样,就在函数MX_RTC_Init()中加入了用户功能代码,使得在系统复位时,RTC不必设置初始日期和时间。
4、keyled.c、keyled.h
引用KEYLED文件夹下的 keyled.c、keyled.h,使用方法请参考本文作者发布的其他文章。
五、运行调试
首次下载,或按S6键复位,显示系统菜单。重要的信息是显示当前从哪里重置RTC时间的信息。如果YES(LED2亮)则从RTC初始化值(15:30:0)重置RTC时间,否则不是;
按S2键切换从哪里重置RTC时间。比如,下图,每次按下S6复位键,系统都从RTC初始化值重置时间,否则不重置时间,即当LED2灯不亮(DR0=1)时,按下复位键S6,不改变RTC时间,连续显示RTC时间。

按S4键,存储当前时间到备份寄存器;按S3键,读取备份存储器内容并保存当前最新值到备份寄存器;按S5键,用备份寄存器内容重置RTC时间;

相关文章:
细说STM32F407单片机RTC的备份寄存器原理及使用方法
目录 一、备份寄存器的功能 二、示例功能 三、项目设置 1、晶振、DEBUG、CodeGenerator、USART6 2、RTC 3、NVIC 4、GPIO 及KEYLED 四、软件设计 1、main.h 2、main.c 3、rtc.c 4、keyled.c、keyled.h 五、运行调试 本实例旨在介绍备份寄存器的作用。本实例继续使…...
MATLAB计算反映热需求和能源消耗的度数日指标(HDD+CDD)(全代码)
目录 度数日(Degree Days, DD)概述计算公式MATLAB计算代码调用函数1:计算单站点的 CDD参考度数日(Degree Days, DD)概述 度数日(Degree Days, DD)是用于衡量建筑、城市和地区的热需求和能源消耗模式的指标。它分为两部分: 加热度日(Heating Degree Days, HDD):当室…...
J6 X8B/X3C切换HDR各帧图像
1、OV手册上的切换命令 寄存器为Ox5074 各帧切换: 2、地平线control tool实现切换命令 默认HDR模式出图: HCG出图: LCG出图 SPD出图 VS出图...
09-轮转数组
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 方法一:使用额外数组 function rotate(nums: number[], k: number): void {const n nums.length;k k % n; // 处理 k 大于数组长度的情况const newNums new A…...
用vue3写一个好看的wiki前端页面
以下是一个使用 Vue 3 Element Plus 实现的 Wiki 风格前端页面示例,包含现代设计、响应式布局和常用功能: <template><div class"wiki-container"><!-- 头部导航 --><el-header class"wiki-header"><d…...
瑞芯微烧写工具
文章目录 前言一、安装驱动二、安装烧写工具1.直接解压压缩包2. 如何使用 三、MASKROM 裸机必备四、LOADER 烧写,前提是搞过第三步没问题五、Update.img包的烧录六、linux下烧写总结 前言 提示:这里可以添加本文要记录的大概内容: 项目需要…...
说下JVM中一次完整的GC流程?
大家好,我是锋哥。今天分享关于【说下JVM中一次完整的GC流程?】面试题。希望对大家有帮助; 说下JVM中一次完整的GC流程? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM中的一次完整的垃圾回收(GC)流程可以概括为…...
Open FPV VTX开源之OSD使用分类
Open FPV VTX开源之OSD使用分类 1. 源由2. 硬件2.1 【天空端】SigmaStar2.2 【天空端】Raspberry Pi2.3 【地面端】 3. 软件3.1 天空端软件3.2 地面端软件 4. 分类4.1 嵌入式OSD分类A1-嵌入式OSD:SigmaStar Android分类A2-嵌入式OSD:SigmaStar Hi3536分…...
智慧农业-虫害及生长预测
有害生物防控系统是一个综合性的管理体系,旨在预防和控制对人类生活、生产甚至生存产生危害的生物。这些生物可能包括昆虫、动物、植物、微生物乃至病毒等。 一、系统构成 1、监测预警系统:利用智能传感器、无人机、遥感技术等手段,实时监测…...
Python 识别图片和扫描PDF中的文字
目录 工具与设置 Python 识别图片中的文字 Python 识别图片中的文字及其坐标位置 Python 识别扫描PDF中的文字 注意事项 在处理扫描的PDF和图片时,文字信息往往无法直接编辑、搜索或复制,这给信息提取和分析带来了诸多不便。手动录入信息不仅耗时费…...
C语言如何知道当前系统中的编译器数据类型的大小是多少?
在 C 语言中,你可以使用sizeof运算符来确定当前系统中编译器数据类型的大小,该运算符返回一个size_t类型的值,表示所操作对象或数据类型占用的字节数。下面为你详细介绍使用方法: 1. 基本数据类型大小的获取 基本数据类型如char…...
gitlab Webhook 配置jenkins时“触发远程构建 (例如,使用脚本)”报错
报错信息: <html> <head> <meta http-equiv"Content-Type" content"text/html;charsetISO-8859-1"/> <title>Error 403 No valid crumb was included in the request</title> </head> <body><h2…...
Mysql中使用sql语句生成雪花算法Id
🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…...
/etc/profile vs ~/.bashrc:如何正确使用?
在 Linux 或 WSL 环境中,我们经常需要配置环境变量、命令别名、路径等信息。然而,许多人在配置时会纠结:到底应该放在 /etc/profile 还是 ~/.bashrc?本文将全面解析它们的区别,并帮助你做出正确的选择。 1. 什么是 /et…...
SpringBoot实战:高效获取视频资源
文章目录 前言技术实现SpringBoot项目构建产品选取配置数据采集 号外号外 前言 在短视频行业高速发展的背景下,海量内容数据日益增长,每天都有新的视频、评论、点赞、分享等数据涌现。如何高效、精准地获取并处理这些庞大的数据,已成为各大平…...
Flutter_学习记录_数据更新的学习
Flutter 如果界面上有数据更新时,目前学习到的有3种: 第一种: 直接用 StatefulWidget组件,然后当数据更新时,调用setState的方法更新数据,页面上的数据会直接更新;第二种: 用 State…...
c++ 多线程知识汇总
一、std::thread std::thread 是 C11 引入的标准库中的线程类,用于创建和管理线程 1. 带参数的构造函数 template <class F, class... Args> std::thread::thread(F&& f, Args&&... args);F&& f:线程要执行的函数&…...
day09_实时类标签/指标
文章目录 day09_实时类标签/指标一、日志数据实时采集2、Flume简介2.3 项目日志数据采集Flume配置2.3.1 涉及的Flume组件和参数2.3.2 Nginx日志采集2.3.3 用户行为日志采集 二、Nginx日志数据统计1、日志格式说明2、数据ETL2.1 日志抽取2.1.1 正则表达式2.1.2 基于Spark实现Ngi…...
【前端开发学习笔记16】Vue_9
文章分类架子 多个页面复用,封装成组件: props 定制标题默认插槽 default 定制内容主体具名插槽 extra 定制按钮 <template><el-card class"page-container"><template #header><div class"header"><s…...
Bash 中的运算方式
目录 概述: 1. (()) 运算符 2. let 命令 3. expr 命令 4. $[] 直接运算 5. bc(计算器,支持浮点数) 6. awk(强大的文本处理工具,也可计算) 概述: Bash 本身只支持整数运算&am…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
