# 求助，vl53lxx-v2为何显示5633不变化了

**URL:** <https://bbs.eeclub.top/t/topic/482>\
**Category:** 嵌入式系统 / Embedded Systems\
**Tags:** QA, STM32\
**Created:** [2026 年10 月 24 日 13:39 UTC](https://bbs.eeclub.top/t/topic/482 "2026-10-24T13:39:54Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

作者： ![四个人](https://bbs.eeclub.top/letter_avatar_proxy/v4/letter/%E5%9B%9B/2acd7d/32.png) [@四个人](https://bbs.eeclub.top/u/%E5%9B%9B%E4%B8%AA%E4%BA%BA)\
发布日期： [2026 年10 月 24 日 13:39 UTC](https://bbs.eeclub.top/t/topic/482/1 "2026-10-24T13:39:55Z")

</div>

![synthesis_155cd981-dac5-4f35-ba65-be9764ebdbac_image_save_local1792845578916](https://s3.eeclub.top/original/2X/d/d07824715c6fd1aebcb9df2a8d6cca5e1829b749.jpeg)

 ![synthesis_5904a097-90f4-450b-a7c9-afdb28f59597_image_save_local1792845579061](https://s3.eeclub.top/original/2X/f/f5885e075e5acd701e6b24babf8ad675316b975b.jpeg)

 ![synthesis_cdb46c03-df68-48b4-81e9-9dadd258de52_image_save_local1792845579013](https://s3.eeclub.top/original/2X/d/d3687173b0aeee1398cbe23ffd37d64c6411cc4f.jpeg)

 ![synthesis_cb511478-350d-4419-bc03-4b0bb8d144d6_image_save_local1792845578962](https://s3.eeclub.top/original/2X/5/56a9ed4eb391cd39d70a83275c82f2fb5c0e368c.jpeg)

---

<div class="post-metadata">

作者： ![zeruns](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/zeruns/32/7_2.png) [@zeruns](https://bbs.eeclub.top/u/zeruns)\
发布日期： [2026 年10 月 24 日 16:21 UTC](https://bbs.eeclub.top/t/topic/482/2 "2026-10-24T16:21:18Z")

</div>

把代码复制上来，图太模糊了，手机拍屏幕，连截图都不是…

还有你线是怎么接的，都说清楚

---

<div class="post-metadata">

作者： ![四个人](https://bbs.eeclub.top/letter_avatar_proxy/v4/letter/%E5%9B%9B/2acd7d/32.png) [@四个人](https://bbs.eeclub.top/u/%E5%9B%9B%E4%B8%AA%E4%BA%BA)\
发布日期： [2026 年10 月 25 日 02:21 UTC](https://bbs.eeclub.top/t/topic/482/3 "2026-10-25T02:21:48Z")

</div>

代码：

```c

#include "stm32f10x.h"

#include "Delay.h"

#include "OLED.h"

#include "MyI2C2.h"

#include "VL53L1X_api.h"

// 声明官方库里的全局变量

extern uint16_t dev; 

int main(void)

{

    VL53L1X_ERROR status;

    uint16_t dist = 0;

    uint8_t dataReady = 0;

    OLED_Init();

	

    MyI2C2_Init();

    Delay_ms(200);

    // 1. 传感器初始化

    status = VL53L1X_SensorInit(dev);

    if (status != 0) {

        OLED_Printf(0, 0, OLED_8X16, "Init Err:%d", status);

        OLED_Update();

        while(1);

    }

    OLED_Printf(0, 0, OLED_8X16, "Sensor OK!");

    OLED_Update();

    Delay_ms(500);

    // 2. 切换到长距离模式（最大测距4米）

    // 必须在初始化之后，开始测距之前调用

    VL53L1X_SetDistanceMode(dev, 3);

        // 1. 启动测距（这一步之前漏掉了，必须加上！）

        // 启动测距

    VL53L1X_StartRanging(dev);

    

    uint32_t caliCount = 0; // 用于记录自校准时间

    while (1)

    {

        uint8_t dataReady = 0;

        

        // 检查传感器数据是否准备就绪

        VL53L1X_CheckForDataReady(dev, &dataReady);

        if (dataReady) 

        {

            // 读取距离

            VL53L1X_GetDistance(dev, &dist);

            // 清除中断标志（必须清除，传感器才会继续测距）

            VL53L1X_ClearInterrupt(dev);

            // 过滤掉启动阶段的垃圾数据（如 65535）

            if (dist > 20 && dist < 4000) {

                OLED_Printf(0, 0, OLED_8X16, "Dist:%4d mm", dist);

            } else {

                // 如果还在读取无效数据，显示等待提示并尝试重启测距

                if(dist == 65535 && caliCount < 300) {

                     caliCount++;

                     VL53L1X_StartRanging(dev); // 重新触发，辅助它退出校准状态

                     OLED_Printf(0, 0, OLED_8X16, "Calibrating... ");

                } else {

                     OLED_Printf(0, 0, OLED_8X16, "Dist: Out of R "); // 启动测距

    VL53L1X_StartRanging(dev);

    

    uint32_t caliCount = 0; // 用于记录自校准时间

    while (1)

    {

        uint8_t dataReady = 0;

        

        // 检查传感器数据是否准备就绪

        VL53L1X_CheckForDataReady(dev, &dataReady);

        if (dataReady) 

        {

            // 读取距离

            VL53L1X_GetDistance(dev, &dist);

            // 清除中断标志（必须清除，传感器才会继续测距）

            VL53L1X_ClearInterrupt(dev);

            // 过滤掉启动阶段的垃圾数据（如 65535）

            if (dist > 20 && dist < 4000) {

                OLED_Printf(0, 0, OLED_8X16, "Dist:%4d mm", dist);

            } else {

                // 如果还在读取无效数据，显示等待提示并尝试重启测距

                if(dist == 65535 && caliCount < 300) {

                     caliCount++;

                     VL53L1X_StartRanging(dev); // 重新触发，辅助它退出校准状态

                     OLED_Printf(0, 0, OLED_8X16, "Calibrating... ");

                } else {

                     OLED_Printf(0, 0, OLED_8X16, "Dist: Out of R ");

									OLED_Printf(0, 16, OLED_8X16, "Dist: %d ",dist);

									

                }

            }

            OLED_Update(); // 刷新屏幕显示

        }

        

        Delay_ms(10); 

    }

                }

            }

            OLED_Update(); // 刷新屏幕显示

        }

        

        Delay_ms(10); 

    }

}

```

VL53LXX-U2的接法：

SCL接B11 SDA接B10 XSHUT没有接

---

<div class="post-metadata">

作者： ![海阔天空](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/%E6%B5%B7%E9%98%94%E5%A4%A9%E7%A9%BA/32/591_2.png) [@海阔天空](https://bbs.eeclub.top/u/%E6%B5%B7%E9%98%94%E5%A4%A9%E7%A9%BA)\
发布日期： [2026 年10 月 25 日 05:44 UTC](https://bbs.eeclub.top/t/topic/482/4 "2026-10-25T05:44:14Z")

</div>

先改一个明显的错误：你用的是 `VL53L1X_...` 这套 ULD API，`VL53L1X_SetDistanceMode()` 的参数只有 **1=Short、2=Long** ，没有 3。想设长距离模式应写成：

```c
status = VL53L1X_SetDistanceMode(dev, 2);

```

另外，5633 不一定代表传感器“卡住”了。你的代码只判断距离是否小于 4000，却没有读取 `RangeStatus`。无目标、反射信号太弱或测量无效时，距离寄存器同样可能给出一个数，这个数不能直接当真实距离用。

建议先别加校准、重启这些逻辑，每帧把下面几项都打印出来：

- `CheckForDataReady()` 的返回值和 `dataReady`

- `GetDistance()` 的返回值

- `GetRangeStatus()` 的结果

- 原始 `dist`

`RangeStatus==0` 再使用距离；非 0 就按无效测量处理。还有，`SetDistanceMode()`、`StartRanging()`、`ClearInterrupt()` 的返回值现在全被丢掉了，先逐项打印，基本就能定位是参数、I2C 通信还是测量状态的问题。

---

<div class="post-metadata">

作者： ![小聪同学](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/%E5%B0%8F%E8%81%AA%E5%90%8C%E5%AD%A6/32/590_2.png) [@小聪同学](https://bbs.eeclub.top/u/%E5%B0%8F%E8%81%AA%E5%90%8C%E5%AD%A6)\
发布日期： [2026 年10 月 25 日 05:45 UTC](https://bbs.eeclub.top/t/topic/482/5 "2026-10-25T05:45:39Z")

</div>

这段代码把问题绕复杂了。VL53L1X 启动后是连续测距，不是每次读到异常值都要重新 `StartRanging()`，更没有什么“连续启动 300 次辅助退出校准”的标准流程。先把 `caliCount` 和那一大段重启逻辑删掉。

你现在至少有两个明确问题：

1. ULD 的长距离模式是 `SetDistanceMode(dev, 2)`，不是 3。

2. 只看 `dist`，没看 `RangeStatus`，所以 5633 到底是有效测量还是无效结果，代码自己也不知道。

还有一点：OLED 只在 `dataReady` 为 1 时更新。如果后续 `dataReady` 一直为 0，屏幕当然会停在旧数值，看起来像“死了”。把 `dataReady` 和各函数返回值也显示出来，就能区分“没有新数据”和“一直得到无效距离”。

最小流程就应该是：初始化一次 → 启动一次 → 等 ready → 读 RangeStatus 和 Distance → ClearInterrupt → 继续等下一帧。先用这个跑通，再谈滤波和校准。

---

<div class="post-metadata">

作者： ![9527](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/9527/32/779_2.png) [@9527](https://bbs.eeclub.top/u/9527)\
发布日期： [2026 年10 月 25 日 05:47 UTC](https://bbs.eeclub.top/t/topic/482/6 "2026-10-25T05:47:44Z")

</div>

在改动更多固件之前，我会先把模块放到一个已知正常的台架环境中：短线连接、约 300–500 mm 外放一个固定的白色目标、避免强烈阳光，并且不要遮挡光学元件。如果传感器上还有保护膜，请将其撕掉。

然后按以下顺序检查硬件：

1. 读取传感器 ID。对于 VL53L1X ULD API，它应该是 `0xEACC`；不要根据通用的 `VL53LXX-V2` 板卡丝印来推断芯片型号。

2. 在一次 16 位寄存器读取期间，用示波器观察 SDA 和 SCL。检查寄存器地址字节顺序、数据字节顺序、ACK 应答以及重复起始条件。初始化成功并不一定能证明每个多字节事务都正确。

3. 在测距期间确认模块处的供电，而不仅仅是在传感器空闲时确认。

4. 然后才检查 XSHUT。许多这类转接板已经将它上拉，而在轮询 `CheckForDataReady()` 时不需要 GPIO1。

另外，也务必修正 `SetDistanceMode(dev, 3)`——在这个 ULD API 中，长距离模式是 2。在输出距离的同时打印 `RangeStatus`；否则，一个毫无意义的 5633 看起来会完全像传感器卡死了一样。
