1. SPI协议基础:从起源到全双工通信
各位同学,咱们今天正式开始聊SPI。说实话,SPI这个协议在嵌入式领域太常见了,几乎每个工程师都会用到。但真正把它吃透的人,我觉得并不多。
先说说SPI的起源。上世纪80年代,Motorola公司推出了一款叫MC68HC11的微控制器。当时他们需要一种简单、高速的串行通信方式,用来连接外设芯片。于是SPI(Serial Peripheral Interface)就诞生了。我最早接触SPI是在做一款工业传感器采集板的时候,那时候刚入行,看着四根线一头雾水——怎么四根线就能实现全双工通信?后来才明白,这设计其实非常巧妙。
1.1 四线制功能详解
SPI总线一共就四根信号线,咱们一个一个说清楚。
| 信号线 | 全称 | 方向 | 功能 |
|---|---|---|---|
| SCLK | Serial Clock | 主机→从机 | 时钟信号,由主机产生,决定通信速率 |
| MOSI | Master Out Slave In | 主机→从机 | 主机发送数据给从机 |
| MISO | Master In Slave Out | 从机→主机 | 从机发送数据给主机 |
| CS | Chip Select | 主机→从机 | 片选信号,低电平有效,选中对应从机 |
这里有个关键点:SCLK永远由主机控制。从机只能被动接收时钟,不能主动产生。我在项目中遇到过有人把从机也接了晶振,以为能自己产生时钟——结果通信完全乱套。记住,SPI是主从架构,时钟主权在主机手里。
核心要点:MOSI和MISO是两条独立的数据线,这是SPI能实现全双工通信的物理基础。不像I2C只有一根数据线,半双工来回切换。
1.2 全双工通信原理
全双工,说白了就是同时收发。SPI怎么做到的?
你看,MOSI和MISO是两条独立的物理线路。主机通过MOSI发数据给从机的同时,从机也能通过MISO发数据给主机。这两件事在同一个时钟周期内完成,互不干扰。
具体工作机制是这样的:
- 主机拉低CS,选中从机
- 主机产生SCLK时钟,每个时钟周期传输1位数据
- 在时钟的某个边沿,主机通过MOSI发送1位,从机通过MISO发送1位
- 在另一个边沿,双方采样对方发送的数据
- 8个时钟周期后,完成1字节的交换
我刚开始做SPI驱动时,总以为主机发一个字节,从机才会回一个字节。后来调试一个AD转换器才发现——SPI的收发是同时发生的。你发0x55的同时,从机也在发数据给你。如果你只关心发送,那接收到的数据就丢了。
实战技巧:很多SPI从机要求主机先发送一个命令字节,然后从机才会返回数据。这时候你发送命令字节时,接收到的数据是无效的;发送完命令后,再发送一个"哑字节"(通常是0x00或0xFF),才能读到真正的数据。这个哑字节就是用来产生时钟的。
1.3 SPI通信的时序基础
SPI的时序其实不复杂,但有两个参数特别重要:时钟极性(CPOL)和时钟相位(CPHA)。咱们先简单提一下,后面会有专门章节详细讲。
- CPOL:决定SCLK空闲时的电平。CPOL=0时空闲为低,CPOL=1时空闲为高。
- CPHA:决定数据在哪个时钟边沿采样。CPHA=0时在第一个边沿采样,CPHA=1时在第二个边沿采样。
这两个参数组合起来,就是SPI的四种模式。我见过不少工程师在这上面栽跟头——从机手册上写的是Mode 0,主机配置成了Mode 3,结果数据全是错的。
避坑指南:我曾经调试一款MEMS加速度计,死活读不到正确的ID寄存器。折腾了两天,最后发现是CPHA配反了。从机要求CPHA=1,我默认配成了CPHA=0。所以拿到一个新器件,第一件事就是看数据手册里的时序图,确认CPOL和CPHA。
1.4 SPI知识体系总览
下面这张图把SPI协议的核心知识点串起来了。你想想看,从物理层到应用层,SPI其实就这几个关键点。
嗯,这张图把SPI的知识结构理清楚了。咱们这门课会按照这个脉络,一层一层往下挖。物理层搞明白四根线怎么接,数据链路层搞明白全双工怎么玩,时序层搞明白CPOL/CPHA怎么配,应用层搞明白多设备怎么级联。
我个人觉得,SPI最迷人的地方就是它简单但灵活。四根线,没有复杂的协议栈,没有地址仲裁,想怎么用就怎么用。但也正因为灵活,才容易出问题。后面的章节,咱们会一个一个坑踩过去。