3. 传感器基础与接口:常见传感器类型与通信协议详解
大家好,我是你们的老朋友。今天我们来聊聊嵌入式多传感器融合里最基础、也最绕不开的一环——传感器本身和它们怎么跟主控“说话”。
说实话,我见过太多项目,算法写得天花乱坠,最后栽在传感器数据读不上来、或者读出来全是噪声。嗯,这章我们就来把这些坑填平。
3.1 常见传感器类型:各怀绝技的“侦察兵”
一个多传感器融合系统,说白了就是一群不同专长的传感器在协同工作。我习惯把它们分成四类:
3.4.1 IMU(惯性测量单元)
IMU 是“闷声干大事”的典型。它包含加速度计和陀螺仪,有的还带磁力计。加速度计测的是比力(包含重力),陀螺仪测的是角速度。
我个人习惯:在无人机项目里,IMU 的数据更新率我一般设到 400Hz 以上。低于 200Hz,姿态解算就会明显滞后。
3.4.2 摄像头
摄像头是信息量最大的传感器,没有之一。它输出的是图像帧,本质上是二维光强分布。但要注意,它没有直接的深度信息。
你想想看,一个 640x480 的灰度图,一帧就有 307200 个像素点。如果跑 30fps,每秒要处理 9MB 数据。这对嵌入式平台是个不小的挑战。
3.4.3 激光雷达(LiDAR)
激光雷达直接输出距离信息,精度高、抗干扰强。单线雷达常用于避障,多线雷达(如 16线、32线)用于建图。
我记得第一次调 16 线激光雷达时,被它的点云数据量吓了一跳——每秒 30 万个点。用 UART 传?想都别想。必须上以太网或 USB。
3.4.4 超声波传感器
超声波是“老黄牛”型传感器。成本低、功耗小,但精度一般,而且有盲区(通常 2-3cm 以内测不准)。
我一般用它做近距离辅助测距,比如机器人离墙 20cm 以内时,用超声波补激光雷达的盲区。
3.2 通信协议:传感器与主控的“语言”
传感器再好,数据传不出来也是白搭。嵌入式里最常用的三种协议:I2C、SPI、UART。我一个个说。
3.2.1 I2C(Inter-Integrated Circuit)
I2C 是两线制:SCL(时钟线)和 SDA(数据线)。支持多主多从,但速度偏慢——标准模式 100kHz,快速模式 400kHz,高速模式 3.4MHz。
适用场景:IMU、温度传感器、气压计这类数据量小、更新率不高的器件。
代码示例:读取 MPU6050(IMU)的加速度计数据
// I2C 读取 MPU6050 加速度计 X 轴高字节
uint8_t reg_addr = 0x3B; // ACCEL_XOUT_H 寄存器地址
uint8_t data[2];
HAL_I2C_Mem_Read(&hi2c1, 0xD0, reg_addr, I2C_MEMADD_SIZE_8BIT, data, 2, 100);
int16_t accel_x = (data[0] << 8) | data[1];
3.2.2 SPI(Serial Peripheral Interface)
SPI 是四线制:MOSI、MISO、SCLK、CS(片选)。全双工,速度可以跑到几十 MHz。我常用它接高速 ADC、显示屏、SD 卡。
为什么我偏爱 SPI?因为它没有 I2C 那种“应答”机制,数据流是连续的。在需要高速读取大量数据时(比如摄像头原始数据),SPI 是首选。
代码示例:SPI 读取 LSM6DS3(IMU)的 WHO_AM_I 寄存器
uint8_t tx_data = 0x8F; // 读命令 + 寄存器地址 0x0F
uint8_t rx_data = 0;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); // 拉低片选
HAL_SPI_TransmitReceive(&hspi1, &tx_data, &rx_data, 1, 100);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); // 拉高片选
// rx_data 应为 0x69,表示 LSM6DS3 正常
3.2.3 UART(通用异步收发器)
UART 是异步串口,只需要 TX 和 RX 两根线。速度一般从 9600bps 到 115200bps,高的也能到 1Mbps 以上。
我最常用的场景:调试日志输出、GPS 模块、某些低端激光雷达。
UART 有个好处——硬件简单,几乎所有的 MCU 都有。但坏处也明显:没有时钟线,双方必须约定好波特率,而且一帧只能传 5-8 位数据。
代码示例:UART 发送字符串
char msg[] = "Hello from STM32\r\n";
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 1000);
3.3 协议对比与选型建议
我整理了一张表,方便你快速决策:
| 协议 | 线数 | 速度 | 全双工 | 多设备 | 典型应用 |
|---|---|---|---|---|---|
| I2C | 2 | ~3.4MHz | 否 | 是(地址寻址) | IMU、温湿度、气压计 |
| SPI | 4+ | ~80MHz | 是 | 是(片选) | 高速 ADC、显示屏、SD 卡 |
| UART | 2 | ~1Mbps | 是 | 否(点对点) | GPS、调试口、蓝牙模块 |
我的选型口诀:
- 数据量小、设备多 → I2C
- 数据量大、要高速 → SPI
- 简单、距离远、点对点 → UART
3.4 多传感器融合中的接口资源规划
最后聊点实战的。一个典型的融合系统可能同时挂:IMU(I2C)、激光雷达(UART 或 SPI)、摄像头(DCMI 或 SPI)、超声波(GPIO 模拟或 UART)。
你想想看,MCU 的外设资源是有限的。我见过有人把 3 个 I2C 设备挂到同一个总线上,结果因为地址冲突,死活读不到其中一个。后来我建议他用 I2C 多路复用器(如 TCA9548A),才解决。
- 优先用硬件外设(硬件 I2C/SPI/UART),别用 GPIO 模拟,除非资源实在不够。
- 高速传感器(如摄像头)独占一个 SPI 或 DCMI 接口。
- 低速传感器(如温湿度)可以共享 I2C 总线,但注意地址不能冲突。
- UART 尽量用 DMA 接收,避免中断频繁打断主循环。
嗯,这一章的内容就到这里。传感器接口这块,说白了就是“选对协议、配好资源、避开坑”。下一章我们会深入讲传感器数据的时间同步问题——那可是多传感器融合里最容易出幺蛾子的地方。