SPI读出255?别急着换芯片——那是你的采样边沿正在“踩空”
你有没有遇到过这样的场景:
刚把ADS1118接上i.MX6ULL开发板,C++程序一调read(),四字节全返回0xFF 0xFF 0xFF 0xFF;
示波器上看SCLK在跳,CS在拉低,MOSI也在发0x00,可MISO纹丝不动——不是没信号,是它根本没“活”过来;
查电源正常、焊接无虚焊、设备树也写了spi-cpol和spi-cpha……最后发现:从设备只支持Mode 3,而你配成了Mode 0。
这不是驱动bug,不是硬件损坏,更不是Linux内核抽风。
这是SPI总线上最隐蔽、最顽固、也最容易被误判的“时序踩空”——主控在采样,而从设备还没把数据摆上桌。
Mode 0/1/2/3不是编号,是四份互不兼容的通信契约
SPI没有握手,没有ACK,没有重传。它靠的是主从双方对四个关键时间点的绝对共识:
- SCLK空闲时是高还是低?(CPOL)
- 数据在哪一刻被采样?第一个边沿?还是第二个?(CPHA)
- 数据在哪一刻必须已稳定?(Setup time)
- 数据要保持到哪一刻之后?(Hold time)
这四点一旦错位,就像两个人约在火车站见面,却一个按北京时间、一个按东京时间——表面都在动,实则永远擦肩。
我们常以为“Mode 0 = 默认”,但真相是:Mode 0只是Linux内核的默认值,不是世界的默认值。
ADS1118手册第18页清清楚楚写着:“Data is sampled on thefirstSCLK edge, and clock idleslow” → Mode 0。
W25Q32JV手册第9页却写:“Data is sampled on thesecondSCLK edge, clock idleshigh” → Mode 3。
同一根SPI总线上挂两个器件?它们必须用同一套契约——否则你就得为每个设备单独配一条总线,或者用GPIO模拟片选+软件切换Mode(极不推荐)。
📌关键洞察:SPI Mode不是“风格偏好”,而是硬件级硬约束。多数ADC、Flash、Codec芯片的SPI接口逻辑是固化在数字前端里的,烧录进硅片的时序状态机根本不支持动态切Mode </