串行外设接口(SPI) admin    17/07/12



说明

串行外设接口(SPI)常被用于单片机和小型外围设备之间的通讯,如移位寄存器、传感器、SD卡. 它使用单独的时钟和数据线,以及一个片选信号线。

串口有什么问题?

    一个普通的串行口(有TX和RX信号线的那种),被称为“异步”口(不同步) 由于没时钟线,无法保证通讯双方以相同的步调收发数据。然而电脑通常依赖于一个单一的“时钟” (电脑内部的石英晶体,驱动这个“时钟”),两系统用略有不同的时钟来互相通讯,会带来一些问题。

    要解决这一问题,异步串行连接为每个字节添加了额外的启动和停止位, 以便接收机收到数据时重新“同步”。双方还必须事先约定一致传输速率(如9600比特每秒)。 传输率略有差异是没有问题的,因为接端在每个字节的开始时会重新同步。

异步串口波形

    (顺便说一下,你可能注意到了上图中的“11001010”不等于0x53, 感谢你关注细节。串行协议常常会首先发出的最低有效位,所以最低的位是在左边。低半字节是0011 = 0x3, 上半字节是0101 = 0x5:。)

    异步串行工作得很好,但有需要为每个字节数据增加额外开销(启动和停止位), 并要求由复杂的硬件来实现。另外,你可能已经注意到,在你自己的项目,如果双方没有设置为相同的速度, 接收到的将是垃圾数据。这是因为接收器是在特定的时间点采样的(上图中的箭头)。如果接收器采样的 时间点错了,它会看到错误的数据位。

同步的解决方案

    SPI工作方式略有不同,它是一个“同步”数据总线,这意味着它使用单独的时钟线, 使双方在完全同步。时钟振荡信号,告诉接收机什么时候采样数据线。这可能是在时钟信号的上升沿(低到高) 或下降(高到低),器件的《数据手册》会给出这一选项。当接收器检测到时钟的边缘,它会立即看一下数据 线,读出数据(见下图箭头)。因为时钟是和数据一起发送,其速度并不重要,当然这仍要设备可以操作极限 限制(后面,我们将讨论如何选择适当的时钟边缘和速度)。

替换文本

    ,SPI是如此流行的原因之一是,接收硬件可以是一个简单的 移位寄存器。 相比异步串口的UART(通用异步接收器/发送器)这是一个非常简单(便宜!)的硬件。

接收数据

    你可能会想到,这个用在单向通信的场合,听起来挺棒的, 但是我们如何向相反的方向发送数据呢?这就使事情变得稍微有点复杂了。

    在SPI,只有一方产生时钟信号(通常称为CLK或SCK串行时钟)。 产生时钟的一侧称为“主机”,而另一边是被称为“从机”。只有一个主机(一般是你的单片机), 但可以有多个从机。

    当数据从主机发送从机时,它使用的数据线叫做MOSI(Master Out / Slave In), 如果从机需要发送一个响应给主机,主机会继续产生预定数量的时钟周期,从机将数据传输到第三根信号线上, 这根信号线被称作MISO(Master In / Slave Out)。

替换文本

    注意我们上面的描述中说的“预定”。因为时钟信号总是由主机产生, 它必须预先知道当从机需要返回数据,有多少数据将返回。这点同异步串口不同,异步串口数据可随时向任一方向发送。 在实践中,这不成问题,SPI一般用来同类似传感器一类的设备通讯,如果你发送的命令“读取数据”, 你知道装置总是会向你返回两个字节。(如果你想返一组变长数据,你可以在命令中指定数据的长度,然后一次取回全部数据。)

    注意,SPI是“全双工”(有单独的发送和接收线)的,因此,在某些情况下, 您可以同时发送和接收数据(例如,请求传感器准备一个新的数据的同时读出前面检索的数据)。 如有这可能,您的设备的《数据手册》会描述的。

从机选择(SS)

    还有最后一条信号线需要了解——SS(从机选择)。这个信号告诉从机应该醒来接收/发送数据, 也可用来从多个从机中选择一个通讯目标机。

替换文本

    SS线通常在高电平时,从SPI总线断开从机。(这种逻辑称为“低电平有效”, 一些启动和复位线往往也使用这种逻辑。)要向从机发送数据,先拉低SS线,激活了从机。使用完从机,SS线又被拉高。 对于一个移位寄存器,这相当于“锁存”输入,将接收到的数据锁定到输出线。

    

多个从机

    连接多个从机的SPI总线有两种方式:

  1. 一般来说,每个从机都需要一个单独的SS线。要跟一个特定的从机通讯,就把对应的SS线拉低, 把其余SS线拉高(你不想同时激活两个从机,他们同时驱动MISO线会造成乱码)。 大量从机需要大量SS线;可以使用二进制解码芯片减少所需MCU引脚数。
替换文本
  1. 另外一些场合,可以使用菊花链连接,用前一个设备的MISO(输出)链接下一个设备的MOSI(输入)。 在这种情况下,只需要一个单一的SS线去控制全部从机。
替换文本

    需要注意的是,这种布局中,数据从前一个从机溢出,“流”到下一个从机,所以为了将数据传送到 任何一个从机,你将需要发送足够的数据,来保证数据能达到所有从机。还有,记住, 你最先发送的数据,将“流”向最后的从机。

    这种布局通常用于只有输出的场合,如驱动LED,你不需要接受任何数据回复。 在这些情况下你可以断开主机的MISO线断开。然而,如果数据需要返回到主机,你可以通过闭合菊花链的循环 (在上面的图中蓝线)。注意,从机1的数据将需要通过所有其他从机才能回到主机, 所以一定要有足够时钟数来刷出数据。



0 评论 | 直到2022-05-21 19:37添加评论