SPI菊花链原理和配置

一、概述

在一个主机和多个从器件的典型 SPI 系统中, 通常采用专门的片选信号来寻址从器件。随着从器件数量不断增加, 片选线也随之增多。 这种情况将给电路板布板带来很大的挑战。

一个布板方法就是采用菊链结构。 本文详细讲述了 SPI 系统的菊链配置, 并展示如何使用软件向串联从器件发送命令。

标准 SPI™/QSPI™/MICROWIRE™兼容微控制器通过 3 线/4 线串口与从器件通信。典型接口包括片选信号(/CS)串行时钟(SCLK) 数据输入信号(DIN) , 有时还会有数据输出信号(DOUT) 。如同 I² C 系统中一样, 单独寻址的器件能轻易的和总线上的其它器件通信。

二、基本串行通信接口

很多 SPI 器件并不是单独寻址的。 因此, 这些器件和总线上其它单个器件通信时, 就需要进行额外的硬件或者软件处理。 图 1 所示是一个微控制器和多个从器件通信的系统。

在上述系统中, 微控制器通过一个串行时钟输出(SCLK) 和一个主机输出/从机输入(MOSI) 信号线向各从器件发送命令。 主机为每个器件分配了一个独立的片选信号(/SS_) , 从而实现各个从器件的独立寻址。 由于所有从器件共享同一个时钟和数据线, 只有/CS 输入变低的从器件才会应答串行时钟和数据线。 当从器件数目较少时, 该系统较易实现。 如果系统中从器件数较多, 微控制器需要提供和从器件一样多的/SS_输出, 这种结构就增加了硬件和布板的复杂程度。

菊链方法

硬件空间方面的限制往往会使图 1 所示的电路无法实现或难以实现。可采用菊链法替代实现串行接口。 图 2 是一个有 N 个从器件的菊链系统结构。

 采用一个/SS (或者/CS) 信号控制所有从器件的/CS 输入; 所有从器件接收同一个时钟信号。只有链上的第一个从器件(SLAVE 1) 从微控制器直接接收命令。 其他所有从器件都从链上前一个器件的 DOUT 输出获得其 DIN 数据。要保证菊链正常工作, 每一个从器件就必须能在给定的命令周期内(定义为每一个命令所需的时钟数) 从 DIN 引脚读入命令, 而在下一个命令周期从 DOUT 引脚输出同样的命令。 显然,从 DIN 到 DOUT 会有一个命令周期的延迟。 另外, 各个从器件只能在/CS 的上升沿执行写入的命令。 这意味着只要/CS 保持低电平, 从器件将不会执行命令, 并且会在下一个命令周期将命令通过 DOUT 引脚输出。 如果在给定命令周期之后/CS 变高, 所有从器件将立即执行写入 DIN 引脚的命令。 如果/CS 变高, 数据将不会从 DOUT 输出, 这就使得链上每个从器件可以执行不同的命令。只要菊链的这些要求能够满足, 微控制器只需三个信号(/SS、SCK 和 MOSI)就能控制网络上的所有从器件。

如何实现菊链

在菊链系统中(图 2) , SLAVE 1 从微控制器直接接收数据。 该数据在时钟驱动下进入 SLAVE 1的内部移位寄存器。 只要/CS (或/SS) 仍然保持低电平, 该数据将通过 SLAVE 1 的 DOUT 引脚输出。 SLAVE 1 的 DOUT 引脚接至 SLAVE 2 的 DI 引脚, 因此当数据通过 SLAVE 1 的 DOUT 引脚端输出时, 同时也被同步移入 SLAVE 2 的内部移位寄存器。 同理, 当 SLAVE 2 接收来自SLAVE 1 的数据的时候, 微控制器可同时向 SLAVE 1 发送另一个命令。 该新命令将覆盖 SLAVE1 移位寄存器中原来的数据。 只要/CS 保持为低, 数据会在整条菊链上传递, 直到每一个从器件都接收了相应的命令。 存储在每一个从器件移位寄存器中的命令将在/CS 的上升沿执行。下面例子使用 MAX5233 和 MAX5290 构成菊链。

电路图范例#1

图 3 给出的菊链结构中连接了 3 个 MAX5233。 MAX5233 为双路、 10 位 DAC (包含两个 DAC 通道, 通道 A 和 B) 。 将 RSTV 接至 VDD, 模拟输出的上电状态被设置到中点。

 图 4 给出了将 IC1 (A1 和 B1) 、 IC2 (A2 和 B2) 和 IC3 (A3 和 B3) 的输出分别设为零点、 中点和满刻度的命令序列图。 在这个例子中, 使用了以下的命令:

  • 0x7FF8—将满刻度数据加载到 IC3 DAC 寄存器, 并将两路输出(A3、 B3) 设置到满刻度
  • 0x7000—将满刻度数据加载到 IC2 DAC 寄存器, 并将两路输出(A2、 B2) 设置到中点
  • 0x6000—将满刻度数据加载到 IC1 DAC 寄存器, 并将两路输出(A1、 B1) 设置到零点

 

 在第一个命令周期(16 个 SCLK 脉冲序列) , 将 0x7FF8 载入 IC1 的移位寄存器。 当/CS 保持低电平, 这一数据将在 IC1 内传递, 并且在下一个命令周期内通过 DOUT1 输出。 在第二个命令周期内, IC1 输出端 DOUT1 上的数据输入到 DIN2, 将 0x7FF8 载入 IC2 的移位寄存器中。 同时, 新的命令 0x7000 将载入 IC1 移位寄存器, 覆盖了前一个命令。第三个命令周期内, 第一个命令 0x7FF8 将载入 IC3 的移位寄存器, 而第二个命令 0x7000将载入 IC2 的移位寄存器, 同时 IC1 将接收到新的命令 0x6000。 此时, 三个 IC 都从菊链上接收到命令并存储在他们的移位寄存器中。 一旦/CS 变高, 将执行已存储的命令; A1 和 B1被设为零点、 A2 和 B2 被设为中点、 A3 和 B3 被设为满刻度。

图 5 给出了更为复杂的命令序列。 在这个例子中, 使用以下的命令(更多详细信息, 请参考MAX5233 数据资料) :

  • 0x3FF8—将满刻度数据加载到输入寄存器 A, 不改变 DAC 寄存器和输出
  • 0x3000—将中点数据加载到输入寄存器 A, 不改变 DAC 寄存器和输出
  • 0x2000—将零点数据加载到输入寄存器 A, 不改变 DAC 寄存器和输出
  • 0xBFF8—将满刻度数据加载到输入寄存器 B, 不改变 DAC 寄存器和输出
  • 0xB000—将中点数据加载到输入寄存器 B, 不改变 DAC 寄存器和输出
  • 0xA000—将零点数据加载到输入寄存器 B, 不改变 DAC 寄存器和输出
  • 0x0000—空操作

在第一个三命令周期内, 菊链上三个 IC 中的各个器件的移位寄存器军接收到一条命令。IC1、IC2、 IC3 接收到的命令分别为 0xB000、 0xBFF8 和 0xBFF8。 器件将在/CS 的上升沿执行这些命令(第一次执行) 。 执行完之后, IC1、 IC2、 IC3 的输入寄存器 B 中分别加载了中点、 满刻度和满刻度的数据。 此时, 由于各 IC 的 DAC 寄存器 B 保持不变, 因此 B1、 B2、 B3 均未改变。 

在接下来的三命令周期内, 每个 IC 的移位寄存器中均写入了仅向输入寄存器 A 加载数据的命令。 DAC 寄存器 A 和输出保持不变。 在/CS 的上升沿, IC1、 IC2、 IC3 的输入寄存器 A 分别加载了满刻度、 零点和中点数据。 此时, 由于只更新了输入寄存器 A 而不是 DAC 寄存器 A,因此 A1、 A2、 A3 均保持不变。

在第二次执行命令之后, 硬件/LDAC 命令(驱动/LDAC 为低) 将输入寄存器中的数据加载到相应的 DAC 寄存器中。 这样, DAC 的输出就被刷新为相应的 DAC 寄存器中的数据。 A1、 B2 和B3 变为满刻度。 A2 变为零点而 A3 仍为中点状态。

在第三个命令周期, IC2 和 IC3 接收了空操作命令(0x0000) , 而 IC1 接收 0xA000 命令, 将零点数据加载到 IC1 的输入寄存器 B。 第三次执行命令之后, 所有的输出仍旧没有改变。

在第四个命令周期内, IC1 和 IC2 接收空操作命令, 而 IC3 接收到 0x3FF8 命令。 第四次执行命令之后, IC3 的输入寄存器 A 加载满刻度数据。 另一个硬件/LDAC 命令将输入寄存器的数据加载到相应 DAC 寄存器。 这将使 B1 从中点变为零点, A3 从中点变为满刻度。 其他的输出仍旧不变。

表 1. 命令序列 B 中, 上电后以及执行硬件/LDAC 命令后, IC1、 IC2 和 IC3 的输出状态

Analog Output State of Output
Name After Power-Up
(RSTV = VDD)
First Hardware
Active-Low LDAC
Second Hardware
Active-Low LDAC
IC1 A1 Midscale Full scale Full scale
B1 Midscale Midscale Zero scale
IC2 A2 Midscale Zero scale Zero scale
B2 Midscale Full scale Full scale
IC3 A3 Midscale Midscale Full scale
B3 Midscale Full scale Full scale

电路范例#2

图 6 给出的菊链结构中有三个 MAX5290 (双路 12 位 DAC) 。 将 PU 接至 DVDD, 则上电时模拟输出设置为满刻度。 MAX5290 没有专用于菊链的数字输出。 因此, 需通过串口将两个 UPIO (用户可编程输入/输出) 引脚中的任意一个编程设置为 DOUTDC_模式。 更多详细信息请见MAX5290 数据资料。

图 7 给出了命令序列示例, 使用了以下的命令(更多详细信息请见 MAX5290 数据资料) 。

  • 0xDFFF—将满刻度数据加载到所有输入寄存器和 DAC 寄存器, 刷新 DAC 的 A 和 B 输出
  • 0xD800—将中点数据加载到所有输入寄存器和 DAC 寄存器, 刷新 DAC 的 A 和 B 输出
  • 0xD000—将零点数据加载到所有输入寄存器和 DAC 寄存器, 刷新 DAC 的 A 和 B 输出
  • 0xE400—将 DAC 的 A 和 B 输出置于关断模式
  • 0xE40F—使 DAC 的 A 和 B 输出跳出关断模式
  • 0xFFFF—空操作 

器件在/CS 上升沿时执行已经加载到每个器件移位寄存器中的命令。 第一次执行命令后, 所有 DAC 输出均刷新。 IC1 的 DAC 输出为零点, IC2 的 DAC 输出为中点, 而 IC3 的 DAC 输出为 满刻度。第二个命令周期时, 执行命令 0xE400, IC2 的 DAC 的 A 和 B 输出都进入关断模式。 IC1 和 IC3由于执行空操作命令而不受影响。 第三个命令周期后, IC1 的输出变为满刻度, IC3 的输出变为零点。 而 IC2 的输出仍处于关断模式, 其内部输入寄存器和 DAC 寄存器数据已被刷新。在最后的命令周期, IC2 恢复正常工作模式, 所有输出变为满刻度。

表 2. 命令序列示例中, 上电后和执行命令后, IC1、 IC2、 IC3 的输出状态

Analog Output State of Output
Name After Power-Up
(RSTV = VDD)
After First
Excution
After Second
Excution
After Third
Excution
After Fourth
Excution
IC1 A1 Full scale Zero scale Zero scale Full scale Full scale
B1 Full scale Zero scale Zero scale Full scale Full scale
IC2 A2 Full scale Midscale Shutdown Shutdown Full scale
B2 Full scale Midscale Shutdown Shutdown Full scale
IC3 A3 Full scale Full scale Full scale Zero scale Zero scale
B3 Full scale Full scale Full scale Zero scale Zero scale