1. 从理论到实战:为什么极性与相位是SPI通信的“灵魂”?
上一篇文章我们聊了SPI通信的基本流程和四种工作模式,你可能已经知道了CPOL和CPHA这两个参数决定了模式。但很多朋友在实际动手配置时,还是会犯迷糊:为什么我的STM32和Flash芯片就是连不上?为什么示波器上看波形都对,但数据就是错的?我刚开始玩嵌入式那会儿,也在这上面栽过跟头,后来发现,问题十有八九出在极性和相位的配置上。
你可以把SPI通信想象成两个人(主设备和从设备)在打拍子传球。时钟极性CPOL,决定了“拍子空闲时的手势”——是手举在空中(高电平)还是放在下面(低电平)。而时钟相位CPHA,决定了“在拍子的哪个瞬间完成传接球动作”——是在拍子响起的瞬间(第一个边沿)还是拍子落下后的瞬间(第二个边沿)。这两个参数如果没对上,就像两个人一个在拍手时传球,一个在拍手后接球,球肯定就掉地上了。
在实际项目中,你几乎不会遇到一个芯片的Datasheet上写着“请使用SPI通信”,它一定会明确告诉你需要配置成 “Mode 0”、“Mode 3” 或是直接给出CPOL和CPHA的值。比如,常见的NOR Flash芯片W25Q64通常使用Mode 0或Mode 3,而一些传感器如MPU6500则可能使用Mode 3。如果你不按它的规矩来,通信就无法建立。所以,理解并熟练配置CPOL和CPHA,是打通SPI设备任督二脉的关键一步。这篇文章,我就带你抛开理论图表,直接上手代码,看看在STM32和嵌入式Linux这两种最典型的场景下,如何玩转这两个参数,并分享一些我踩过坑后才悟出来的模式选择技巧。
2. 深入核心:CPOL与CPHA的硬件级行为剖析
在写代码之前,我们有必要再深挖一层,看看CPOL和CPHA在信号电平上到底是如何表现的。这能帮你真正看懂示波器波形,而不是对着代码瞎猜。
时钟极性CPOL,它定义的是SCLK线在非活跃时期(即片选CS有效但数据传输尚未开始,以及两个数据传输周期之间)的状态。当CPOL=0时,SCLK在空闲时为低电平;当CPOL=1时,空闲时为高电平。这个“空闲状态”是你的基准线。时钟相位CPHA,定义的是数据采样(捕获)的时刻。但这里有个关键细节容易混淆:CPHA并不是简单地指定上升沿或下降沿采样,而是指定第几个时钟边沿作为数据采样点。
当 CPHA=0 时,数据在第一个时钟边沿被采样(对于主设备和从设备的接收端而言)。同时,数据的输出(对于发送端而言)则在第一个时钟边沿之前就已经稳定了。换句话说,发送方要提前准备好数据。当 CPHA=1 时,数据在第二个时钟边沿被采样。数据的输出则在第一个时钟边沿发生变化。
让我用更生活化的方式解释一下:假设你和朋友约定,在“点头-抬头”这个动作周期内传递纸条。CPHA=0意味着,你在他刚开始点头的瞬间(第一个边沿)就把纸条塞过去,他也在同一瞬间接住。而CPHA=1意味着,你在他点头完成、开始抬头的瞬间(第二个边沿)塞纸条,他也在同一瞬间接住。CPOL则决定了起始动作是“头原本低着然后抬起”(CPOL=0,空闲低,第一个边沿是上升沿),还是“头原本抬着然后低下”(CPOL=1,空闲高,第一个边沿是下降沿)。
为了更直观,我整理了一个表格,结合波形图来看会更清楚:
| 模式 | CPOL | CPHA | 时钟空闲状态 | 数据采样时刻 (对接收方) | 数据建立时刻 (对发送方) | 常见应用场景 |
|---|---|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | SCLK上升沿 |

—— 极性与相位配置实战及模式选择技巧&spm=1001.2101.3001.5002&articleId=154598266&d=1&t=3&u=3628ee6d858946f0b0f41b28137be2cb)
267

被折叠的 条评论
为什么被折叠?



