单片机外部晶振故障后自动切换内部晶振——以STM32为例
单片机外部晶振故障后自动切换内部晶振——以STM32为例
作者 | 日期 | 版本 | 说明 |
---|---|---|---|
Dog Tao | 2023.08.02 | V1.0 | 发布初始版本 |
文章目录
- 单片机外部晶振故障后自动切换内部晶振——以STM32为例
- 背景
- 外部晶振与内部振荡器
- STM32F103时钟系统
- STM32F407时钟系统
- 代码实现
- 系统时钟设置流程
- 时钟源检测与切换
- 使用内部振荡器
- 总结
背景
时钟信号是单片机的心跳,对嵌入式系统的长期稳定运行有着至关重要的作用。现代单片机的时钟信号一般都支持外部时钟、外部晶体振荡器、内部RC振荡器等形式的输入。外部晶体振荡器(晶振)由于其高精度、高稳定性、低温飘、低成本的特性,广泛应用于各类对通讯、时间、性能要求严格的场合。
外部晶振与内部振荡器
-
外部晶振:这种时钟源来自于微控制器外部的晶振或者振荡器。晶振是一种机械振动器件,利用压电效应或反压电效应产生精确的频率。外部晶振的主要优点是精度高,稳定性好。但是,他们可能需要额外的电路空间,并且可能更容易受到环境因素如温度和震动的影响。
-
内部振荡器:这是一种集成在微控制器内部的时钟源。它通常是基于RC(电阻-电容)网络的振荡器。内部振荡器的优点是它们不需要额外的硬件,更便宜,更节省空间。但是,他们的频率精度和稳定性通常较低。
在实际应用中,选择哪种时钟源取决于具体的设计需求。对于需要高精度和稳定性的应用,通常会选择外部晶振。对于成本和空间更为重要的应用,内部振荡器可能是一个更好的选择。
STM32F103时钟系统
STM32F103的时钟系统相当复杂,主要有四种时钟源:高速内部(HSI)时钟,高速外部(HSE)时钟,低速内部(LSI)时钟,以及低速外部(LSE)时钟。
- 高速内部(HSI)时钟:一个自校准的内部RC振荡器,提供8MHz的时钟。
- 高速外部(HSE)时钟:可以连接到一个外部4-16 MHz的晶振或者用户提供的时钟源。
- 低速内部(LSI)时钟:一个内部RC振荡器,提供40kHz的时钟,主要供独立看门狗和自动唤醒单元使用。
- 低速外部(LSE)时钟:可以连接到一个外部32.768 kHz的晶振,主要用于RTC(实时时钟)和LCD。
如果使用外部晶振(HSE),STM32F103的最大系统时钟频率可以达到72 MHz。如果使用内部振荡器(HSI),STM32F103的最大系统时钟频率可以达到64 MHz。
STM32F407时钟系统
STM32F407的时钟系统与STM32F103的类似,也包括HSI,HSE,LSI和LSE四种时钟。但是其高速内部时钟频率达到了16MHz。
在STM32F407中,无论是16 MHz的HSI还是最高可以到24 MHz的HSE,都可以通过PLL倍频到168 MHz作为系统时钟频率。
STM32F103的时钟系统
代码实现
系统时钟设置流程
在STM32F103的标准库函数中,“system_stm32f10x.c”文件提供了多个不同频率的系统时钟设置方法,可以通过宏定义的方式条件编译指定时钟频率的设置函数,如下图所示:
基于标准库函数的系统时钟设置调用路径依次为:
- 启动文件“startup_stm32f103x8.s”调用位于“system_stm32f10x.c”文件中的
SystemInit()
函数。 SystemInit()
函数调用SetSysClock()
函数。SetSysClock()
函数根据上述宏定义调用不同的时钟设置函数,将系统时钟设置为指定频率。- 使用全局变量
SystemCoreClock
可获取当前系统的时钟频率。
时钟源检测与切换
在上述位于“system_stm32f10x.c”文件中系统时钟设置函数中已经内置了相关功能的模板,以SetSysClockTo72()
函数为例:
/*** @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 * and PCLK1 prescalers. * @note This function should be used only after reset.* @param None* @retval None*/
static void SetSysClockTo72(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;} if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9);
#else /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}
因此,只需要设计实现当外部晶振启动失败后的情况即可,函数框架如下:
static void SetSysClockTo72(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* 省略无关内容 */ if (HSEStatus == (uint32_t)0x01){/* HSE启动成功 */}else{ /* 自定内容:HSE启动失败,尝试启动内部振荡器,并更新系统时钟 */SetSysClockTo48_HSI();SystemCoreClockUpdate();}
}
使用内部振荡器
HSE启动失败,尝试启动内部振荡器,并更新系统时钟的自定义代码示例如下:
static void SetSysClockTo48_HSI()
{/* 开启HSI 即内部晶振时钟 */RCC->CR |= (uint32_t)0x00000001; /*选择HSI为PLL的时钟源HSI必须2分频给PLL*/RCC->CFGR |= (uint32_t)RCC_CFGR_PLLSRC_HSI_Div2; /*PLLCLK=8/2*12=48MHz 设置倍频得到时钟源PLL的频率*/RCC->CFGR |= (uint32_t)RCC_CFGR_PLLMULL12;/* PLL不分频输出 */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* 使能 PLL时钟 */RCC->CR |= RCC_CR_PLLON;/* 等待PLL时钟就绪*/while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* 选择PLL为系统时钟的时钟源 */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* 等到PLL成为系统时钟的时钟源*/while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}
}
使用内部振荡器设置系统时钟之后,需要调用预设的SystemCoreClockUpdate()
完成时钟频率的更新(更新全局变量SystemCoreClock
的值)。
/*** @brief Update SystemCoreClock variable according to Clock Register Values.* The SystemCoreClock variable contains the core clock (HCLK), it can* be used by the user application to setup the SysTick timer or configure* other parameters.* * @note Each time the core clock (HCLK) changes, this function must be called* to update SystemCoreClock variable value. Otherwise, any configuration* based on this variable will be incorrect. * * @note - The system frequency computed by this function is not the real * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source:* * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)* * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)* * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) * or HSI_VALUE(*) multiplied by the PLL factors.* * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value* 8 MHz) but the real value may vary depending on the variations* in voltage and temperature. * * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value* 8 MHz or 25 MHz, depedning on the product used), user has to ensure* that HSE_VALUE is same as the real frequency of the crystal used.* Otherwise, this function may have wrong result.* * - The result of this function could be not correct when using fractional* value for HSE crystal.* @param None* @retval None*/
void SystemCoreClockUpdate (void)
{uint32_t tmp = 0, pllmull = 0, pllsource = 0;#ifdef STM32F10X_CLuint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)uint32_t prediv1factor = 0;
#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL *//* Get SYSCLK source -------------------------------------------------------*/tmp = RCC->CFGR & RCC_CFGR_SWS;switch (tmp){case 0x00: /* HSI used as system clock */SystemCoreClock = HSI_VALUE;break;case 0x04: /* HSE used as system clock */SystemCoreClock = HSE_VALUE;break;case 0x08: /* PLL used as system clock *//* Get PLL clock source and multiplication factor ----------------------*/pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;#ifndef STM32F10X_CL pllmull = ( pllmull >> 18) + 2;if (pllsource == 0x00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */SystemCoreClock = (HSI_VALUE >> 1) * pllmull;}else{#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;/* HSE oscillator clock selected as PREDIV1 clock entry */SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; #else/* HSE selected as PLL clock entry */if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET){/* HSE oscillator clock divided by 2 */SystemCoreClock = (HSE_VALUE >> 1) * pllmull;}else{SystemCoreClock = HSE_VALUE * pllmull;}#endif}
#elsepllmull = pllmull >> 18;if (pllmull != 0x0D){pllmull += 2;}else{ /* PLL multiplication factor = PLL input clock * 6.5 */pllmull = 13 / 2; }if (pllsource == 0x00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */SystemCoreClock = (HSI_VALUE >> 1) * pllmull;}else{/* PREDIV1 selected as PLL clock entry *//* Get PREDIV1 clock source and division factor */prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;if (prediv1source == 0){ /* HSE oscillator clock selected as PREDIV1 clock entry */SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; }else{/* PLL2 clock selected as PREDIV1 clock entry *//* Get PREDIV2 division factor and PLL2 multiplication factor */prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull; }}
#endif /* STM32F10X_CL */ break;default:SystemCoreClock = HSI_VALUE;break;}/* Compute HCLK clock frequency ----------------*//* Get HCLK prescaler */tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];/* HCLK clock frequency */SystemCoreClock >>= tmp;
}
总结
本文所述的设计方法,能够在外部晶振故障后自动切换到内部晶振,提高系统的可靠性与稳定性。注意,上述示例只在单片机启动时进行时钟源检测,因此,如果是处理运行时的突发时钟故障,需要设计配套的看门狗,在系统陷入异常状态后自动重启系统。
相关文章:

单片机外部晶振故障后自动切换内部晶振——以STM32为例
单片机外部晶振故障后自动切换内部晶振——以STM32为例 作者日期版本说明Dog Tao2023.08.02V1.0发布初始版本 文章目录 单片机外部晶振故障后自动切换内部晶振——以STM32为例背景外部晶振与内部振荡器STM32F103时钟系统STM32F407时钟系统 代码实现系统时钟设置流程时钟源检测…...

Matlab实现决策树算法(附上多个完整仿真源码)
决策树是一种常见的机器学习算法,它可以用于分类和回归问题。在本文中,我们将介绍如何使用Matlab实现决策树算法。 文章目录 1. 数据预处理2. 构建决策树模型3. 测试模型4. 可视化决策树5. 总结6. 完整仿真源码下载 1. 数据预处理 在使用决策树算法之前…...

java中异步socket类的实现和源代码
java中异步socket类的实现和源代码 我们知道,java中socket类一般操作都是同步进行,常常在read的时候socket就会阻塞直到有数据可读或socket连接断开的时候才返回,虽然可以设置超时返回,但是这样比较低效,需要做一个循环来不停扫描…...

ElasticSearch7.6入门学习笔记
在学习ElasticSearch之前,先简单了解一下Lucene: Doug Cutting开发 是apache软件基金会4 jakarta项目组的一个子项目 是一个开放源代码的全文检索引擎工具包不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的…...

《面试1v1》ElasticSearch架构设计
🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结…...

tomcat和nginx的日志记录请求时间
当系统卡顿时候,我们需要分析时间花费在哪个缓解。项目的后端接口可以记录一些时间,此外,在我们的tomcat容器和nginx网关上也可以记录一些有关请求用户,请求时间,响应时间的数据,可以提供更多的信息以便于排…...

数据结构——红黑树基础(博文笔记)
数据结构在查找这一章里介绍过这些数据结构:BST,AVL,RBT,B和B。 除去RBT,其他的数据结构之前的学过,都是在BST的基础上进行微小的限制。 1.比如AVL是要求任意节点的左右子树深度之差绝对值不大于1,由此引出…...

盘点帮助中心系统可以帮到我们什么呢?
在线帮助中心系统是一种强大的软件系统,可以让我们用来组织、管理、发布、更新和维护企业的宝贵知识库和用户文档。今天looklook就详细讲讲,除了大众所熟知的这些,帮助中心系统还有什么特别作用呢? 帮助中心系统的作用 1.快速自助…...

Web3 solidity编写交易所合约 编写ETH和自定义代币存入逻辑 并带着大家手动测试
上文 Web3 叙述交易所授权置换概念 编写transferFrom与approve函数我们写完一个简单授权交易所的逻辑 但是并没有测试 其实也不是我不想 主要是 交易所也没实例化 现在也测试不了 我们先运行 ganache 启动一个虚拟的区块链环境 先发布 在终端执行 truffle migrate如果你跟着我…...

概念解析 | 生成式与判别式模型在低级图像恢复与点云重建中的角力:一场较量与可能性探索
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:生成式模型与判别式模型在低级图像恢复/点云重建任务中的优劣与特性。 生成式与判别式模型在低级图像恢复与点云重建中的角力:一场较量与可能性探索 1. 背景介绍 机器学习…...

【云原生】kubectl命令的详解
目录 一、陈述式资源管理方式1.1基本查看命令查看版本信息查看资源对象简写查看集群信息配置kubectl自动补全node节点查看日志 1.3基本信息查看查看 master 节点状态查看命名空间查看default命名空间的所有资源创建命名空间app删除命名空间app在命名空间kube-public 创建副本控…...

uniapp两个单页面之间进行传参
1.单页面传参:A --> B url: .....?code JSON.stringify(param), 2.单页面传参B–>Auni.$emit() uni.$on()...

uniapp运行项目到iOS基座
2022年9月,因收到苹果公司警告,目前开发者已无法在iOS真机设备使用未签名的标准基座,所以现在要运行到 IOS ,也需要进行签名。 Windows系统,HBuilderX 3.6.20以下版本,无法像MacOSX那样对标准基座进行签名…...

HTTP——九、基于HTTP的功能追加协议
HTTP 一、基于HTTP的协议二、消除HTTP瓶颈的SPDY1、HTTP的瓶颈Ajax 的解决方法Comet 的解决方法SPDY的目标 2、SPDY的设计与功能3、SPDY消除 Web 瓶颈了吗 三、使用浏览器进行全双工通信的WebSocket1、WebSocket 的设计与功能2、WebSocket协议 四、期盼已久的 HTTP/2.01、HTTP/…...

Redis 在电商秒杀场景中的应用
Redis 在电商秒杀场景中的应用 一、简介1.1 简介1.2 场景应用 二、Redis 优势与挑战2.1 优势2.2 秒杀场景的挑战 三、应用场景分析3.1 库存预热代码示例 3.2 分布式锁3.3 消息队列 四、系统设计方案4.1 架构设计4.2 技术选型4.3 数据结构设计 五、Redis 性能优化5.1 集群部署5.…...

大麦订单生成器 大麦一键生成订单
后台一键生成链接,独立后台管理 教程:修改数据库config/Conn.php 不会可以看源码里有教程 下载源码程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3...

Java实现Google cloud storage 文件上传,Google oss
storage 控制台位置 创建一个bucket 点进bucket里面,权限配置里,公开访问,在互联网上公开,需要配置角色权限 新增一个访问权限 ,账号这里可以模糊搜索, 角色配置 给allUser配置俩角色就可以出现 在互联…...

适配器模式(AdapterPattern)
适配器模式 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 优缺点 优点: 单一职责原则。你可以将接口或数据转换代码从程序主要业务逻辑中分…...

Apache Kafka Learning
目录 一、Kafka 1、Message Queue是什么? 2、Kafka 基础架构 3、Kafka安装 4、Offset自动控制 5、Acks & Retries 6、幂等性 7、事务控制 8、数据同步机制 9、Kafka-Eagle 二、Maven项目测试 1、Topic API 2、生产者&消费者 一、Kafka Kafka是…...

手把手教你用idea实现Java连接MySQL数据库
目录 1.下载MySQL 2.下载mysql 的jdbc驱动 3.将驱动jar包导入idea 4.通过Java测试数据库是否连接成功 1.下载MySQL 首先如果没有mysql的需要先下载MySQL,可以看这个教程 MYSQL安装手把手(亲测好用)_程序小象的博客-CSDN博客 2.下载mysql…...

Ubuntu 22.04安装和使用ROS1可行吗
可行。 测试结果 ROS1可以一直使用下去的,这一点不用担心。Ubuntu会一直维护的。 简要介绍 Debian发行版^_^ AI:在Ubuntu 22.04上安装ROS1是可行的,但需要注意ROS1对Ubuntu的支持只到20.04。因此,如果要在22.04上安装ROS1&am…...

83 | Python可视化篇 —— Bokeh数据可视化
Bokeh 是一种交互式数据可视化库,它可以在 Python 中使用。它的设计目标是提供一个简单、灵活和强大的方式来创建现代数据可视化,同时保持良好的性能。Bokeh 支持多种图表类型,包括线图、散点图、柱状图、饼图、区域图、热力图等。此外,它还支持将这些图表组合在一起以创建…...

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection (arXiv 2018)
图像 检测 - RetinaNet: Focal Loss for Dense Object Detection - 密集目标检测中的焦点损失(arXiv 2018) 摘要1. 引言2. 相关工作References 声明:此翻译仅为个人学习记录 文章信息 标题:RetinaNet: Focal Loss for Dense Obje…...

MySQL 与MongoDB区别
一、什么是MongoDB呢 ? MongoDB 是由C语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数据存储为一…...

Kaggle First Place Winner Solution Study——多变量回归问题
本期分享一个Kaggle上playground系列多变量回归问题的第一名解决方案。试着分析、复现、学习一下金牌选手的数据分析思路。 赛题链接: Prediction of Wild Blueberry Yield | Kagglehttps://www.kaggle.com/competitions/playground-series-s3e14第一名解决方案链…...

分布式应用:Zookeeper 集群与kafka 集群部署
目录 一、理论 1.Zookeeper 2.部署 Zookeeper 集群 3.消息队列 4.Kafka 5.部署 kafka 集群 6.FilebeatKafkaELK 二、实验 1.Zookeeper 集群部署 2.kafka集群部署 3.FilebeatKafkaELK 三、问题 1.解压文件异常 2.kafka集群建立失败 3.启动 filebeat报错 4.VIM报错…...

Last-Mile Embodied Visual Navigation 论文阅读
论文阅读 题目:Last-Mile Embodied Visual Navigation 作者:JustinWasserman, Karmesh Yadav 来源:CoRL 时间:2023 代码地址:https://jbwasse2.github.io/portfolio/SLING Abstract 现实的长期任务(例如…...

thunder gbm
文章目录 背景参考官网信息训练调参模型保存推理 背景 想在 GPU 上使用使用闪电般快速的提升方法?了解这个库就好了。在很多任务上,它都比 LightGBM 和 XGBoost 快。 ThunderGBM 的主要特征如下: 通常是其它库的 10 倍。 支持 Python&#x…...

数据结构--单链表
前言 上一章,我们讲了数据结构--动态顺序表,我们会发现有以下问题: 1.当我们要头部或者插入或删除时,都需要进行位置挪动,腾出某一个位置,时间复杂度为0(N); 2.增容需要申请新空间,…...

过程:从虚拟机上添加 git 并成功提交到 GitLab 的全过程
Ⅰ、准备工作: 1、Git 查看: 其一、命令:git --version // 此时就能在虚拟机环境下看到 git 的版本为: git version 2.41.0 其二、如何在虚拟机上安装 git : A、命令 : sudo apt-get install git B、然后再输入虚…...