该图的“MUX”部分实际上由许多分立的逻辑门组成,它们用于在正确的时间将数据馈入相关的触发器。
这很重要,因为 PISO 移位寄存器需要单独计时并行数据的每一位。这意味着并行输入上的数据在读取时不能更改,同样,大多数实际设计采用缓冲区来保存并行数据。
级联移位寄存器移位寄存器按其处理的位数进行分类,前面插图中显示的那些是 4 位寄存器,而我们今天将使用的两个移位寄存器都是 8 位设备。
如果您需要增加可以使用移位寄存器处理的并行数据量,您可以将其与另一个移位寄存器级联。所以两个 8 位移位寄存器可以支持 16 位,再加一个支持 24 位,等等。
您不需要额外连接到微控制器来级联移位寄存器,因此这是驱动大量 LED 或读取大量开关而不使用大量端口的好方法。
74HC575 & 74HC165 移位寄存器今天我们将使用两个非常常见且容易获得的移位寄存器,即 74HC595 SIPO 和 74HC165 PISO。让我们仔细看看这些芯片。
74HC595——8位串行输入——并行输出该74HC575是一个8级串行移位寄存器,它也具有一个内部存储寄存器。存储寄存器缓冲输出数据并且可以独立于移位寄存器计时。这可以防止数据在加载时发生变化。
74HC595 具有“三态”输出。这意味着并行数据输出上的引脚可以处于三种不同的状态。
- 低
- 高
- 关
OFF 状态是高阻态,有效断开芯片的输出。这种技术允许多个三态芯片驱动同一条总线,在任何给定时间只有其中一个处于活动状态。
DIP 封装中 74HC575 的引脚排列如下所示:
串行数据在 DS 引脚(引脚 14)上输入。您可以使用 Q7' 引脚来级联这些设备,以增加您可以控制的并行输出数量。
输出使能(引脚 13)控制三态总线,如果它为低电平,则输出总线被使能。
74HC165 – 8 位并行输入 – 串行输出该74HC165是具有串行输出的8位并行负载移位寄存器。它具有互补输出,其中一个可以连接到另一个 74HC165 以将它们级联。
该器件用于并行到串行数据转换,具有以下引脚排列:
与 74HC595 一样,这是一种非常常见的集成电路,您几乎可以从任何电子供应商处获得它。
74HC595 的额外输出端口我们将从 74HC595 SIPO(串行输入-并行输出)移位寄存器开始我们的实验。
74HC595 允许我们扩展 Arduino 上的数字 I/O 端口的数量。在这些实验中,我们将使用它来驱动一些 LED,我们将使用 Arduino 控制这些 LED。
Arduino & 74HC595 连接以下是我们将 74HC595 连接到 Arduino 和八个 LED 的方法。
请注意在电源两端添加了一个去耦电容器,当使用 74HC595 等 TTL 芯片时,这是一个好主意。我使用了一个 100uf 的电容器,但 10uf 以上的任何值都可以正常工作。确保您观察电容器的极性。
在我的面包板上,我用一个 8×2220 欧姆的电阻阵列替换了八个降压电阻。当您需要大量相同的电阻器时,这是一个方便的组件。当然,如果您没有阵列,您可以使用分立电阻器。
这里有很多电线,所以请仔细检查您的接线。您可以先连接 LED 降压电阻器组合,然后向电阻器施加 5 伏电压,如果接线正确,您将点亮 LED。对所有八个电阻-LED 对重复测试。在连接 74HC595 和 Arduino 之前执行此操作。
一旦全部连接好,您就可以继续前进并编写一些代码以使其全部工作。
Arduino shiftOut() 函数有几种方法可以使用 Arduino 与移位寄存器“对话”。一种方法是使用 SPI 总线,它允许您利用现有库来简化代码编写。
另一种方法是使用 Arduino 上的任何标准 I/O 引脚来创建时钟并交换串行数据。这是我们将用于处理 74HC595 移位寄存器的方法。
Arduino 提供了一个shiftOut()函数来简化串行连接上的数据移动。它可以获取一个字节值并以串行格式与另一个引脚上的时钟脉冲同步输出。可以选择两个方向输出数据。
- MSB First– 最高位在前。所以二进制数 10110010 将以“101”开始,或者从左到右,一次输出一位。
- LSB First – 最低有效位在前。在这种情况下,二进制数 10110010 将以“010”开始,或从右到左,一次输出一位。
我们将在我们的代码中使用这个功能。
Arduino 和 74HC595 代码我们的代码非常简单。该SHIFTOUT函数能将我们的数据发送到移位寄存器和创建时钟信号。
/*
74HC595 Shift Register Demonstration 1
74hc595-demo.ino
Count in Binary and display on 8 LEDs
Modified from "Hello World" example by Carlyn Maw,Tom Igoe and David A. Mellis
DroneBot Workshop 2020
https://dronebotworkshop.com
*/
// Define Connections to 74HC595
// ST_CP pin 12
const int latchPin = 10;
// SH_CP pin 11
const int clockPin = 11;
// DS pin 14
const int dataPin = 12;
void setup ()
{
// Setup pins as Outputs
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
// Count from 0 to 255 and display in binary
for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay ) {
// ST_CP LOW to keep LEDs from changing while reading serial data
digitalWrite(latchPin, LOW);
// Shift out the bits
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);
// ST_CP HIGH change LEDs
digitalWrite(latchPin, HIGH);
delay(500);
}
}
我们首先为连接到 74HC595 的引脚分配变量名称。然后将所有这些引脚设置为输出。然后我们进入循环。
我们使用 for-next 循环从 0 到 255 计数,递增 1。在每次增量时,我们将计数器值写入移位寄存器。锁存引脚用于在我们准备好之前保存数据,以便在加载移位寄存器时显示不会闪烁。
半秒延迟后,下一个数字被加载。