STM32F103驱动VL53L0X激光测距:IIC底层与初始化避坑指南
简介这份资源面向嵌入式开发初学者与需要快速集成测距功能的工程师提供基于STM32F103微控制器驱动VL53L0X飞行时间测距传感器的完整IIC方案。内容涵盖GPIO模拟IIC总线的初始化、收发与错误处理VL53L0X的初始化、启动测量、读取距离等API调用以及HAL库与自定义驱动库的配合使用并附有技术文档与用户指南辅助理解传感器原理。压缩包共238个文件约8.28MB以c源码、h头文件、o目标文件、d依赖文件及crf编译记录为主另含uvprojx工程、sct链接脚本、hex与axf固件等可直接在KEIL UV5中编译运行。目前已有1724人学习下载。通过研究工程结构与驱动代码读者能掌握IIC时序调试、传感器参数配置与数据读取的完整流程并可将方案迁移到其他类似硬件平台。1. 从一块“测不准”的板子说起VL53L0X 在 STM32F103 上到底怎么跑起来手头有一块 STM32F103 最小系统板加上一个 VL53L0X 激光测距模块想做个简单的距离检测装置。接线不复杂VCC、GND、SCL、SDA 四根线一接打开 Keil 建工程写几行 IIC 读写函数结果读出来的距离值要么是 8190要么是 0偶尔蹦出个正常值又马上跳回去。翻遍数据手册发现寄存器一大堆初始化流程长得吓人IIC 时序稍微不对就全盘皆输。这个场景太常见了VL53L0X 虽然是个成熟的 ToF 测距传感器但它的 IIC 驱动并不是“接上就能用”那么简单。这份资源就是围绕 STM32F103 的硬件 IIC 和软件模拟 IIC 两种方式把 VL53L0X 从底层寄存器操作到上层距离读取的完整驱动链路拆开适合正在做嵌入式测距项目、需要快速把传感器跑起来的开发者。下面从工程结构开始一步步把这份驱动代码讲透。2. 工程结构与 IIC 底层驱动从目录划分到引脚配置拿到一份 STM32F103 的 VL53L0X 驱动代码第一件事不是急着编译而是先看清楚它的目录怎么分的。一个合格的工程不会把所有 .c 文件堆在同一个文件夹里那样后期改起来就是灾难。2.1 目录层级与文件职责常见的做法是按“硬件抽象层 传感器驱动层 应用层”来切分。以这份资源为例典型的目录结构是这样的Project/ ├── CMSIS/ # 内核相关头文件 ├── STM32F10x_StdPeriph_Driver/ # 标准外设库 ├── User/ │ ├── main.c # 主程序入口 │ ├── stm32f10x_it.c # 中断服务函数 │ └── system_stm32f10x.c # 系统时钟配置 ├── Hardware/ │ ├── iic.c / iic.h # IIC 底层驱动硬件或模拟 │ ├── vl53l0x.c / vl53l0x.h # 传感器驱动 │ └── delay.c / delay.h # 延时函数 └── Output/ # 编译输出这个划分的好处是换 MCU 平台时只需要改 Hardware 层里的 IIC 引脚定义和延时函数vl53l0x.c 里的寄存器操作逻辑基本不用动。我一般会把 vl53l0x.c 里的硬件相关宏定义单独抽出来放在头文件顶部比如VL53L0X_IIC_PORT、VL53L0X_SCL_PIN这些方便移植。2.2 硬件 IIC 与模拟 IIC 的选择STM32F103 有硬件 IIC 外设但用过的人都知道它有个“玄学”问题在某些工况下会卡死在总线忙状态尤其是多设备挂载或者线缆较长的时候。所以这份驱动同时提供了两种实现方式通过一个宏来切换// iic.h 中选择 IIC 模式 #define IIC_MODE_HARDWARE 0 // 1: 使用硬件 IIC 0: 使用模拟 IIC #define IIC_MODE_SIMULATE 1模拟 IIC 的代码更直观也更容易调试。下面是模拟 IIC 的起始信号和字节写入函数// 模拟 IIC 起始信号SCL 高时 SDA 由高变低 void IIC_Start(void) { SDA_OUT(); // SDA 设为输出 IIC_SDA 1; IIC_SCL 1; delay_us(4); // 保持时间VL53L0X 要求 0.6us IIC_SDA 0; // 拉低 SDA 产生起始条件 delay_us(4); IIC_SCL 0; // 钳住 SCL准备发送数据 } // 向 IIC 总线写入一个字节返回从机应答位 // data: 待写入的 8 位数据 // 返回值: 0-应答成功 1-应答失败 u8 IIC_Wait_Ack(void) { u8 ucErrTime 0; SDA_IN(); // SDA 设为输入释放总线 IIC_SDA 1; delay_us(1); IIC_SCL 1; delay_us(1); while (READ_SDA) // 等待从机拉低 SDA { ucErrTime; if (ucErrTime 250) // 超时退出防止死循环 { IIC_Stop(); return 1; } } IIC_SCL 0; return 0; }这里有几个参数需要根据实际硬件调整。delay_us(4)是模拟 IIC 的时钟频率控制VL53L0X 支持最高 400kHz 的 IIC 速率4us 的延时对应大约 125kHz留了足够余量。如果线缆很短、上拉电阻合适可以改成 2us 试试。ucErrTime 250这个超时阈值也不是固定的主频 72MHz 下大概对应几百微秒如果从机响应慢可以适当加大。2.3 VL53L0X 的 IIC 地址与读写时序VL53L0X 的 7 位 IIC 地址是 0x29写操作时地址字节为 0x52读操作为 0x53。它的寄存器地址是 16 位的所以读写时序比常见的 8 位寄存器传感器多一个字节// 向 VL53L0X 指定寄存器写入一个字节 // reg: 16 位寄存器地址 data: 待写入数据 u8 VL53L0X_WriteByte(u16 reg, u8 data) { IIC_Start(); IIC_Send_Byte(0x52); // 发送写地址 if (IIC_Wait_Ack()) return 1; IIC_Send_Byte(reg 8); // 寄存器高 8 位 IIC_Wait_Ack(); IIC_Send_Byte(reg 0xFF); // 寄存器低 8 位 IIC_Wait_Ack(); IIC_Send_Byte(data); // 写入数据 if (IIC_Wait_Ack()) return 1; IIC_Stop(); delay_us(10); // 等待传感器内部处理 return 0; }注意delay_us(10)这个等待VL53L0X 在收到写命令后需要一定时间把数据写入内部寄存器连续写多个寄存器时如果不加延时后面写入的值可能会覆盖前面的。这个坑我在第一次调试时踩过读出来的校准数据全是 0查了半天才发现是写太快了。3. 核心驱动拆解VL53L0X 初始化流程与距离读取底层 IIC 通了之后真正的难点在于 VL53L0X 的初始化。这个传感器内部有上百个寄存器官方给的初始化流程是一长串的寄存器写入序列少写一个或者顺序错了测出来的距离就不对。3.1 初始化流程的五个阶段VL53L0X 的初始化可以拆成五个阶段上电复位、私有寄存器解锁、参考校准、偏移校准、配置测量模式。每个阶段都有对应的寄存器操作下面按顺序讲。第一阶段是上电后的基本检查。先读VL53L0X_REG_IDENTIFICATION_MODEL_ID地址 0xC0正常应该返回 0xEE。如果读不到说明 IIC 通信有问题后面的都不用看了。// 检查 VL53L0X 是否在线 u8 VL53L0X_CheckID(void) { u8 id VL53L0X_ReadByte(0xC0); // 模型 ID 寄存器 if (id 0xEE) return 0; // 正常 return 1; // 异常 }第二阶段是私有寄存器解锁。VL53L0X 有一组“私有寄存器”地址范围 0x00 到 0x7F默认是锁定的需要先写 0x01 到 0x88 寄存器解锁再写 0x00 到 0x80 寄存器使能。// 解锁私有寄存器 void VL53L0X_Private_Unlock(void) { VL53L0X_WriteByte(0x88, 0x00); // 解锁私有寄存器 VL53L0X_WriteByte(0x80, 0x01); // 使能私有寄存器访问 VL53L0X_WriteByte(0xFF, 0x01); // 切换到私有寄存器页 VL53L0X_WriteByte(0x00, 0x00); // 选择页 0 }第三阶段是参考校准。这一步需要读取 SPAD 的参考值写入VL53L0X_REG_REFERENCE_SPAD寄存器。代码比较长核心逻辑是// 参考校准简化版完整版需要读取多个寄存器 void VL53L0X_Ref_Calibration(void) { u8 ref_spad; VL53L0X_WriteByte(0x4F, 0x00); // 关闭所有 SPAD VL53L0X_WriteByte(0x4E, 0x2C); // 使能参考 SPAD VL53L0X_WriteByte(0x4F, 0x01); // 使能一个 SPAD VL53L0X_WriteByte(0x51, 0x01); // 设置 SPAD 使能 VL53L0X_WriteByte(0x52, 0x00); // 清除中断 VL53L0X_WriteByte(0x61, 0x00); // 设置测量模式 VL53L0X_WriteByte(0x62, 0x00); VL53L0X_WriteByte(0x63, 0x00); VL53L0X_WriteByte(0x81, 0x01); // 启动参考校准 VL53L0X_WriteByte(0x00, 0x01); // 等待校准完成 while (VL53L0X_ReadByte(0x00) 0x01); // 轮询等待 ref_spad VL53L0X_ReadByte(0x4E); // 读取参考值 VL53L0X_WriteByte(0x4E, ref_spad); // 写回参考值 }第四阶段是偏移校准这一步需要实际测量一个已知距离的物体计算偏移量。如果应用场景对精度要求不高可以跳过用默认值。第五阶段是配置测量模式。VL53L0X 支持单次测量和连续测量两种模式通过SYSTEM_SEQUENCE_CONFIG寄存器配置。单次测量适合低功耗场景连续测量适合实时性要求高的场景。3.2 距离读取与数据解析初始化完成后读取距离就相对简单了。触发一次测量等待中断然后读取结果寄存器// 读取一次距离值单位 mm // 返回值: 距离值8190 表示超量程或测量失败 u16 VL53L0X_ReadDistance(void) { u16 distance; VL53L0X_WriteByte(0x00, 0x01); // 启动单次测量 while (VL53L0X_ReadByte(0x00) 0x01); // 等待测量完成 distance VL53L0X_ReadByte(0x1E); // 读取距离高 8 位 distance (distance 8) | VL53L0X_ReadByte(0x1F); // 拼接低 8 位 return distance; }这里有个细节距离结果寄存器是 0x1E 和 0x1F高字节在前。读出来的值单位是毫米量程最大约 2000mm。如果返回 8190说明测量超时或者信号太弱常见原因是目标物体太远、反射率太低或者环境光太强。3.3 中断方式与轮询方式的取舍上面的代码用的是轮询方式简单但占用 CPU。如果主循环里还有其他任务建议用中断方式。VL53L0X 的 GPIO1 引脚在测量完成时会输出高电平可以接到 STM32 的外部中断引脚上// 外部中断服务函数中置位标志 void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line1) ! RESET) { vl53l0x_int_flag 1; // 通知主循环测量完成 EXTI_ClearITPendingBit(EXTI_Line1); } } // 主循环中检查标志 if (vl53l0x_int_flag) { vl53l0x_int_flag 0; distance VL53L0X_ReadDistance(); }中断方式的好处是不用死等但要注意 GPIO1 的默认电平状态有些模块上电后 GPIO1 就是高电平需要在初始化时配置好中断触发边沿。4. 避坑与常见问题排查那些让测距值跳来跳去的坑VL53L0X 的驱动调试过程中有几个问题几乎每个人都会遇到。下面按“现象 → 原因 → 解决”的方式列出来都是实际调试中踩过的。4.1 读出的距离值一直是 8190现象初始化看起来正常ID 也能读到 0xEE但每次读距离都是 8190。原因8190 是 VL53L0X 的超量程标志值说明测量没有有效回波。常见原因有三个一是目标物体太远超出了量程二是目标物体是黑色或透明材质反射率太低三是测量模式配置不对比如把测量时间设得太短。解决先用一张白纸放在 10cm 处测试排除物体因素。如果还是 8190检查SYSTEM_SEQUENCE_CONFIG寄存器的配置确保测量时间足够。常见做法是把测量时间设为 33ms 以上对应寄存器VL53L0X_REG_MEASUREMENT_TIMING_BUDGET写入 0x00 和 0x64。4.2 距离值偶尔跳变不稳定现象大部分时候读数正常但偶尔会跳出一个明显偏大或偏小的值。原因VL53L0X 对环境光比较敏感尤其是阳光直射或者强光手电照射时。另外如果电源纹波较大也会影响测量稳定性。解决在传感器上方加一个遮光罩或者把测量模式改为“高精度模式”增加测量时间。电源方面在 VCC 和 GND 之间并一个 100nF 和 10uF 的电容能明显改善。4.3 IIC 通信失败读不到 ID现象上电后读 0xC0 寄存器返回 0x00 或 0xFF。原因IIC 引脚接反、上拉电阻缺失、地址错误、时序不对都有可能。VL53L0X 的 SDA 和 SCL 需要 4.7k 到 10k 的上拉电阻有些模块自带了有些没有。解决先用示波器看 SCL 和 SDA 的波形确认起始信号和地址字节是否正确。如果没有示波器用模拟 IIC 的方式在IIC_Start()里加个 LED 翻转看程序有没有卡在IIC_Wait_Ack()里。4.4 初始化后第一次测量特别慢现象上电后第一次读距离要等好几秒后面就正常了。原因VL53L0X 上电后需要加载固件这个过程大约需要 1.2ms但如果电源上升沿太慢或者复位不充分加载时间会变长。解决在初始化前加一个 10ms 的延时确保电源稳定。另外XSHUT 引脚如果没用到要拉高不能悬空。4.5 多个传感器挂载时地址冲突现象两个 VL53L0X 接在同一条 IIC 总线上只能读到一个。原因VL53L0X 的默认地址都是 0x29两个设备同时上电就会冲突。解决用 XSHUT 引脚分时启动先让一个传感器进入复位状态改另一个的地址然后再启动被复位的那个。改地址的寄存器是VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS0x8A写入新地址后需要重新初始化。5. 二次开发与移植把驱动塞进你的项目里这份驱动的价值不在于跑通一个 Demo而在于能快速移植到实际项目里。下面从移植步骤、参数调优、扩展思路三个方面讲。5.1 移植到不同 STM32 型号从 STM32F103 换到 STM32F407 或者 GD32核心的 IIC 时序和 VL53L0X 寄存器操作不用变需要改的是三个地方第一GPIO 初始化。把GPIO_InitStructure.GPIO_Pin和GPIO_Mode改成目标平台的写法。如果是 HAL 库把标准库的GPIO_SetBits换成HAL_GPIO_WritePin。第二延时函数。delay_us()的实现依赖系统主频F103 是 72MHzF407 是 168MHz需要重新校准。我一般用 SysTick 或者定时器来做微秒延时比空循环靠谱。第三时钟配置。如果目标平台的 IIC 外设时钟源不同硬件 IIC 的初始化代码要跟着改。模拟 IIC 则不受影响。移植完成后先跑VL53L0X_CheckID()返回 0 就说明底层通了。5.2 测量参数调优VL53L0X 的测量精度和速度是一对矛盾。通过调整VL53L0X_REG_MEASUREMENT_TIMING_BUDGET寄存器可以在两者之间找平衡测量时间对应值精度适用场景20ms0x00 0x28一般高速检测33ms0x00 0x64较好通用场景100ms0x00 0xC8高精密测量200ms0x01 0x90最高静态标定我一般会先在 33ms 下测试如果精度不够再往上加。注意测量时间越长功耗越高电池供电的场景要权衡。5.3 扩展思路从单点到多点测距单个 VL53L0X 只能测一个方向的距离。如果需要多点测距有两个方案一是用多个传感器通过 XSHUT 分时复用二是加一个舵机让传感器旋转扫描。多个传感器的方案更可靠但成本高、布线复杂。舵机扫描的方案成本低但实时性差适合静态场景。如果要做避障小车建议用多个传感器前、左、右各一个通过 IIC 多路复用器如 TCA9548A扩展总线。5.4 一个实用的调试技巧最后分享一个调试习惯在VL53L0X_ReadDistance()里加一个超时计数器如果等待超过 500ms 还没完成就强制退出并返回错误码。这样即使传感器出问题主程序也不会卡死。我早期调试时没加这个结果传感器一掉线整个程序就挂在那里查了半天才发现是死等。// 带超时的距离读取 u16 VL53L0X_ReadDistance_Timeout(u16 timeout_ms) { u16 distance; u16 cnt 0; VL53L0X_WriteByte(0x00, 0x01); while (VL53L0X_ReadByte(0x00) 0x01) { delay_ms(1); cnt; if (cnt timeout_ms) { return 0xFFFF; // 超时返回错误码 } } distance VL53L0X_ReadByte(0x1E); distance (distance 8) | VL53L0X_ReadByte(0x1F); return distance; }从那以后我每次写传感器驱动都会在轮询等待的地方加上超时保护这个习惯帮我省了很多调试时间。希望这份驱动拆解能帮你把 VL53L0X 顺利跑起来少走点弯路。本文还有配套的精品资源点击获取

相关新闻

Linux系统安全加固实战指南:五大核心策略防入侵

Linux系统安全加固实战指南:五大核心策略防入侵

说句实在话,干了这么多年Linux运维,见过太多“业务跑得飞起、安全一塌糊涂”的服务器了。很多开发者觉得系统安全加固是安全团队的事,或者觉得只要不装乱七八糟的东西就不会出事。但实际情况是,等你在生产环境看到服务器被植入挖矿程序、SSH被暴力破解登…

2026/10/19 13:26:13 阅读更多 →
EEG脑波音乐版权归属迷局:从信号采集到AI生成的技术审视

EEG脑波音乐版权归属迷局:从信号采集到AI生成的技术审视

脑波版权战争:EEG数据生成音乐的侵权迷局与软件测试从业者的专业审视上个月我接手了一个有点特殊的项目:一套把用户脑电波转成音乐的系统。需求文档写得花团锦簇,"用意识作曲""脑机接口创作"之类的口号喊得很响&#xff…

2026/10/19 13:25:11 阅读更多 →
AI+知识库:让标书创作从“人找资料”到“资料找人”

AI+知识库:让标书创作从“人找资料”到“资料找人”

标书这东西,圈内人都懂,看着是文档活,实际上是体力活、耐力活、甚至运气活。很多集团型企业的标书团队,表面上几百号人,业务覆盖全国,私下里干的都是同一件事:从旧标书里翻素材,找兄…

2026/10/19 13:25:11 阅读更多 →

最新新闻

AI证件照生成器:人像分割与尺寸校准的工程实现

AI证件照生成器:人像分割与尺寸校准的工程实现

1. 先拆解证件照的真实需求做AI证件照生成器之前,我先把用户真正会面临的问题摆到了台面上:大部分人手上并没有一张“现成的、合规的证件照”,要么是以前拍的已经过期,要么是背景颜色不对、衣服颜色不对、头部占比不对&#xff0c…

2026/10/19 14:06:28 阅读更多 →
开源代码审查基础设施:CLI+Git+LLM协同范式

开源代码审查基础设施:CLI+Git+LLM协同范式

1. 这不是又一个“AI代码审查工具”,而是一套可审计、可验证、可嵌入CI的开源协作范式你有没有遇到过这样的场景:团队里新来一位应届生,提交了PR,你点开diff页面,扫了一眼——变量命名有点随意,但逻辑似乎没…

2026/10/19 14:06:28 阅读更多 →
智能金融研究助手实战:让数据清洗与文档解析自动化

智能金融研究助手实战:让数据清洗与文档解析自动化

1. 为什么金融研究需要一位“数字助理”先说个我自己的体会。做金融研究这行当,不管是机构里的研究员,还是独立做投资分析的散户,日常工作里最耗时间的往往不是“思考”,而是“找东西”和“对数据”——翻研报、查公告、拉历史行情…

2026/10/19 14:06:28 阅读更多 →
open-code-review:面向开发者的开源CLI代码审查工具

open-code-review:面向开发者的开源CLI代码审查工具

1. 项目概述:这不是又一个“AI写代码”玩具,而是一套可嵌入日常开发流的轻量级代码审查协作者“open-code-review”这个名字乍一听像某个开源项目仓库名,但拆开来看——open,不是指“开源”,而是“开放接入、开放协议、…

2026/10/19 14:06:28 阅读更多 →
open-code-review:基于CLI+Git+LLM的开源代码审查范式

open-code-review:基于CLI+Git+LLM的开源代码审查范式

1. “open-code-review”不是工具名,而是一种可落地的代码审查新范式你有没有遇到过这样的场景:团队里刚入职的新人提交了一段看似没问题的Python函数,逻辑通顺、变量命名规范、单元测试也跑过了——但上线三天后,服务在凌晨两点开…

2026/10/19 14:06:28 阅读更多 →
Romax C1模块入门:15分钟跑通齿轮箱静态分析

Romax C1模块入门:15分钟跑通齿轮箱静态分析

简介:本资源是Romax传动系统仿真软件的官方入门级培训资料,专为齿轮箱设计初学者与进阶工程师打造,聚焦C1模块——软件基础建模、界面导航与分析流程。内容覆盖Romax软件定位、版权规范、五大核心界面(工作表/对话框/设计窗口/许可…

2026/10/19 14:05:22 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →