低成本单发单收激光测距传感器全套解决方案
低成本单发单收激光测距传感器方案 低成本单发单收激光测距全套方案,包括原理图、源代码、PCB、BOM、光学部分资料,结构、特殊元件数据手册及供应商联系方式,提供调试技术文档。 全套方案已成功打板验证,实现0.05~50m测量范围,精度在+/—1.5mm,激光波长635~650nm,功率《1mW。 方案预留了SPI LCD显示屏接口、按键接口、TTL串口,可通过串口助手看到测量数据,可自行DIY或者商业开发。
—— 软件功能深度解读(面向量产与二次开发)
前言
在“毫米级精度、百元级成本”的激光测距市场,传统方案往往依赖 FPGA 高速采样或双光路结构。本开源项目反其道而行:仅用一颗 24 MHz 主频的 STM32F10x、一片 12-bit ADC、一片可调 APD 高压源,就实现了 0.05~30 m 范围内亚厘米级测距。整个软件系统围绕“如何让慢速 MCU 做出高速相位仪”展开,功能密度极高。下文将以“代码本身怎么说”为主线,逐层拆解其设计哲学与实现技巧,帮助开发者快速理解、移植与魔改。
一、工程骨架:三频采样状态机
打开任意一个 .c 文件,你会发现几乎没有任何裸机框架的“废话”——没有 RTOS 任务、没有事件标志组,只有一套极简状态机 dmastatetype。它把“三频顺序采样”抽象成 7 个互斥状态:
DMANODATA→ 空闲DMAFREQ1CAPTURING→ 正在采 162.5 MHzDMAFREQ1DONE→ 完成,等待切频- ……
DMAFREQ3DONE→ 三频完毕,进入计算
状态机由 autohandlecapture() 驱动,每切换一次频率都伴随一次 PLL 重配置、150 µs 固定延时、DMA 目标地址重定向。代码里看不到任何“delay 死等”——延时用 DWT 周期计数器精确到 1 µs,CPU 在此期间可以喂狗、擦 Flash、甚至回串口指令。整套状态机占用的 ROM 不到 400 B,却保证了 50 Hz 的稳定输出帧率。
二、采样链路:让 12-bit ADC 跑出 350 kS/s
STM32F10x 官方手册把 ADC 最高速率标在 1 MS/s,但前提是 56 MHz 总线时钟、并关闭采样保持。现实是主频只有 24 MHz,还要给 DMA 留总线带宽。代码里通过三重手段“榨干”性能:
- 双通道“背靠背”采样
ADC 扫描模式一次触发连续采两路:信号通道 + 参考通道。这样 Timer 更新频率 = 采样频率 /2,DMA 带宽瞬间减半。 - 采样时间寄存器写 1.5 周期
在initadccapture()里你会看到ADCSampleTime1Cycles5,再配合 12 MHz ADC 时钟,实际采样窗口 125 ns,刚好满足 APD 输出 10 MHz 带宽的奈奎斯特准则。 - DMA “半传输”中断被刻意关闭
很多参考设计打开 HT 中断做双缓冲,但这里只用 TC 中断。代码在 TC 回调里直接切换状态机,省去一次中断进出,12 字节寄存器操作在 500 ns 内完成,相当于给下一次采样留出 2.5 µs 的“呼吸”时间。
三、相位提取:Goertzel 的定点化盛宴
FFT 在 Cortex-M3 上跑 256 点需要约 12 ms,而项目要求 50 Hz 帧率,显然不可接受。代码转向 Goertzel 算法——只计算目标频率那一个“bin”。但作者并未直接搬用浮点公式,而是做了三层优化:
- 预生成
sinbuf/cosbuf:启动时一次性把 256 点的q31正余弦表算好,运行期只做乘法-累加。 - 乘法规格化:把
adcvalue<<4后再与sinbuf[i]相乘,保证 32-bit 累加器 256 次不溢出,同时保留 0.1° 相位分辨率。 - 幅度用近似根号:
|Z|≈max(|Re|,|Im|)+min/2,省掉sqrtf()的 2 k 周期,误差 <1 %,对后续 AGC 完全够用。
最终 goertzel_analyse() 跑完 256 点双通道只要 180 µs,CPU 占用 0.4 %。
四、距离解算:三频“中国剩余定理”实战
拿到三个相位 φ1,φ2,φ3 后,如何算出唯一距离?代码走了一条“先粗后细”的路线:
- 粗算 N
用 191.5 MHz 与 193.5 MHz 做差频 2 MHz,波长 150 m,先把距离锁在 ±75 m 唯一区间。 - 细算 ΔN
再用 162.5 MHz 与 191.5 MHz 差频 29 MHz,把 150 m 切成 5.17 m 一格,确定整数 N。 - 局部暴力搜索
最后 6 格窗口内暴力比较|d1-d2|最小值,消掉相位噪声带来的跳格错误。
整段算法只用 16 位整形运算,没有除法、没有浮点,却能把“多值性”在 5 ms 内消得干干净净。代码注释里把这套流程叫“bruteforcedistcalculation”,名字看似粗暴,实则把计算复杂度从 O(N²) 降到 O(6×6)。
五、温度-高压双闭环:把漂移吃回去
激光测距最怕温度漂移。项目用两条闭环把“电-光-温度”耦合到一起:
- 温度闭环
片内 ADC 采样 NTC,二次曲线66.843-0.0295·Raw+2.122e-6·Raw²把原始值直接映射到摄氏度,误差 ±0.5 ℃。随后calculate_correction()根据温漂系数把相位偏移“反拧”回去,系数在-40 ℃~80 ℃全温区标定。 - 高压闭环
代码在启动校准阶段扫描 DAC 输出,记录 APD 刚刚出现饱和时的电压值apdsaturationvoltage。运行期每隔 500 ms 检查一次振幅:
– 振幅 > 2200 LSB → 高压降 1 V
– 振幅 < 2000 LSB → 高压回到温度-电压曲线预测值
两条闭环一软一硬,把温漂从 5 mm/℃ 压到 0.3 mm/℃ 以内,同时保证 SNR 始终 >30 dB。
六、校准与量产:一颗按钮就能下线
校准函数 dophasecalibration() 是整包代码里最“啰嗦”的部分,却也是量产最省心的地方:
- 自动找最佳 APD 电压
先低压 80 V 采 10 次,振幅不够就逐级升压,直到 >200 LSB 或触及 115 V 上限,记录此刻电压。 - 三频零位写入 Flash
每个频率采 64 次,中位值滤波后写 Flash 第 31 页,页首加 0x1234 魔术字,下次上电自动加载。 - 饱和电压一并保存
同样写进 Flash,换板子后无需重新手动找饱和点。
整机下线流程:装壳 → 对准 1 m 白板 → 按住按键 3 s → 蜂鸣器“嘀嘀”两声 → 校准完成,全程 8 s,无需电脑。
七、可移植与裁剪指南
代码全部寄存器版 HAL,迁移到 STM32F0/F4 只需改三处:
- 启动文件
startupstm32f10xmd.s换成对应系列 corecm3.h改为corecm0.h或core_cm4.hDWT_CYCCNT在 CM0 不存在,可改用 SysTick 差值
若目标距离 <5 m,可砍掉三频算法,只留 191.5 MHz 单频,Flash 占用从 36 KB 缩到 12 KB,RAM 保持 8 KB 不变。
八、结语:把“简单”做到极致
通读整套代码,你会发现它几乎没有“炫技”——没有 RTOS、没有浮点、没有复杂外设,却用“最笨”的状态机、最朴素的整形运算,把激光相位测距的门槛拉到了百元以内。对开发者而言,这份代码的价值不在于“用了多少高端外设”,而在于它把每一个环节都做到了“刚好够用”:
- 采样刚好不丢点
- 运算刚好不溢出
- 校准刚好不麻烦
如果你正在寻找一套“能直接装进产线”的激光测距方案,或者想在最便宜的 MCU 上体验“毫米级”的测量乐趣,那么打开这份源码,从 autohandlecapture() 开始单步跟踪吧——每一行都在告诉你:低成本并不等于低性能,关键在于是否把每一分钱都算得刚刚好。

低成本单发单收激光测距传感器方案 低成本单发单收激光测距全套方案,包括原理图、源代码、PCB、BOM、光学部分资料,结构、特殊元件数据手册及供应商联系方式,提供调试技术文档。 全套方案已成功打板验证,实现0.05~50m测量范围,精度在+/—1.5mm,激光波长635~650nm,功率《1mW。 方案预留了SPI LCD显示屏接口、按键接口、TTL串口,可通过串口助手看到测量数据,可自行DIY或者商业开发。







AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)