1. Sensor 基础与硬件接口
各位同学,咱们这门课讲的是 Sensor 寄存器配置与驱动开发。第一节课,我想先聊聊 Sensor 本身。
很多人一上来就盯着数据手册看寄存器,结果越看越懵。为什么?因为你不了解 Sensor 的分类和接口特性。我刚开始做驱动时也犯过这毛病——拿到一个温度传感器,照着手册配完寄存器,读数死活不对。后来才发现,我连它是 I2C 还是 SPI 都没搞清楚。
所以这一章,咱们先把地基打牢。
1.1 Sensor 分类:你面对的是哪种器件?
Sensor 的种类很多,但从驱动开发的角度,我习惯把它们分成三大类:
| 类别 | 典型器件 | 输出信号 | 接口特点 |
|---|---|---|---|
| 环境类 | 温度、湿度、气压、气体 | 数字(I2C/SPI)或模拟 | 数据率低,功耗敏感 |
| 运动类 | 加速度计、陀螺仪、磁力计 | 数字(I2C/SPI) | 需要 FIFO 和中断 |
| 光学类 | 环境光、距离、摄像头 | 数字或 MIPI | 带宽高,时序要求严 |
你想想看,一个温度传感器,每秒读一次就够了。但一个 IMU,可能每秒要输出 1000 组数据。接口选型完全不同。
我的经验: 拿到一个新 Sensor,先看它是「慢速设备」还是「快速设备」。慢速设备优先用 I2C,快速设备优先用 SPI。别问为什么,问就是我在一个项目里用 I2C 接了 6 轴 IMU,结果数据率死活上不去,最后只能改板子。
1.2 I2C 总线协议详解
I2C 是 Sensor 领域最常用的接口。两根线:SCL(时钟)和 SDA(数据)。
它的核心逻辑很简单:
- 起始条件: SCL 高电平时,SDA 从高拉低
- 停止条件: SCL 高电平时,SDA 从低拉高
- 数据传输: 每个时钟周期传 1 位,高位在前
- 应答机制: 每 8 位数据后,接收方拉低 SDA 表示 ACK
写一个 I2C 寄存器,流程是这样的:
// 伪代码:写 Sensor 寄存器 0x10 的值为 0xA5
START
发送设备地址 (0x76 << 1 | 0) // 写操作
等待 ACK
发送寄存器地址 (0x10)
等待 ACK
发送数据 (0xA5)
等待 ACK
STOP
读操作稍微复杂一点,需要先写寄存器地址,再重新发送起始条件,切换为读模式:
// 伪代码:读 Sensor 寄存器 0x10
START
发送设备地址 (写)
等待 ACK
发送寄存器地址 (0x10)
等待 ACK
REPEATED START
发送设备地址 (读)
等待 ACK
读取 1 字节数据
发送 NACK // 告诉 Sensor 我读完了
STOP
注意: 很多 Sensor 的 I2C 地址是可以配置的。比如 MPU6050,AD0 引脚接 GND 时地址是 0x68,接 VCC 时是 0x69。我曾经因为没注意这个,调了整整一个下午。
1.3 SPI 总线协议详解
SPI 比 I2C 快,但线多。四根线:SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)、CS(片选)。
SPI 有四种模式,由时钟极性(CPOL)和时钟相位(CPHA)决定:
| 模式 | CPOL | CPHA | 数据采样边沿 |
|---|---|---|---|
| 模式 0 | 0 | 0 | 上升沿采样 |
| 模式 1 | 0 | 1 | 下降沿采样 |
| 模式 2 | 1 | 0 | 下降沿采样 |
| 模式 3 | 1 | 1 | 上升沿采样 |
SPI 写寄存器通常是这样:
// 伪代码:SPI 写 Sensor 寄存器 0x10 的值为 0xA5
CS 拉低
发送 (0x10) // 寄存器地址,通常最高位为 0 表示写
发送 (0xA5) // 数据
CS 拉高
读操作类似,只是地址的最高位设为 1:
// 伪代码:SPI 读 Sensor 寄存器 0x10
CS 拉低
发送 (0x10 | 0x80) // 地址 + 读标志
接收 1 字节数据
CS 拉高
关键区别: I2C 有设备地址,一条总线上可以挂多个设备。SPI 靠 CS 片选,每个设备需要一根独立的 CS 线。所以 SPI 更适合「少设备、高速度」的场景。
1.4 Sensor 数据手册阅读方法
这是我最想强调的部分。很多工程师拿到数据手册,从头读到尾,结果读到寄存器部分已经忘了前面讲了什么。
我个人的阅读顺序是这样的:
- 先看 Features 和 Applications —— 确认这个 Sensor 能不能满足你的需求
- 再看 Pin Configuration —— 搞清楚每个引脚的功能,特别是电源、地、中断、地址选择
- 然后看 Electrical Characteristics —— 供电电压、工作电流、I2C/SPI 时序参数
- 接着看 Register Map —— 找到你要配置的寄存器,理解每个 bit 的含义
- 最后看 Application Information —— 参考电路和初始化流程
举个例子,假设你拿到一个 BMP280 气压传感器。你翻到 Register Map,看到 0xF4 是控制寄存器:
Register 0xF4 (ctrl_meas)
Bit[7:5] : osrs_t (温度过采样)
Bit[4:2] : osrs_p (气压过采样)
Bit[1:0] : mode (模式: 00=休眠, 01/10=强制, 11=正常)
你想让它以正常模式工作,温度过采样 1 次,气压过采样 1 次。那这个寄存器的值就是:
osrs_t = 001 (1 次)
osrs_p = 001 (1 次)
mode = 11 (正常模式)
结果: 0b00100111 = 0x27
避坑指南: 我曾经在配置一个 Sensor 时,手册上说寄存器默认值是 0x00,但我读出来是 0x80。后来发现是芯片版本不同。所以,永远不要相信默认值,上电后先读一遍确认。
1.5 知识结构总览
下面这张图,把本章的核心知识点串起来了: