045、传感器驱动开发:I2C与SPI通信
一、一次深夜的IMU调试
凌晨两点,示波器探头戳在MPU9250的SCL引脚上,波形干净得像教科书。但读回来的加速度计数据就是不对——X轴永远比Y轴大0.3g,温度漂移曲线像癫痫发作。我盯着逻辑分析仪抓到的I2C时序,突然发现每次读取WHO_AM_I寄存器后,总线会多出一个ACK时钟周期。这个“幽灵ACK”让我浪费了整整一个晚上,最后发现是I2C时钟频率设成了400kHz,而MPU9250的I2C接口在3.3V供电下只能稳定跑200kHz。
传感器驱动开发,说白了就是和时序、寄存器、中断打交道。I2C和SPI是嵌入式世界最常用的两种总线,但很多人只停留在“会调库函数”的层面。今天这篇笔记,咱们就聊聊那些藏在数据手册角落里的坑,以及我踩过之后怎么填平的。
二、I2C:看似简单,实则暗流涌动
2.1 时钟延展——被忽略的“隐形杀手”
很多I2C从设备(比如BMP280气压计)会在处理内部数据时拉低SCL,这叫时钟延展。主设备必须等待从设备释放SCL才能继续通信。但问题来了:如果你的I2C控制器不支持硬件时钟延展(比如某些低端MCU的I2C外设),就得靠软件轮询SCL电平。
踩坑实录:某次用STM32F103的硬件I2C读LSM6DS3,代码在HAL库的HAL_I2C_Mem_Read()里卡死。查了三天,发现是LSM6DS3在读取加速度数据时偶尔会延展时钟,而F103的硬件I2C在时钟延展