news 2026/9/4 14:50:24

基于C语言与VL53L1x的嵌入式激光测距系统毕业设计实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于C语言与VL53L1x的嵌入式激光测距系统毕业设计实战指南

简介:本资源是一套基于C语言实现的VL53L1x激光测距传感器驱动与应用开发完整方案,面向本科毕业设计、电子类课程设计及嵌入式项目开发者,解决ToF激光测距模块在STM32等MCU平台上的初始化、数据读取、校准与多模式配置等核心工程问题。压缩包共96个文件(1.98MB),涵盖34个头文件(.h)定义寄存器映射与API接口、32个C源文件(.c)实现I²C通信、中断处理、距离计算及多设备管理逻辑,辅以Python脚本用于数据可视化与固件调试、Arduino示例(.ino)便于快速验证,以及PDF硬件手册、Markdown使用指南和Keil工程配置文件(.uvprojx/.uvoptx)等配套文档。已有117人学习下载,内容经过实机严格测试,结构清晰、注释完整,支持直接编译运行,并预留扩展接口,便于读者快速集成至智能小车避障、工业定位或IoT测距系统中。

1. 项目缘起:为什么选择VL53L1x与C语言作为毕业设计的黄金搭档?

又到了一年一度的毕业设计季,看着学弟学妹们为选题焦头烂额,我想起了自己当年用C语言折腾VL53L1x激光测距传感器的日子。这个组合,在我看来,是电子、通信、自动化乃至物联网相关专业学生做课程设计或毕业设计的一个“宝藏选项”。它不像纯软件项目那样容易显得空洞,也不像复杂的图像处理或AI项目那样门槛高、周期长、难以落地。VL53L1x传感器本身足够“硬核”,能让你接触到真实的硬件、总线通信和物理世界的数据;而C语言,则是嵌入式领域的“世界语”,掌握了它,你就拿到了通往单片机、ARM、Linux驱动等更广阔世界的第一把钥匙。

很多人一听到“激光测距”、“ToF(飞行时间法)”,就觉得高深莫测,下意识想用Arduino的现成库或者Python来快速实现。这当然可以,但作为毕业设计,深度和“技术含量”是评委老师考量的重点。用C语言从零开始驱动VL53L1x,意味着你需要亲手去解析数据手册(Datasheet),理解I2C总线协议,编写底层的读写函数,处理传感器返回的原始数据,并最终将其转化为可靠的距离值。这个过程,恰恰完整地覆盖了嵌入式系统开发的核心流程:硬件接口、通信协议、驱动编写、数据处理。你的论文和答辩也因此有了扎实的“血肉”,而不是仅仅展示一个调用库函数的结果。

VL53L1x是意法半导体(ST)推出的一款高性能、多功能的ToF测距传感器。相比前代VL53L0x,它的测距范围更远(可达4米),抗环境光干扰能力更强,还增加了区域扫描等高级功能。市面上很多教程和开源库都基于VL53L0x或Arduino平台,专门针对VL53L1x的、纯C语言的、从寄存器级别讲解的完整资料并不多见。这正是本项目的价值所在:我将带你绕过我当年踩过的坑,用最“原始”也最有效的方式,在STM32这样的主流MCU上,亲手让VL53L1x跑起来,并附上全部源码和详尽的文档说明,让你的毕业设计既有深度,又能顺利完成。

2. 核心硬件与原理:VL53L1x如何“看见”距离?

在动手写代码之前,我们必须先搞清楚手里的“武器”是如何工作的。VL53L1x的核心原理是飞行时间法(Time-of-Flight, ToF)。你可以把它想象成一个超级迷你版的激光雷达:它内部有一个微型的激光二极管,发射出一束人眼不可见的红外激光脉冲(波长940nm)。这束光碰到目标物体后会发生反射,其中一部分光会返回到传感器上的SPAD(单光子雪崩二极管)探测器阵列。

传感器内部的核心是一个高精度的时间数字转换器(TDC)。它的工作就是测量激光脉冲从发射到被接收之间的时间差 Δt。光在空气中的速度 c 是已知的(约 3×10^8 m/s),那么到目标的距离 d 就可以通过一个简单的公式计算出来:d = (c × Δt) / 2。除以2是因为光走了一个来回。

VL53L1x的“L1”升级,带来了几个关键提升:

  1. 更大的光学视野和SPAD阵列:这使得它能够进行简单的区域扫描,而不仅仅是单点测距。你可以通过配置,让传感器报告前方不同区域的距离,实现初步的物体轮廓感知。
  2. 更智能的固件:传感器内部集成了一个微型处理器(MCU)和固件,负责处理复杂的时序计算、环境光补偿和串扰校准。我们通过I2C发送命令,固件执行测量,然后将处理好的结果数据返回给我们,大大减轻了主控MCU的负担。
  3. 多模式支持:它支持高速度、高精度、长距离等多种测量模式,适应不同场景。

与MCU的连接极其简单,主要通过标准的I2C接口。通常需要连接四根线:

  • VIN:电源(2.6V - 3.5V)。注意,虽然很多开发板是3.3V,但一定要确认你的板子电压在此范围内且稳定。
  • GND:地。
  • SCL:I2C时钟线。
  • SDA:I2C数据线。
  • GPIO1(可选):中断引脚,可用于通知MCU测量完成,实现非阻塞式读取。
  • XSHUT(可选):复位/关断引脚,可用于硬件复位或低功耗控制。

注意:VL53L1x对电源噪声比较敏感。如果你的测量结果跳动很大,第一个要怀疑的就是电源。建议在VIN引脚附近放置一个1μF和100nF的电容进行滤波。这是很多教程里不会提,但实际调试中至关重要的一步。

3. 开发环境搭建与工程框架设计

我们选择STM32F103C8T6(即常见的“蓝桥杯”核心板或最小系统板)作为主控平台,使用Keil MDK作为开发环境。选择它们的原因是普及率高、资料多、成本低,完全符合毕业设计的“经济实用”原则。

3.1 工程创建与基础驱动准备

首先,在Keil中创建一个标准的STM32工程。我们需要准备以下基础驱动文件:

  1. stm32f10x.h等标准外设库头文件。
  2. system_stm32f10x.c等系统初始化文件。
  3. 最关键的是I2C的驱动代码。你可以使用STM32标准外设库(SPL)或HAL库来编写。为了更贴近底层理解,我建议从SPL开始。

一个健壮的I2C驱动应包含以下函数:

void I2C_Configuration(void); // 初始化I2C,设置速度(VL53L1x支持标准模式100kHz和快速模式400kHz) uint8_t I2C_WriteByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); // 向指定设备地址、寄存器地址写入一个字节 uint8_t I2C_ReadByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data); // 从指定设备地址、寄存器地址读取一个字节 uint8_t I2C_WriteMulti(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t count); // 连续写入多个字节 uint8_t I2C_ReadMulti(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t count); // 连续读取多个字节

devAddr是VL53L1x的I2C设备地址,默认为0x52(7位地址)。注意,I2C库的读写函数必须包含错误处理和重试机制,因为I2C通信容易受到干扰。我的经验是,在读写失败后,加入一个短暂的延时,然后发送一个I2C停止信号再重试,最多重试3次,这样可以解决90%以上的偶然通信失败问题。

3.2 文件结构规划

一个清晰的工程结构能让你的代码更易读、易维护,也是答辩时的加分项。建议按如下方式组织:

/Project ├── /CMSIS // ARM内核支持文件 ├── /StdPeriph_Driver // STM32标准外设库 ├── /User │ ├── main.c // 主函数 │ ├── vl53l1x_api.c // VL53L1x核心驱动层(我们编写的重点) │ ├── vl53l1x_api.h │ ├── vl53l1x_platform.c // 平台抽象层(实现I2C读写、延时函数) │ ├── vl53l1x_platform.h │ ├── i2c.c // 具体的I2C硬件驱动 │ └── i2c.h └── /Doc // 存放数据手册、你自己的设计文档等

这种分层架构的优势在于可移植性vl53l1x_platform.c文件里只包含i2c_writei2c_readdelay_ms这样的抽象函数。当你想把代码从STM32移植到ESP32或者别的单片机时,只需要重写这个平台层文件,上层的核心API代码 (vl53l1x_api.c) 完全不需要改动。

4. VL53L1x驱动层代码的逐行解析与实现

这是整个项目的核心。我们不会使用ST官方的ULD(Ultra Lite Driver)库,因为它封装程度较高,不利于理解底层细节。我们将根据数据手册,从寄存器操作开始,一步步构建自己的驱动。

4.1 传感器初始化序列

上电后,VL53L1x需要一系列正确的初始化命令才能进入工作状态。这个过程比简单的“复位-等待-开始”要复杂一些。

首先,在vl53l1x_api.c中,我们定义一些必要的常量和寄存器地址(根据数据手册):

#define VL53L1X_DEFAULT_I2C_ADDR 0x52 #define VL53L1X_SOFT_RESET 0x0000 #define VL53L1X_FIRMWARE_SYSTEM_STATUS 0x0089 // ... 更多寄存器地址定义 uint8_t VL53L1X_Init(uint8_t devAddr) { uint8_t status = 0; uint16_t firmware_status = 0; uint16_t sensor_id = 0; // 步骤1:软件复位 status |= VL53L1X_WriteWord(devAddr, VL53L1X_SOFT_RESET, 0x00); delay_ms(100); // 复位后必须等待至少1ms,这里给100ms确保稳定 // 步骤2:等待传感器固件就绪 int timeout = 100; while (timeout-- > 0) { VL53L1X_ReadWord(devAddr, VL53L1X_FIRMWARE_SYSTEM_STATUS, &firmware_status); if ((firmware_status & 0x01) == 0x01) { // 检查低位是否为1 break; } delay_ms(10); } if (timeout <= 0) { return 1; // 初始化超时错误 } // 步骤3:验证传感器ID(确保连接的是VL53L1x而不是其他设备) VL53L1X_ReadWord(devAddr, 0x010F, &sensor_id); if (sensor_id != 0xEACC) { // VL53L1x的固定ID return 2; // 传感器ID不匹配错误 } // 步骤4:加载固件预设配置(关键!) // VL53L1x需要主控MCU将一段固件配置数据(约2KB)写入其内存。 // 这段数据在数据手册的附录中可以找到,是一个超长的常量数组。 status |= VL53L1X_LoadTuningSettings(devAddr, vl53l1x_tuning_settings); delay_ms(10); // 步骤5:启动测距固件 status |= VL53L1X_WriteByte(devAddr, 0x0007, 0x01); delay_ms(10); // 步骤6:设置测量模式(例如,设置为默认的单次测距模式) status |= VL53L1X_SetMeasurementMode(devAddr, MODE_SINGLE_RANGING); return status; // 返回0表示成功 }

实操心得VL53L1X_LoadTuningSettings这一步是最容易出错的地方。官方数据手册里的配置表有上百行,手动输入极易出错。我的做法是:先从ST官网找到官方的ULD库,从中提取出那个VL53L1X_TuningSettings数组,直接复制到自己的代码里。这是“站在巨人的肩膀上”,避免因一个字节的错误导致传感器行为异常。此外,每一步操作后的delay_ms并非随意设置,数据手册对许多命令都有明确的最小时间间隔要求,必须遵守。

4.2 单次测距流程与数据解析

初始化成功后,我们就可以开始测量了。一次完整的单次测距流程如下:

uint8_t VL53L1X_StartSingleRanging(uint8_t devAddr) { // 清除中断状态 VL53L1X_ClearInterrupt(devAddr); // 发送开始测量命令 return VL53L1X_WriteByte(devAddr, VL53L1X_SYSTEM_START, 0x40); } uint8_t VL53L1X_GetMeasurementData(uint8_t devAddr, VL53L1X_Result_t *pResult) { uint8_t status = 0; uint8_t data_buffer[17]; // 结果数据共有17个字节 // 等待测量完成(可以通过轮询状态寄存器,或使用中断) uint8_t is_data_ready = 0; int timeout = 500; // 根据测量模式设置超时,长距离模式需要更久 while (timeout-- > 0 && !is_data_ready) { VL53L1X_ReadByte(devAddr, VL53L1X_GPIO_TIO_HV_STATUS, &is_data_ready); is_data_ready &= 0x01; delay_ms(1); } if (!is_data_ready) { return 1; // 测量超时 } // 读取全部17个字节的结果数据 status |= VL53L1X_ReadMulti(devAddr, VL53L1X_RESULT_BASE, data_buffer, 17); // 解析数据:这是核心! pResult->status = data_buffer[0]; // 测量状态,0表示有效 pResult->distance_mm = (data_buffer[13] << 8) | data_buffer[12]; // 距离值,单位毫米 pResult->signal_rate = (data_buffer[7] << 8) | data_buffer[6]; // 信号速率(反映信号强度) pResult->ambient_rate = (data_buffer[9] << 8) | data_buffer[8]; // 环境光速率 pResult->sigma = (data_buffer[11] << 8) | data_buffer[10]; // 测量值的标准差(反映精度) // 清除中断,为下一次测量做准备 VL53L1X_ClearInterrupt(devAddr); return status; }

数据解析部分需要格外小心。VL53L1x的结果数据是小端格式(Little-Endian),即低字节在前,高字节在后。所以距离值data_buffer[13]是高字节,data_buffer[12]是低字节,组合方式是(高字节 << 8) | 低字节

pResult->status字段非常重要,它告诉你这次测量是否可靠。常见的状态值有:

  • 0:测距有效。
  • 1:信号失败(目标反射信号太弱)。
  • 2:信号太强,饱和了(目标太近或反射率太高)。
  • 4:环境光太强,干扰了测量。
  • 5:相位溢出(通常发生在超出最大量程时)。

在你的应用程序中,必须检查这个状态位,只有当状态为0时,distance_mm才是可信的。直接使用无效状态下的距离值,是导致测距结果“乱跳”的主要原因之一。

4.3 高级功能配置:以区域扫描为例

VL53L1x支持4x4或8x8的区域扫描(ROI,Region of Interest),这能让你获取一个小区域内的简单深度信息。配置ROI主要涉及设置中心点和尺寸。

uint8_t VL53L1X_SetROI(uint8_t devAddr, uint8_t center_x, uint8_t center_y, uint8_t width, uint8_t height) { uint8_t status = 0; // 首先需要停止当前的测量 status |= VL53L1X_StopMeasurement(devAddr); // 设置ROI中心(寄存器地址参考数据手册) status |= VL53L1X_WriteByte(devAddr, 0x0B, center_x); status |= VL53L1X_WriteByte(devAddr, 0x0C, center_y); // 设置ROI宽度和高度(需要转换成特定的格式) uint8_t roi_config = ((height-1) << 4) | (width-1); status |= VL53L1X_WriteByte(devAddr, 0x0D, roi_config); // 重新启动测量 status |= VL53L1X_StartMeasurement(devAddr); return status; }

配置后,当你读取数据时,需要从不同的结果区域读取对应子区域的距离值。这部分的寄存器地址是连续的,可以通过一个循环批量读取。在毕业设计中,实现一个简单的4x4区域扫描,并可视化显示(比如通过串口打印成矩阵,或者用LED矩阵表示远近),能极大提升项目的展示效果和复杂程度。

5. 系统集成、调试与数据滤波实战

驱动写好了,但要让它在实际系统中稳定工作,还需要完成“最后一公里”的集成和调试。

5.1 主程序逻辑与外围电路

main.c中,我们需要构建一个清晰的应用逻辑:

int main(void) { VL53L1X_Result_t result; uint8_t sensor_status; char uart_buf[64]; // 系统时钟、GPIO、I2C、UART初始化 SystemInit(); I2C_Configuration(); UART_Configuration(); // 初始化VL53L1x sensor_status = VL53L1X_Init(VL53L1X_DEFAULT_I2C_ADDR); if (sensor_status != 0) { sprintf(uart_buf, "Sensor Init Failed! Error: %d\r\n", sensor_status); UART_SendString(uart_buf); while(1); // 初始化失败,停机 } UART_SendString("VL53L1X Init OK!\r\n"); while(1) { // 启动一次单次测量 VL53L1X_StartSingleRanging(VL53L1X_DEFAULT_I2C_ADDR); // 获取结果 sensor_status = VL53L1X_GetMeasurementData(VL53L1X_DEFAULT_I2C_ADDR, &result); if (sensor_status == 0 && result.status == 0) { // 测量成功且数据有效 sprintf(uart_buf, "Distance: %d mm, Signal: %d, Ambient: %d\r\n", result.distance_mm, result.signal_rate, result.ambient_rate); UART_SendString(uart_buf); } else { // 处理错误 sprintf(uart_buf, "Error! Sensor Status: %d, Data Status: %d\r\n", sensor_status, result.status); UART_SendString(uart_buf); } delay_ms(100); // 控制测量频率 } }

外围电路提醒

  • 上拉电阻:I2C总线的SDA和SCL线上必须接上拉电阻(通常4.7kΩ),这是硬件常识,但很多学生在自己焊接电路时会忘记。
  • 传感器放置:VL53L1x的发射和接收镜头非常小,要确保前方没有遮挡,并且目标物体表面最好是漫反射面。对于玻璃、镜面或纯黑色物体,测量会不准甚至失败,这是物理限制,需要在论文中说明。

5.2 软件滤波:让数据更平滑

原始的距离数据难免会有跳动,尤其是在测量边缘或远距离物体时。在嵌入式系统中,一个简单有效的软件滤波算法能极大提升用户体验。

移动平均滤波是最容易实现且效果不错的方法:

#define FILTER_WINDOW_SIZE 5 int16_t MovingAverageFilter(int16_t new_value) { static int16_t value_buffer[FILTER_WINDOW_SIZE] = {0}; static uint8_t index = 0; static int32_t sum = 0; // 减去最旧的值,加上最新的值 sum = sum - value_buffer[index] + new_value; value_buffer[index] = new_value; index = (index + 1) % FILTER_WINDOW_SIZE; // 返回平均值 return (int16_t)(sum / FILTER_WINDOW_SIZE); }

在主循环中,将读取到的result.distance_mm传入这个滤波函数,得到的就是平滑后的距离值。你可以调整FILTER_WINDOW_SIZE的大小,窗口越大越平滑,但响应也会变慢。对于快速移动的物体,窗口不宜过大。

更高级的滤波:可以结合result.sigma(标准差)和result.status。当sigma值过大或状态非0时,直接丢弃本次数据,不更新滤波窗口,等待下一次有效测量。这能有效过滤掉明显的错误数据。

5.3 常见问题排查指南(踩坑实录)

  1. I2C通信失败,初始化不成功

    • 检查硬件连接:用万用表确认VCC、GND、SDA、SCL四根线是否连通,电压是否正常(3.3V)。
    • 检查上拉电阻:SDA和SCL是否都有上拉到3.3V的电阻(4.7kΩ-10kΩ)。
    • 用逻辑分析仪抓取波形:这是最直接的调试手段。看起始信号、设备地址、应答位是否正常。有时SCL频率设置过快(比如超过400kHz)也会导致通信不稳定。
  2. 可以初始化,但测距结果全是0或固定值

    • 检查固件配置加载:99%的问题出在VL53L1X_LoadTuningSettings这一步。确认你写入的配置数组完全正确,没有遗漏或错位。一个字节的错误就可能导致传感器内部状态机混乱。
    • 检查测量启动命令:确认在初始化后,正确发送了启动测距固件的命令(写入0x0007寄存器为0x01)。
  3. 测量数据跳动(噪声)大

    • 电源问题:这是首要怀疑对象。在VCC和GND之间,尽可能靠近传感器引脚的地方,并联一个10μF的电解电容和一个100nF的陶瓷电容。
    • 环境光干扰:虽然VL53L1x抗环境光能力很强,但避免在正午阳光下直射传感器。可以尝试读取ambient_rate,如果这个值非常高,说明环境光太强。
    • 目标物特性:尝试测量不同材质、颜色的物体。对于吸光材料(如黑绒布),信号会很弱,结果自然不稳。
    • 软件滤波:如上所述,必须加入软件滤波算法。
  4. 测量距离明显不准

    • 校准:VL53L1x出厂已校准,但在高精度场合,可以进行“偏移校准”。你需要一个已知精确距离的参考目标(如15cm),按照数据手册的步骤进行校准,并将得到的偏移量写入寄存器。
    • 模式选择:确认你使用的测量模式是否适合当前距离。短距离(<1.3米)用高精度模式,长距离用长距离模式。

6. 从驱动到应用:毕业设计创意拓展

有了稳定的驱动和测距数据,你可以将其融入一个完整的系统中,这能让你的毕业设计脱颖而出。

创意一:智能避障小车

  • 核心:将VL53L1x安装在舵机上,实现180度扫描。主控(STM32)根据扫描到的距离信息,构建简单的局部地图,实现动态避障和路径规划。
  • 亮点:结合了传感器、电机控制、简单算法。你可以对比不同扫描密度(角度分辨率)下避障效果的差异。

创意二:手势识别交互装置

  • 核心:利用VL53L1x的区域扫描(4x4)功能,将前方空间划分为16个格子。通过检测不同格子距离值的变化序列(如手从左向右挥过),来定义简单的手势(左滑、右滑、靠近、远离)。
  • 亮点:实现了非接触式交互。可以控制LED灯带、播放器或智能家居设备,论文中可以探讨识别算法的鲁棒性。

创意三:高精度液位/料位监测系统

  • 核心:将传感器固定安装在容器顶部,垂直向下测量到液体或物料表面的距离,从而换算出液位高度。利用其高精度和抗干扰特性,实现非接触式连续测量。
  • 亮点:贴近工业应用。你需要重点解决容器内蒸汽、泡沫对激光的干扰问题,并在论文中详细分析测量误差来源及补偿方法。

创意四:人员计数与存在检测

  • 核心:在门口或房间角落安装传感器,通过监测特定区域距离值的突变(有人经过或进入)来实现计数或存在检测。相比红外热释电传感器,ToF方案方向性更好,误报率更低。
  • 亮点:低成本物联网应用。可以结合Wi-Fi或NB-IoT模块,将数据上传到云平台,实现远程监控。

在实现这些应用时,你的文档教程就变得至关重要。它不应该只是代码的注释,而应该包括:

  1. 系统总体设计框图(软硬件架构)。
  2. 详细的接线图(标注引脚和元器件参数)。
  3. 传感器寄存器配置表(说明你配置了哪些关键寄存器及其含义)。
  4. 主程序流程图
  5. 关键算法的伪代码或流程图(如滤波算法、手势识别状态机)。
  6. 系统测试方法与数据(在不同光照、距离、目标物下的测试数据表格和曲线图)。
  7. 遇到的问题与解决方案总结

这份完整的、图文并茂的文档,配合结构清晰、注释良好的源码,就是一份高质量的毕业设计材料。它能向答辩老师清晰地展示你的工作量、技术掌握程度和解决问题的能力,而这正是获得高分的关键。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 14:49:10

海康VisionMaster 4.3二次开发实战:从SDK集成到工业级应用部署

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

作者头像 李华
网站建设 2026/9/4 14:46:39

MTK1389 DVD播放器源码解析:嵌入式音视频系统架构与RTOS实战

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

作者头像 李华
网站建设 2026/9/4 14:44:50

单片机毕设项目:基于 STM32 或 51 单片机的水产养殖水质多参数智能调控装置 多传感器水质数据采集、阈值预警与自动换水一体化系统设计(021506)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机&#xff0c;Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/4 14:44:23

AI工作流时代,机密电路设计如何守住安全边界?

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

作者头像 李华
网站建设 2026/9/4 14:41:50

450 款终端配色主题 5 分钟一键导入

450 款终端配色主题 5 分钟一键导入 【免费下载链接】iTerm2-Color-Schemes Over 450 terminal color schemes/themes for iTerm/iTerm2. Includes ports to Terminal, Konsole, PuTTY, Xresources, XRDB, Remmina, Termite, XFCE, Tilda, FreeBSD VT, Terminator, Kitty, Moba…

作者头像 李华
网站建设 2026/9/4 14:40:06

INGcontrol v0.2.37 一套键盘鼠标 自然跨越多台电脑

链接&#xff1a;https://pan.quark.cn/s/d0ec9e7a9947请让所有电脑都安装相同最新版&#xff0c;并登录同一个微信账号&#xff1b;同一局域网时会优先使用低延迟直连。从官网下载 Windows x64 安装版&#xff0c;双击 INGcontrol-Windows-0.2.37.exe。 如果 SmartScreen 出现…

作者头像 李华