# SPI 协议笔记 (基于 AD/DA 芯片 XPT2046) 坑惨我了
# 被坑经历
我买的 51 似乎是新版的 上面的 ADDA 芯片不是视频里面说的 PCF8591 视频里面是以 PCF8591 来讲解的 而那个芯片正好也是走的 IIC 协议 所以视频里面改一改通讯地址就能用了 我就一直抱着我的单片机学啊学啊 一直都不行 在网上找了很多例程都没办法用 (因为都是找的 PCF8591 的代码 当然用不了) 所以这个问题就被搁置了 之后后面有一天我无意中看到了我的单片机上面的 AD/DA 芯片特别小 感觉有些不对劲 拿出来和同学的一比较 才发现自己的那个芯片是 XPT2046 走的是 SPI 协议 这才能继续进行下去 (51 单片机结束的一个工程需要利用到 AD 转换 必须得用到 ADDA)
# SPI 协议
和 IIC 协议类似 SPI 协议也是用于不同模块之间的通讯 但是 SPI 用了四根线 分别是 SCLK CS MOSI (master output slave input) 和 MISO (master input slave output)
其中 SCLK 为时钟节拍 其电平的变化使得每一位的数据被传送出去 CS 为使能端 当 CS 为低电平时 SCLK 才能起作用 MOSI 和 MISO 分别对应着主发从收和主收从发 默认情况下 SCLK 空闲状态为低电平 此时将数据送给 MOSI (或 MISO) 再将 SCLK 电平拉高 此时数据便发出去了 此外 SPI 由高位到低位的顺序传送数据
其实在 SPI 协议中 SCLK 空闲时的电平、在第几个跳变沿发送数据都是可以自定义的 就我目前看来 如果不是特殊项目对数据传输的时效性有很高要求的话 使用默认情况就可以满足要求了
在 SPI 协议中 时钟极性 (CPOL) 就是用来定义 SCLK 空闲时候的电平的
当 SPOL = 0 时 SCLK 空闲时的电平为 0
当 SPOL = 1 时 SCLK 空闲时的电平为 1
时钟相位 (CPHA) 是用来定义采取第几个跳变沿时的数据
当 CHPA = 0 时 采用第一个跳变沿时候的数据
当 CHPA= 1 时 采用第二个跳变沿时候的数据
由 CHPA 和 CPOL 的变化 也就产生了四种模式
| 模式 | CPOL | CHPA | 功能 |
|---|---|---|---|
| Mode 0 | 0 | 0 | SCLK 低电平空闲 且在第一个跳变沿时 (上升沿) 采集数据 |
| Mode 1 | 0 | 1 | SCLK 低电平空闲 且在第二个跳变沿时 (下降沿) 采集数据 |
| Mode 2 | 1 | 0 | SCLK 高电平空闲 且在第一个跳变沿时 (下降沿) 采集数据 |
| Mode 3 | 1 | 1 | SCLK 高电平空闲 且在第二个跳变沿时 (上升沿) 采集数据 |

因为 SPI 采用了两根数据线 所以使得收发数据都变得很容易 以下为 XPT2046 的通讯过程
- 使能端 (CS) 电平降低
- 主发从收:发送从机 (XPT2046) 地址
- 从发主收:主机接收来自从机的一字节的数据
- 使能端 (CS) 电平升高
与 DHT11 的通讯比起来 SPI 不用做数据校验 与 IIC 协议比起来 SPI 不用响应应答信号 在编写过程中非常方便 但是相对来说还是缺少了数据的稳定性 因为它并未考虑到主机未接收时的措施
# 完整代码如下
1 | /***********DIN 对应 MOSI, DOUT 对应 MISO**********/ |
