LIS2DW12三轴加速度计驱动开发与实战:从寄存器配置到中断FIFO应用

简介:这份资源面向嵌入式与物联网方向的开发者,聚焦意法半导体LIS2DW12三轴加速度计的驱动开发与典型应用示例,帮助读者掌握通过I²C或SPI与传感器通信、配置寄存器、解析加速度数据以及处理中断与低功耗唤醒等关键环节。压缩包共10个文件,全部为C语言源码,整体约30KB,涵盖驱动实现与多种应用场景示例,如单次读取、FIFO读取、轮询采集、自由落体检测、单击与双击识别、活动检测、唤醒及自检等,便于对照理解驱动架构与数据流。目前已有1515人学习下载,适合希望快速上手传感器驱动、在健康监测或运动设备项目中集成LIS2DW12的开发者参考,也可作为调试与功能验证的实践素材。

1. 从一块加速度计说起:lis2dw12 驱动到底能帮你省掉多少事

如果你手头正捏着一块 LIS2DW12 三轴加速度计,大概率是这几种情况之一:做低功耗可穿戴设备,需要它在运动唤醒和自由落体检测之间来回切换;做工业振动监测,想拿它当状态感知的前端;或者纯粹是买了个开发板,想先跑通再谈产品化。不管哪种,真正卡住你的往往不是传感器本身,而是驱动——寄存器手册几百页,数据手册里 CTRL1 到 CTRL6 翻来覆去,FIFO 和中断映射绕得人头晕。这份 lis2dw12 驱动及例子资源,就是冲着这个痛点来的:它把底层寄存器操作、数据读取、中断配置和几个典型应用场景的调用示例打包在一起,让你不用从零啃手册就能把传感器跑起来。适合嵌入式新手照着移植,也适合熟手直接拿来做二次开发的起点。

2. 驱动架构拆解:从寄存器到应用层的三层结构

2.1 为什么这类传感器驱动要分层

LIS2DW12 是 ST 家的低功耗三轴加速度计,支持 I2C 和 SPI 两种接口,内置 FIFO、自由落体检测、运动唤醒、单击双击识别等功能。如果驱动只写成一坨直接操作寄存器的函数,换平台时就得重写,加新功能时也容易把底层和业务逻辑搅在一起。这份资源里的驱动采用了典型的三层结构:底层通信抽象层负责 I2C/SPI 读写,中间寄存器操作层封装了初始化、量程设置、输出数据速率配置、中断使能等,上层应用接口层则提供“读三轴加速度”“配置运动唤醒阈值”“读取 FIFO 数据”这类语义化函数。这样分层的好处是,换 MCU 平台时只需要改底层通信的几个函数,中间层和上层几乎不用动。

2.2 目录结构与文件职责

资源包里的文件组织大致是这样的:

lis2dw12_driver/ ├── lis2dw12_reg.h # 寄存器地址、位域定义 ├── lis2dw12_reg.c # 寄存器读写封装 ├── lis2dw12_driver.h # 驱动对外接口声明 ├── lis2dw12_driver.c # 驱动核心实现 ├── lis2dw12_platform.h # 平台相关接口声明 ├── lis2dw12_platform.c # 平台相关接口实现(I2C/SPI 读写、延时) └── examples/ ├── read_accel.c # 三轴加速度读取示例 ├── wakeup_detection.c # 运动唤醒中断示例 └── fifo_stream.c # FIFO 连续采集示例

lis2dw12_reg.h里用宏定义把每个寄存器的地址和位域都列了出来,比如LIS2DW12_CTRL1、LIS2DW12_CTRL1_ODR_MASK这种。lis2dw12_platform.c是唯一需要根据你实际硬件改的文件,里面通常有lis2dw12_write_reg、lis2dw12_read_reg、lis2dw12_delay_ms这几个函数。驱动核心文件不直接调 HAL 库,而是通过 platform 层间接访问硬件,这就是移植的关键。

2.3 初始化流程与关键寄存器配置

初始化是驱动跑通的第一步,也是最容易翻车的地方。LIS2DW12 上电后默认处于掉电模式,必须先把 CTRL1 的 ODR 位设成非零值才能唤醒。下面是一个典型的初始化代码片段:

/* 初始化 LIS2DW12,配置为 100Hz 输出速率,±2g 量程 */ int lis2dw12_init(void) { uint8_t reg_val; /* 第一步:软复位,确保寄存器回到已知状态 */ lis2dw12_write_reg(LIS2DW12_CTRL2, LIS2DW12_CTRL2_SOFT_RESET); lis2dw12_delay_ms(10); /* 等待复位完成,手册要求至少 5ms */ /* 第二步:配置 CTRL1,设置输出数据速率和功耗模式 */ reg_val = LIS2DW12_CTRL1_ODR_100HZ | LIS2DW12_CTRL1_MODE_LOW_POWER; lis2dw12_write_reg(LIS2DW12_CTRL1, reg_val); /* 第三步:配置 CTRL6,设置量程为 ±2g */ reg_val = LIS2DW12_CTRL6_FS_2G; lis2dw12_write_reg(LIS2DW12_CTRL6, reg_val); /* 第四步:使能 BDU,保证读取数据时高低字节一致 */ lis2dw12_write_reg(LIS2DW12_CTRL2, LIS2DW12_CTRL2_BDU); /* 第五步:等待第一个数据就绪 */ lis2dw12_delay_ms(20); return 0; }

这段代码里几个关键点:软复位后必须延时,否则后续寄存器写入可能不生效;CTRL1 的 ODR 位同时决定了功耗模式,低功耗模式下噪声会大一些,但电流只有几微安;CTRL6 的 FS 位设置量程,±2g 对应灵敏度 0.061 mg/LSB,±4g 则是 0.122 mg/LSB,换算时别搞错。BDU 位建议打开,否则在读取 OUT_X_L 和 OUT_X_H 之间如果数据更新了,拼出来的值就是错的。

2.4 三轴数据读取与单位换算

读加速度数据本身不复杂,但要注意寄存器是左右对齐还是右对齐,以及高低字节的拼接顺序。LIS2DW12 默认是右对齐,12 位有效数据放在 16 位寄存器的高 12 位还是低 12 位,取决于 CTRL1 里的 BLE 位设置。下面是一个读取并换算成 mg 的示例:

/* 读取三轴加速度,结果存入 accel_mg[3],单位毫克 */ void lis2dw12_read_accel(float *accel_mg) { uint8_t raw_data[6]; int16_t raw_x, raw_y, raw_z; float sensitivity = 0.061f; /* ±2g 量程下的灵敏度,单位 mg/LSB */ /* 连续读取 6 个字节:X_L, X_H, Y_L, Y_H, Z_L, Z_H */ lis2dw12_read_regs(LIS2DW12_OUT_X_L, raw_data, 6); /* 拼接高低字节,注意 LIS2DW12 是右对齐,直接组合即可 */ raw_x = (int16_t)((raw_data[1] << 8) | raw_data[0]); raw_y = (int16_t)((raw_data[3] << 8) | raw_data[2]); raw_z = (int16_t)((raw_data[5] << 8) | raw_data[4]); /* 右移 4 位,因为 12 位数据在 16 位寄存器里是左对齐的 */ raw_x = raw_x >> 4; raw_y = raw_y >> 4; raw_z = raw_z >> 4; /* 换算成毫克 */ accel_mg[0] = raw_x * sensitivity; accel_mg[1] = raw_y * sensitivity; accel_mg[2] = raw_z * sensitivity; }

这里有个容易踩的坑:如果你在 CTRL1 里把 BLE 位设成了 1,数据就是左对齐,右移 4 位是对的;如果 BLE 为 0,数据是右对齐,就不需要移位。很多人在这一步读出来的值始终偏小 16 倍,就是移位搞反了。另外灵敏度系数跟量程绑定,±2g 是 0.061,±4g 是 0.122,±8g 是 0.244,±16g 是 0.488,单位都是 mg/LSB。

3. 中断与 FIFO 实战:运动唤醒和连续采集怎么配

3.1 运动唤醒中断的完整配置链路

运动唤醒是 LIS2DW12 的招牌功能之一,配置起来涉及 CTRL1、CTRL4_INT1_PAD_CTRL、WAKE_UP_THS、WAKE_UP_DUR 好几个寄存器,链路比较长。下面是一个可用的配置流程:

/* 配置运动唤醒中断,阈值 32LSB,输出到 INT1 引脚 */ void lis2dw12_config_wakeup(void) { uint8_t reg_val; /* 使能中断信号锁存,避免脉冲太短 MCU 抓不到 */ lis2dw12_write_reg(LIS2DW12_CTRL3, LIS2DW12_CTRL3_LIR); /* 将唤醒中断路由到 INT1 引脚 */ lis2dw12_write_reg(LIS2DW12_CTRL4_INT1_PAD_CTRL, LIS2DW12_CTRL4_INT1_WU); /* 设置唤醒阈值,阈值 = WU_THS[5:0] * FS / 64 */ /* 这里设 32,在 ±2g 量程下约等于 1g */ lis2dw12_write_reg(LIS2DW12_WAKE_UP_THS, 32); /* 设置唤醒持续时间,避免单次抖动误触发 */ lis2dw12_write_reg(LIS2DW12_WAKE_UP_DUR, 0x02); /* 使能唤醒功能 */ reg_val = lis2dw12_read_reg(LIS2DW12_CTRL1); reg_val |= LIS2DW12_CTRL1_WU_EN; lis2dw12_write_reg(LIS2DW12_CTRL1, reg_val); }

阈值计算是这里最容易出错的地方。WAKE_UP_THS 寄存器的 6 个位是阈值,实际触发加速度 = 阈值 × 量程 / 64。比如 ±2g 量程、阈值设 32,就是 32 × 2 / 64 = 1g。如果你设了阈值但一直不触发,先检查量程是不是设成了 ±16g,那样同样的阈值对应的实际加速度会大 8 倍。另外 WAKE_UP_DUR 决定的是超过阈值的持续时间,设太小会频繁误触发,设太大又可能漏掉快速动作,一般 0x02 到 0x05 之间比较合适。

3.2 FIFO 工作模式与数据批量读取

FIFO 是 LIS2DW12 另一个实用功能,可以在 MCU 休眠时把数据攒起来,唤醒后一次性读走,省电又省事。FIFO 支持几种模式:Bypass、FIFO、Continuous、Continuous-to-FIFO。最常用的是 Continuous 模式,FIFO 满了之后新数据覆盖旧数据,适合做振动监测。配置代码如下:

/* 配置 FIFO 为 Continuous 模式,水印阈值 16 个样本 */ void lis2dw12_config_fifo(void) { /* 设置 FIFO 水印阈值,达到这个数量后触发中断 */ lis2dw12_write_reg(LIS2DW12_FIFO_CTRL, 16); /* 设置 FIFO 模式为 Continuous,并路由水印中断到 INT1 */ lis2dw12_write_reg(LIS2DW12_FIFO_CTRL, LIS2DW12_FIFO_CTRL_MODE_CONTINUOUS | 16); /* 使能 FIFO 水印中断到 INT1 引脚 */ lis2dw12_write_reg(LIS2DW12_CTRL4_INT1_PAD_CTRL, LIS2DW12_CTRL4_INT1_FTH); } /* 读取 FIFO 中所有样本,返回实际读取的样本数 */ int lis2dw12_read_fifo(float *accel_buf, int max_samples) { uint8_t fifo_status; uint8_t raw_data[6]; int count, i; int16_t raw_x, raw_y, raw_z; /* 读取 FIFO_STATUS 寄存器,获取当前样本数 */ fifo_status = lis2dw12_read_reg(LIS2DW12_FIFO_STATUS); count = fifo_status & 0x3F; /* 低 6 位是样本数 */ if (count > max_samples) count = max_samples; for (i = 0; i < count; i++) { lis2dw12_read_regs(LIS2DW12_OUT_X_L, raw_data, 6); raw_x = (int16_t)((raw_data[1] << 8) | raw_data[0]) >> 4; raw_y = (int16_t)((raw_data[3] << 8) | raw_data[2]) >> 4; raw_z = (int16_t)((raw_data[5] << 8) | raw_data[4]) >> 4; accel_buf[i * 3] = raw_x * 0.061f; accel_buf[i * 3 + 1] = raw_y * 0.061f; accel_buf[i * 3 + 2] = raw_z * 0.061f; } return count; }

FIFO 读取时要注意,读 OUT_X_L 开始连续 6 个字节会自动推进 FIFO 指针,不需要手动操作。但如果你只读了 X 轴就停了,FIFO 指针不会自动跳到下一个样本,下次读出来的还是同一个样本的 Y 轴。所以要么一次读完 6 个字节,要么用 FIFO_CTRL 里的复位命令。另外水印中断触发后,FIFO 里的样本数可能超过水印值,读之前先查 FIFO_STATUS 最稳妥。

3.3 低功耗模式下的数据一致性保障

低功耗模式下,LIS2DW12 的噪声会明显增大,而且如果 MCU 和传感器共用电源域,电源纹波也会影响读数。常见做法是在读取数据前先检查 STATUS 寄存器的 DRDY 位,确保数据是新的一帧:

/* 等待新数据就绪,超时返回 -1 */ int lis2dw12_wait_data_ready(int timeout_ms) { int elapsed = 0; while (elapsed < timeout_ms) { if (lis2dw12_read_reg(LIS2DW12_STATUS) & LIS2DW12_STATUS_DRDY) { return 0; } lis2dw12_delay_ms(1); elapsed++; } return -1; }

这个函数在 100Hz 输出速率下,最多等 10ms 就能拿到新数据。如果一直超时,先检查 ODR 是不是设成了 0,或者传感器是不是还在掉电模式。低功耗模式下如果开了 BDU,读数据时不会出现高低字节不一致的问题,但代价是读取期间数据更新会被阻塞,所以读操作要尽量快。

4. 避坑与排查:调试 LIS2DW12 时最容易翻车的几个点

4.1 读出来的数据全是零或者固定值

现象:初始化后读三轴数据,X/Y/Z 始终是 0 或者某个固定值,怎么动传感器都不变。

原因:最常见的是 I2C 地址搞错了。LIS2DW12 的 I2C 地址由 SA0 引脚决定,SA0 接地是 0x18,接 VDD 是 0x19。如果你用的是 7 位地址,写驱动时还要左移一位。另一个可能是 CTRL1 的 ODR 位没设,传感器还在掉电模式,自然不会更新数据。

解决:先用逻辑分析仪或者示波器抓一下 I2C 波形,确认从机地址有没有应答。如果没有应答,检查 SA0 引脚电平。如果有应答但数据不变,读一下 WHO_AM_I 寄存器(地址 0x0F),正常应该返回 0x44。如果 WHO_AM_I 都不对,说明通信本身有问题。

4.2 中断引脚一直不触发

现象:配置了运动唤醒或者 FIFO 水印中断,但 INT1 引脚始终是高电平或者低电平,MCU 检测不到边沿。

原因:中断触发极性没配对。LIS2DW12 的 CTRL3 寄存器里有 H_LACTIVE 位,决定中断是高有效还是低有效。默认是低有效,但很多 MCU 的外部中断配置成下降沿触发,如果传感器输出的是高电平脉冲,就抓不到。另外中断锁存位 LIR 如果没开,脉冲可能太短,MCU 来不及响应。

解决:先确认 CTRL3 的 H_LACTIVE 和 LIR 设置,再检查 MCU 端的外部中断触发边沿。如果不确定,先把中断配置成双边沿触发,用示波器看引脚有没有脉冲。有脉冲但 MCU 不响应,就是触发边沿或优先级的问题;没脉冲,就是传感器内部中断没使能。

4.3 FIFO 读出来的数据顺序错乱

现象:FIFO 模式下读出来的三轴数据,X/Y/Z 对不上,或者相邻样本之间数值跳变很大。

原因:FIFO 读取时没有按 6 字节对齐读,或者读的过程中被其他中断打断,导致 FIFO 指针错位。另外如果 FIFO 模式设成了 Bypass,读出来的就是当前最新数据,不是 FIFO 里的历史数据。

解决:确保每次读 FIFO 都从 OUT_X_L 开始连续读 6 个字节,中间不要插入其他寄存器操作。如果 MCU 有 DMA,可以用 DMA 一次性搬 6 字节。读之前先查 FIFO_STATUS 的 FTH 位和 OVR 位,如果 OVR 置位说明 FIFO 溢出了,数据已经不可靠,需要复位 FIFO。

4.4 低功耗模式下电流比预期大

现象:配置成低功耗模式后,实测电流还是几百微安,跟手册标的几微安差很远。

原因:可能是 ODR 设得太高,或者开了不需要的功能。LIS2DW12 在 1.6Hz 低功耗模式下电流只有 1.5 微安左右,但 100Hz 下会到几十微安。另外如果 FIFO 和中断都开着,内部逻辑的功耗也会增加。还有一个容易忽略的点:如果 I2C 总线上有上拉电阻,而传感器在掉电模式下拉低了 SDA/SCL,会有额外的漏电流。

解决:先确认 ODR 和功耗模式是否匹配你的需求。如果不需要连续采集,用运动唤醒中断唤醒 MCU,平时让传感器处于低功耗模式。检查 I2C 上拉电阻的阻值,太大或太小都会影响功耗。最后用万用表串在电源线上实测,不要只看手册的典型值。

4.5 移植到新平台后编译报错或运行异常

现象:把驱动移植到另一款 MCU 上,编译能过但运行异常,或者直接编译报错找不到寄存器定义。

原因:platform 层的接口函数没实现完整,或者寄存器定义的头文件路径不对。有些平台的 I2C 读写函数需要传入设备地址,而驱动里默认用的是 7 位地址,如果平台库要求 8 位地址就会通信失败。

解决:先检查lis2dw12_platform.c里的读写函数是否都实现了,特别是lis2dw12_read_regs这种连续读的函数,很多平台库只提供了单字节读。地址问题的话,在 platform 层做一次左移就行,不要改驱动核心。编译报错就检查头文件包含路径,确保lis2dw12_reg.h能被找到。

5. 二次开发改造:从能跑到好用,我一般会做这几件事

拿到一份能跑的驱动只是起点,真正用到项目里还得做几轮改造。我一般会从这几个方向下手。

第一件事是加一层数据滤波。LIS2DW12 在低功耗模式下噪声不小,直接拿原始数据做姿态解算会抖得厉害。常见做法是在驱动上层加一个滑动平均或者一阶低通滤波。滑动平均实现简单,但会引入相位延迟;一阶低通滤波计算量小,适合 MCU 实时跑。我一般会留一个滤波系数接口,让应用层根据场景调。比如做计步的时候系数设小一点,做振动监测的时候设大一点。

第二件事是把中断处理从轮询改成事件驱动。示例代码里很多是轮询 STATUS 寄存器等数据就绪,实际项目里这样太耗电。改造思路是把 INT1 或 INT2 接到 MCU 的外部中断引脚,在中断服务函数里置一个标志位,主循环检测到标志位再读数据。这样 MCU 大部分时间可以休眠,整体功耗能降一个数量级。注意中断服务函数里不要做 I2C 读操作,I2C 通信时间可能比较长,放在中断里会影响其他中断的响应。

第三件事是加自检和错误恢复机制。传感器偶尔会因为电源波动或者静电导致寄存器配置丢失,表现就是数据突然不变了或者量程变了。我一般会在主循环里定期读一下 WHO_AM_I 和 CTRL1,跟预期值比对,不一致就重新初始化。这个操作开销很小,但能避免很多玄学问题。另外如果 I2C 通信连续失败几次,可以尝试重新初始化 I2C 外设,有时候是总线锁死了。

第四件事是统一单位。驱动层读出来的是 mg,但应用层可能用 m/s²,姿态解算可能用 g。我一般会在驱动层提供一个设置输出单位的接口,内部做一次换算,这样应用层不用到处乘 9.8。换算的时候注意精度,mg 转 m/s² 是乘以 0.0098,用浮点还是定点看 MCU 有没有 FPU。

下面是一个改造后的数据读取接口示例,加了滤波和单位切换:

/* 改造后的数据读取接口,支持滤波和单位切换 */ typedef enum { UNIT_MG, /* 毫克 */ UNIT_MS2, /* 米每二次方秒 */ UNIT_G /* 重力加速度 */ } accel_unit_t; static float filter_alpha = 0.3f; /* 低通滤波系数,越小越平滑 */ static float last_accel[3] = {0}; void lis2dw12_read_accel_filtered(float *accel, accel_unit_t unit) { float raw[3]; float scale; lis2dw12_read_accel(raw); /* 原始读取,单位 mg */ /* 一阶低通滤波 */ last_accel[0] = last_accel[0] * (1 - filter_alpha) + raw[0] * filter_alpha; last_accel[1] = last_accel[1] * (1 - filter_alpha) + raw[1] * filter_alpha; last_accel[2] = last_accel[2] * (1 - filter_alpha) + raw[2] * filter_alpha; /* 单位换算 */ switch (unit) { case UNIT_MS2: scale = 0.0098f; break; case UNIT_G: scale = 0.001f; break; default: scale = 1.0f; break; } accel[0] = last_accel[0] * scale; accel[1] = last_accel[1] * scale; accel[2] = last_accel[2] * scale; }

这个接口用起来就顺手多了,应用层不用关心底层是 mg 还是 m/s²,也不用自己写滤波。滤波系数filter_alpha可以做成运行时可调的,通过串口命令或者配置文件改。我一般会在调试阶段把它设成 1.0(不滤波),看原始数据长什么样,确认没问题了再往下调。

验证改造效果的方法也很直接:拿一块已知姿态的板子,静止放平,看 Z 轴是不是接近 1g(或者 9.8 m/s²),X/Y 接近 0。然后快速晃动,看数据能不能跟上,有没有明显的延迟或者过冲。如果做运动唤醒,就用手指轻敲传感器,看中断能不能稳定触发,连续敲十次至少中九次才算合格。

从那以后我每次拿到新的传感器驱动,都强制走一遍“先读 WHO_AM_I,再配 ODR,再验数据,最后调中断”的流程,不跳过任何一步。这套流程帮我省了很多来回翻手册的时间,希望也能帮到你。

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

相关新闻

ESP32S3 Dev Module 开发实战:双核任务与屏幕驱动详解

ESP32S3 Dev Module 开发实战:双核任务与屏幕驱动详解

1. 为什么这块板子成了物联网项目的主力选择如果你最近两年逛过电子市场或者混过创客社区&#xff0c;大概率会发现一个现象&#xff1a;越来越多人在聊ESP32S3 Dev Module这块开发板。它不像某些经典入门板那样“只适合点个灯”&#xff0c;也不像高端开发板那样价格劝退。它卡…

2026/10/20 21:18:02 阅读更多 →
手写鼠标点击粒子特效:从原理到性能优化的完整实战

手写鼠标点击粒子特效:从原理到性能优化的完整实战

前阵子给某活动页面做氛围优化&#xff0c;需求方反复强调要有“互动感”。白底、黑字、产品图&#xff0c;排版再干净&#xff0c;鼠标移上去没有任何反馈&#xff0c;也确实容易让人产生“这是个静态PPT”的错觉。于是我想到了“鼠标粒子特效”——准确说&#xff0c;是一段H…

2026/10/20 21:16:52 阅读更多 →
Java实现IP归属地查询:离线库方案与Spring Boot封装实践

Java实现IP归属地查询:离线库方案与Spring Boot封装实践

在做日志分析和用户画像时&#xff0c;后端服务拿到一个公网IP&#xff0c;最朴素的需求就是想知道这个IP到底来自哪个省、哪个市&#xff0c;甚至哪个运营商。这个需求听起来不难&#xff0c;网上搜“Java IP归属地查询”会跳出一堆在线API&#xff0c;复制一段代码就能跑通&a…

2026/10/20 21:16:52 阅读更多 →

最新新闻

全球AI模型榜前20名国产占6席:技术路线与选型指南

全球AI模型榜前20名国产占6席:技术路线与选型指南

1. 榜单背后的信号&#xff1a;国产模型进入第一梯队的真实含义第一次看到“全球AI模型榜前20名&#xff0c;国产占了6个”这个说法时&#xff0c;我的第一反应不是兴奋&#xff0c;而是想搞清楚三件事&#xff1a;这是哪个榜单、用什么指标排的、这6个模型分别强在哪。因为在大…

2026/10/20 22:39:53 阅读更多 →
多头自注意力机制详解:从原理到代码实战,用外卖订单讲透Transformer核心

多头自注意力机制详解:从原理到代码实战,用外卖订单讲透Transformer核心

1. 多头自注意力&#xff1a;别再死记公式&#xff0c;我用外卖订单给你讲明白第一次接触“多头自注意力”这个概念的时候&#xff0c;我盯着论文里的公式看了整整一个下午&#xff0c;脑子里全是“这到底是什么玩意儿”。后来做了几年深度学习相关的项目&#xff0c;踩过不少坑…

2026/10/20 22:39:53 阅读更多 →
计算器也能打穿?CTF中PHP eval黑名单绕过实战解析

计算器也能打穿?CTF中PHP eval黑名单绕过实战解析

1. 拿到题目的第一轮信息收集&#xff1a;页面、请求和异常输入探针1.1 先用肉眼和抓包把页面过一遍CTF的Web题里&#xff0c;最容易被低估的就是这种"门面干净"的题目。页面没有跳转、没有登录、没有文件上传点&#xff0c;只有一个孤零零的输入框和一个计算结果区&…

2026/10/20 22:39:53 阅读更多 →
用Python打造PPT生成工具:模板+数据+渲染三层架构实战

用Python打造PPT生成工具:模板+数据+渲染三层架构实战

1. 为什么我要自己动手做一个 PPT 生成工具 做技术分享、项目汇报、课程作业&#xff0c;甚至给客户做方案&#xff0c;PPT 几乎是绕不开的一环。我粗略算过&#xff0c;过去一年里我至少做了四十多份 PPT&#xff0c;平均每份从整理大纲到排版定稿要花三到五个小时。最让人抓狂…

2026/10/20 22:39:52 阅读更多 →
Python+TensorFlow+PyQt5人脸表情识别与情绪分类系统实战

Python+TensorFlow+PyQt5人脸表情识别与情绪分类系统实战

人脸表情识别这个方向&#xff0c;外行看起来就是“认个脸、判断一下表情”&#xff0c;真正动手做的人才知道&#xff0c;从摄像头画面到“开心、难过、惊讶”这些标签之间&#xff0c;至少隔着四座山&#xff1a;数据、模型、推理、界面。我最近把一套基于 Python TensorFlo…

2026/10/20 22:39:52 阅读更多 →
MySQL+Java+Swing学生宿舍管理系统课程设计全解析

MySQL+Java+Swing学生宿舍管理系统课程设计全解析

简介&#xff1a;面向高校数据库与Java课程设计场景&#xff0c;这套基于MySQLJavaSwing开发的学生宿舍管理系统提供了完整的可运行工程与配套文档。资源以学生信息管理、宿舍分配管理、管理员后台等核心模块为主线&#xff0c;包含数据库表设计、界面交互与业务逻辑分层实现&a…

2026/10/20 22:38:46 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →