news 2026/5/12 19:46:18

【STM32实战—TOF激光测距】第二篇、I2C协议驱动TOF10120实现精准距离采集与滤波

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【STM32实战—TOF激光测距】第二篇、I2C协议驱动TOF10120实现精准距离采集与滤波

1. TOF10120激光测距模块基础解析

第一次接触TOF10120这个激光测距模块时,我被它的小巧体积和180cm的测量范围惊艳到了。这个模块特别适合用在智能小车避障或者家居智能设备上,实测在10cm到180cm范围内误差可以控制在±1cm以内。模块支持3.3V和5V供电,我用STM32的3.3V直接供电完全没问题,连续工作几小时也不会发烫。

模块背面有6个引脚,实际使用中我们只需要关注4个:VCC(红)、GND(黑)、SCL(绿)、SDA(蓝)。这里有个小细节要注意——模块支持I2C和串口两种通信方式,但实测I2C方式更稳定,特别是当你的STM32串口资源紧张时。我刚开始调试时犯了个错误,把TXD和RXD也接上了,后来发现根本用不到,白白浪费了两个IO口。

2. I2C硬件连接与初始化

2.1 硬件接线方案

我用的是STM32F103C8T6最小系统板,选择PB12和PB13作为I2C引脚。接线时有个坑要注意:模块的I2C是3.3V电平的,如果你用的开发板是5V电平,记得要加电平转换电路。我的接法是这样的:

  • 模块VCC → 3.3V
  • 模块GND → GND
  • 模块SCL → PB12
  • 模块SDA → PB13

这里有个实用技巧:在SDA和SCL线上各加一个4.7kΩ的上拉电阻到3.3V,能显著提高通信稳定性。我刚开始没加上拉电阻,发现偶尔会通信失败,加上后就再没出过问题。

2.2 GPIO初始化代码

在tof.h中定义引脚配置:

#define I2C_SCL_PIN GPIO_Pin_12 #define I2C_SCL_PORT GPIOB #define I2C_SDA_PIN GPIO_Pin_13 #define I2C_SDA_PORT GPIOB

初始化函数这样写:

void UserI2c_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(I2C_SCL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN; GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure); GPIO_SetBits(I2C_SCL_PORT, I2C_SCL_PIN); GPIO_SetBits(I2C_SDA_PORT, I2C_SDA_PIN); }

3. I2C通信协议实现

3.1 基础通信函数

写I2C驱动时,最关键的是时序控制。下面这个发送起始信号的函数,我调试了好久才稳定:

void UserI2c_Start(void) { USERI2C_SDA_1; delay_us(5); USERI2C_SCL_1; delay_us(5); USERI2C_SDA_0; // START条件:SCL高电平时SDA下降沿 delay_us(5); USERI2C_SCL_0; delay_us(30); }

发送一个字节的函数要注意时钟同步:

void UserI2c_Send_Byte(unsigned char txd) { unsigned char t; USERI2C_SCL_0; delay_us(5); for(t=0; t<8; t++) { if((txd & 0x80) >> 0) USERI2C_SDA_1; else USERI2C_SDA_0; txd <<= 1; delay_us(5); USERI2C_SCL_1; delay_us(5); USERI2C_SCL_0; } }

3.2 读写寄存器实现

模块的寄存器读写有固定格式。写寄存器函数:

unsigned char SensorWritenByte(unsigned char Devid, unsigned char *TXBuff, unsigned char SubAdd, unsigned char Size) { unsigned char i = 0; UserI2c_Start(); UserI2c_Send_Byte(Devid | 0x00); if(0 == UserI2c_Wait_Ack()) { UserI2c_Stop(); return 0; } UserI2c_Send_Byte(SubAdd & 0xff); if(0 == UserI2c_Wait_Ack()) { UserI2c_Stop(); return 0; } for(i=0; i<Size; i++) { UserI2c_Send_Byte(TXBuff[Size-i-1]); if(0 == UserI2c_Wait_Ack()) { UserI2c_Stop(); return 0; } } UserI2c_Stop(); return 1; }

4. 距离数据采集与滤波

4.1 实时模式与滤波模式对比

TOF10120支持两种数据模式:

  • 实时模式(0x08寄存器置1):响应快但数据跳动大
  • 滤波模式(0x08寄存器置0):数据稳定但有约100ms延迟

在main.c中这样配置:

dirt_detection_flag=0; // 0-滤波模式 1-实时模式 SensorWritenByte(devid, (unsigned char *)&dirt_detection_flag, 0x08, 1);

实测数据对比:

模式响应时间数据波动适用场景
实时<10ms±3cm高速检测
滤波~100ms±0.5cm精确测量

4.2 数据读取实现

读取滤波后的距离值(单位:mm):

SensorReadnByte(devid, (unsigned char *)&length_aveval, 0x04, 2); printf("距离:%d mm\r\n", length_aveval);

这里有个重要技巧:读取前最好加个延时,我一般用100ms间隔读取,这样数据最稳定。曾经试过10ms读取一次,发现会出现通信错误。

5. 实际应用中的问题排查

5.1 常见通信故障

调试时遇到最多的问题是I2C无响应,通常有几个原因:

  1. 电源不稳:示波器看3.3V是否有波动
  2. 上拉电阻缺失:SCL/SDA必须加4.7kΩ上拉
  3. 时序问题:用逻辑分析仪抓波形看时序是否符合标准

5.2 数据异常处理

当读到异常值(如65535)时,建议这样处理:

#define MAX_VALID_DISTANCE 1800 // 180cm if(length_aveval > MAX_VALID_DISTANCE) { // 重试读取 SensorReadnByte(devid, (unsigned char *)&length_aveval, 0x04, 2); if(length_aveval > MAX_VALID_DISTANCE) { printf("测量超限!\r\n"); length_aveval = MAX_VALID_DISTANCE; } }

6. 不同场景下的优化建议

6.1 智能小车避障

建议配置:

  • 使用滤波模式
  • 采样间隔150ms
  • 触发距离设置80cm
  • 开启模块的自动校准功能(0x0A寄存器置1)

6.2 室内定位应用

优化方案:

  • 多个模块协同工作
  • 采用中值滤波算法
  • 校准环境参数(0x0B寄存器)
  • 使用固定测量间隔(如200ms)

7. 进阶技巧与性能提升

7.1 软件滤波增强

除了硬件滤波,可以加移动平均滤波:

#define FILTER_SIZE 5 unsigned int filter_buf[FILTER_SIZE]; unsigned int filter_index = 0; unsigned int moving_average_filter(unsigned int new_val) { filter_buf[filter_index++] = new_val; if(filter_index >= FILTER_SIZE) filter_index = 0; unsigned int sum = 0; for(int i=0; i<FILTER_SIZE; i++) { sum += filter_buf[i]; } return sum / FILTER_SIZE; }

7.2 低功耗优化

通过配置0x0C寄存器可以降低功耗:

unsigned char low_power_mode = 1; // 1-低功耗模式 SensorWritenByte(devid, &low_power_mode, 0x0C, 1);

实测功耗对比:

  • 正常模式:12mA
  • 低功耗模式:6mA
  • 休眠模式:0.5mA(需通过0x0D寄存器唤醒)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 19:45:43

JetBrains IDE无限期使用终极指南:如何永久重置30天试用期

JetBrains IDE无限期使用终极指南&#xff1a;如何永久重置30天试用期 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 还在为JetBrains IDE试用期到期而焦虑吗&#xff1f;每次30天试用结束后&#xff0c;那些专业…

作者头像 李华
网站建设 2026/5/12 19:43:12

当BitLocker成为拦路虎:系统异常时的密钥寻回与命令行解锁实战

1. 当BitLocker锁死系统时该怎么办 上周我的主力工作电脑突然蓝屏&#xff0c;重启后直接卡在BitLocker恢复密钥输入界面。那一刻我后背发凉——电脑里存着三个正在赶的项目文档。相信很多朋友都遇到过类似情况&#xff1a;系统崩溃后&#xff0c;BitLocker这个安全卫士突然变成…

作者头像 李华
网站建设 2026/5/12 19:37:15

Perplexity检索GitHub突然变慢?紧急排查清单:DNS污染、token降权、向量缓存击穿——凌晨2点救火实录(含监控看板)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Perplexity GitHub资源检索 Perplexity 是一款以实时语义检索与引用溯源见长的 AI 搜索工具&#xff0c;其对 GitHub 代码库的深度索引能力显著优于传统搜索引擎。当开发者需快速定位高质量开源实现、特…

作者头像 李华
网站建设 2026/5/12 19:36:11

3个常见风扇控制难题:用FanControl轻松解决的实用指南

3个常见风扇控制难题&#xff1a;用FanControl轻松解决的实用指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa…

作者头像 李华
网站建设 2026/5/12 19:36:08

AI生成客观内容|GEO优化实战指南及平台推荐

GEO优化实施方法与推荐平台 一、GEO优化实施方法 GEO&#xff08;生成引擎优化&#xff09;的核心是通过优化内容与数据&#xff0c;提升其在生成式AI&#xff08;如ChatGPT、豆包、DeepSeek等&#xff09;中的可见性和被推荐概率。其实施是一个系统工程&#xff0c;主要遵循…

作者头像 李华