• 设备间数据通信 —— 串行外设接口(SPI)协议


    设备间通信

    两个设备或者多个设备之间通信时,需要有一份共同遵守的协议,避免鸡同鸭讲。

    常见的通信协议有:SPI、USB、UART、I2C、CAN[1][2]。

    图 1:不同的设备间通信协议

    不同的协议是为了满足特定场景的要求而制定的,而不是为了好玩。因此应该分析特定应用的要求,并选择合适的协议。

    SPI 协议

    使用 SPI 协议的场景是全双工、同步传输、一主多从、线少、高速率。

    以下是使用 SPI 协议通信的设备群:

    图 2:SPI 一主多从

    从图中可以看出一对设备通过 SPI 协议进行通信需要四条线。SPI 四条线分别是:

    • 片选信号线(CS,Chip Select):选设备
    • 主输出从输入数据线(MOSI):传数据
    • 从输出主输入数据线(MISO):传数据
    • 时钟信号线(SCK,Serial Clock):提供采集数据的时机

    数据传输线

    由于使用同步传输,所以传输一个字节的 8 位二进制不需要八条导线,只需要一条线分 8 个时钟发送就行了。下文的时钟信号线部分会再次提到。

    另外由于要支持全双工,即一次传输过程中主设备传输数据到从设备的同时,从设备也可以传输数据到主设备,因此需要两条传输方向不同的线 MOSI(Master Out/Slave In) 和 MISO(Master In/Slave Out)。如下图:

    图 3:全双工。蓝色线表示主设备输出,红色线表示从设备输出。

    从图 3 可以看出,单向传输的线连接了多个从设备。

    注意这里的接线方式:主设备的 MOSI 接从设备的 MOSI,主设备的 MISO 接从设备的 MISO。

    此时我们有了疑问:这些从设备都会同时接收数据吗?多个从设备同时发送数据给主设备岂不是冲突了?

    片选信号线

    主设备会通过控制从设备的 CS 引脚来激活从设备。上面说过从设备的 CS 引脚为低电平的时候,从设备被激活。

    图 4:片选信号线

    下图表示从设备被激活后传输数据(NSS 是 CS 引脚的另一个称呼):

    图 5:拉低片选线后才开始传输数据

    红框部分表示持续激活从设备,以及采集数据。

    注意,主设备用 I/O 线连接到从设备的片选信号线上。

    时钟信号线

    时钟信号线提供读取数据信号的时机。时钟信号由主设备提供给从设备。

    图 6: 时钟信号(中间波浪线表示省略 N 个信号)

    时钟线的作用是提供高低电平的变化作为数据采样的信号。根据不同的模式,可以是从高到低的时候采样,也可以是从低到高的时候采样。

    SPI 协议有四种通信模式,分别由 CPOL(时钟极性)和 CPHA(时钟相位)来控制。也就是选择采样的时机。

    CPOL(Clock POLarity) 表示时钟空闲时的电平。0 为低电平,1 为高电平。如下图表示 CPOL = 0。

    图 7:空闲的 SCK 为低电平,即 CPOL 为 0 的情况

    CHPA(Clock PHAse) 表示数据有效的时刻的相位,或者说边沿(Edge)。边沿指的是电平变化的时刻,有两种类型:上升沿(Rising Edge)和下降沿(Falling Edge)。0 表示处于第一个边沿类型的时刻数据有效(进行采样),1 表示处于第二个边沿类型的时刻数据有效(进行采样)。

    图 8:上升沿和下降沿

    下图标出了采样的时机:

    图 9:工作在(0,1)模式的数据采样

    四种模式用下表列出:

    SPI 通信模式 CPOL CPHA 特点
    0 0 0 时钟空闲时保持低电平,工作时在上升沿从输入引脚采样,在下降沿改变输出引脚的数据
    1 0 1 时钟空闲时保持低电平,工作时在下降沿从输入引脚采样,在上升沿改变输出引脚的数据
    2 1 0 时钟空闲时保持高电平,工作时在下降沿从输入引脚采样,在上升沿改变输出引脚的数据
    3 1 1 时钟空闲时保持高电平,工作时在上升沿从输入引脚采样,在下降沿改变输出引脚的数据

    注:两个通信的设备要配置为同一个模式才能正常通信。

    通信双方采样的时机是一致的,改变输出的时机也是一致的。不然 A 在采样的时候,B 把输出改了,那 A 得到的数据可能是修改前的数据也可能是修改后的数据,就乱了。

    如何确保主从处于同一模式?应该以从设备的模式为准,再配置主设备的模式。从设备的模式有两种情况[3]:

    • 从设备的 SPI 模式由硬件决定,已经被固定
    • 从设备有 SPI 控制器,则 SPI 模式由软件决定,可配置

    在模式相同且片选信号线拉低时,开始通信。通常芯片内部的 SPI 控制器会自动控制在 8 次取样后停止通信,也就是一次传输 8 bit,即一个字节。但也可以使用 I/O 线模拟片选信号,这样一次可以传送多个字节[4]。

    图 10:工作在(0,1)模式的数据采样

    图 10 中的 MSB 和 LSB 表示最高权重位(Most Significant Bit)和最低权重位(Least Significant Bit)[5]。权重指的是对这个数值影响程度高,例如十进制的万比千的权重高。

    一个字节,即 8 位二进制数据可以从最高位开始发送,也可以从最低为开始发送。

    举个例子:

    一个字节的数据:1000 0000

    MSB - - - - - - LSB
    1 0 0 0 0 0 0 0

    从最高位开始发送就是先发 1。

    如果通信双方没有达成一致,则接收者得到的数据和发送者的数据的含义不一致。不过这个通常不需要我们配置。

    总结

    如果要用到 SPI 协议,需要接四条线。

    • 主设备的 MISO 接从设备的 MISO
    • 主设备的 MOSI 接从设备的 MOSI
    • 主设备的 SCK 接从设备的 SCK
    • 主设备任选一个 I/O 接从设备的 CS

    主设备在编程的时候需要配置与从设备相同的 SPI 模式。

    主设备在编程的时候需要配置第一位(First Bit)[6]先从 MSB 开始发还是 LSB 开始发。从设备会规定第一位是 MSB 还是 LSB。

    参考:

    [1]: https://zhuanlan.zhihu.com/p/47925844 (常见硬件通信协议介绍)
    [2]: https://blog.csdn.net/heda3/article/details/89053635 (IIC、SPI、UART、USART、USB、CAN等通讯协议原理及区别)
    [3]: https://blog.csdn.net/u013165704/article/details/81076890 (SPI 接口配置)
    [4]: https://blog.csdn.net/qq_25814297/article/details/86190106 (SPI通讯有单字节模式和多字节连续模式)
    [5]: https://www.cnblogs.com/shuaifeng/archive/2009/12/23/1630195.html (MSB与LSB)
    [6]: https://www.stmcu.org.cn/module/forum/thread-627137-1-1.html ([分享] SPI原理超详细讲解---值得一看)
    
    知识共享许可协议
    本文采用知识共享署名 2.5 中国大陆许可协议进行许可。欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 schaepher(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言

  • 相关阅读:
    Linux 显示当前时间
    Jenkins 更改工作目录;
    Jenkins 编译 .net 项目
    Jenkins 通过 maven 构建编译 JAVA 项目环境
    Jenkins
    Zatree
    Zabbix 邮件报警示例
    Zabbix 短信报警示例
    Linux 检测出口IP地址
    数据结构与算法面试题80道(4)
  • 原文地址:https://www.cnblogs.com/schaepher/p/14521055.html
Copyright © 2020-2023  润新知