|
您是否曾经发现自己想要控制大量LED灯?或者需要更多的I/O引脚来同时控制按钮、传感器、伺服系统?好吧,您可以将几个传感器连接到Arduino引脚,但很快就会用完Arduino上的引脚。
解决方案是使用移位寄存器。移位寄存器(Shift Register)允许您扩展您可以从Arduino(或任何微控制器)使用的I/O引脚的数量。而74HC595移位寄存器是其中最著名的一个型号。
595基本上控制八个独立的输出引脚,只使用三个输入引脚。如果您需要超过8条额外的I/O线,您可以轻松地以菊花链方式连接任意数量的移位寄存器并创建大量I/O线。所有这些都是通过所谓的位移来完成的。如果您想了解有关位移的更多信息,可以查看Wikipedia的链接。
何时使用移位寄存器? 移位寄存器通常用于节省微控制器上的引脚,因为每个微控制器都有有限数量的I/O引脚 (GPIO)。
如果您的项目需要控制16个独立的LED,通常需要Arduino的16个引脚。如果您没有16个I/O引脚可用,这时可以使用移位寄存器。通过串联两个移位寄存器,我们只需使用3个I/O引脚就可以完成控制16个LED的任务。不仅如此;您链接在一起的移位寄存器越多,您就可以节省更多的引脚。
使用移位寄存器的实例是“任天堂控制器”。任天堂娱乐系统的主控制器需要连续按下所有按钮,它使用移位寄存器来完成这项任务。
74HC595移位寄存器如何工作? 74HC595有两个寄存器(可以认为是“内存容器”),每个寄存器只有8位数据。第一个称为移位寄存器。移位寄存器位于IC电路的深处,安静地接受输入。
每当我们向595施加时钟脉冲时,都会发生两件事: ● 移位寄存器中的位向左移动一步。例如,位7接受之前位6中的值,位6获取位5的值等。 ● 移位寄存器中的位0接受DATA引脚上的当前值。在脉冲的上升沿,如果数据引脚为高电平,则将1推入移位寄存器。否则为0。
在启用锁存器引脚时,移位寄存器的内容被复制到第二个寄存器,称为存储/锁存器寄存器。存储寄存器的每一位都连接到IC的输出引脚 QA-QH 之一,因此通常情况下,当存储寄存器中的值发生变化时,输出也会发生变化。
您可以通过下图更好地理解这一点。
74HC595移位寄存器引脚 595有多种厂商品牌和型号。在这里,我们将使用德州仪器的SN74HC595N。如果您使用不同厂家的型号,请仔细阅读其数据表并记下差异。
让我们来看看它的引脚排列。请注意,两个引脚的名称上有一条线;这意味着它们以“负逻辑”运行。
GND 应连接到Arduino的地。 VCC 是74HC595移位寄存器的电源引脚,我们连接到Arduino上的5V引脚。 SER(Serial Input,串行输入)引脚用于一次将数据输入移位寄存器。 SRCLK(移位寄存器时钟)是移位寄存器的时钟。 595在上升沿由时钟驱动。这意味着为了将位移入移位寄存器,时钟必须为高电平。并且位在时钟的上升沿被传输。 RCLK(寄存器时钟/锁存器)是一个非常重要的引脚。当驱动为高电平时,移位寄存器的内容被复制到存储/锁存寄存器中;最终出现在输出中。因此,可以将锁存引脚视为在输出端查看我们的结果的过程中的最后一步。 SRCLR(移位寄存器清除)引脚允许我们一次复位整个移位寄存器,使其所有位为0。这是一个负逻辑引脚,因此要执行此复位;我们需要将SRCLR引脚设置为低电平。当不需要复位时,该引脚应为高电平。 OE(输出使能)也是负逻辑:当其上的电压为高时,输出引脚被禁用/设置为高阻抗状态并且不允许电流流动。当OE低电压时,输出引脚正常工作。 QA–QH(输出使能)是输出引脚,应连接到某种类型的输出,如LED、7段数码管等。 QH' 引脚输出移位寄存器的第7位。在那里,我们可以菊花链式连接595:如果您将此QH'连接到另一个595的SER引脚,并为两个IC提供相同的时钟信号,它们将像具有16个输出的单个IC一样工作。当然,这种技术并不仅限于两个IC - 如果你有足够的电源,你可以菊花链任意多的IC。
将74HC595移位寄存器连接到Arduino UNO开发板 现在我们对74HC595的工作原理有了基本的了解,我们可以开始将它连接到Arduino!
首先将移位寄存器放在面包板上,确保IC的每一侧都位于面包板的单独一侧。小U形槽口朝上,引脚从上到下在左侧向下1-8,从上到下在右侧向下16-9,如下图所示。
首先让我们将引脚16 (VCC) 和 10 (SRCLR) 连接到Arduino上的 5v 引脚,并将引脚 8 (GND) 和13 (OE) 连接到Arduino上的Gnd引脚。这应该使IC保持正常工作模式。
接下来,我们需要连接我们将控制移位寄存器的三个引脚: ● 移位寄存器的引脚 11 (SRCLK) 连接到Arduino上的引脚6 ● 移位寄存器的引脚 12 (RCLK) 连接到Arduino上的引脚5 ● 移位寄存器的引脚 14 (SER) 连接到Arduino上的引脚4
现在,我们只需将所有输出引脚连接到LED灯,确保在LED之前放置一个220Ω电阻以减少电流,并确保LED的阴极返回到地。
放置LED时,请确保它们按顺序连接,以便QA连接到第一个LED,而QH连接到最后一个LED,否则我们的代码不会以正确的顺序点亮LED!
完成后,您应该会看到类似于下图所示的内容。
Arduino代码 硬件准备好后,现在我们可以测试一些代码!将Arduino开发板插入计算机并尝试草图; - int latchPin = 5; // Latch pin of 74HC595 is connected to Digital pin 5
- int clockPin = 6; // Clock pin of 74HC595 is connected to Digital pin 6
- int dataPin = 4; // Data pin of 74HC595 is connected to Digital pin 4
- byte leds = 0; // Variable to hold the pattern of which LEDs are currently turned on or off
- /*
- * setup() - this function runs once when you turn your Arduino on
- * We initialize the serial connection with the computer
- */
- void setup()
- {
- // Set all the pins of 74HC595 as OUTPUT
- pinMode(latchPin, OUTPUT);
- pinMode(dataPin, OUTPUT);
- pinMode(clockPin, OUTPUT);
- }
- /*
- * loop() - this function runs over and over again
- */
- void loop()
- {
- leds = 0; // Initially turns all the LEDs off, by giving the variable 'leds' the value 0
- updateShiftRegister();
- delay(500);
- for (int i = 0; i < 8; i++) // Turn all the LEDs ON one by one.
- {
- bitSet(leds, i); // Set the bit that controls that LED in the variable 'leds'
- updateShiftRegister();
- delay(500);
- }
- }
- /*
- * updateShiftRegister() - This function sets the latchPin to low, then calls the Arduino function 'shiftOut' to shift out contents of variable 'leds' in the shift register before putting the 'latchPin' high again.
- */
- void updateShiftRegister()
- {
- digitalWrite(latchPin, LOW);
- shiftOut(dataPin, clockPin, LSBFIRST, leds);
- digitalWrite(latchPin, HIGH);
- }
复制代码
将代码上传到Arduino后,您应该会看到如下输出:
如果您想熄灭而不是点亮其中一个 LED,您可以在“leds”变量上调用类似的Arduino函数 bitClear()。这会将“leds”的特定位设置为0,然后您只需要调用 updateShiftRegister() 来更新实际的LED。
代码说明 我们要做的第一件事是定义3个控制引脚,即74HC595的锁存器、时钟和数据引脚,我们将分别连接到Arduino的数字引脚#5、#6和#4。 - int latchPin = 5;
- int clockPin = 6;
- int dataPin = 4;
复制代码接下来,定义了一个名为“leds”的变量。这将用于保存当前熄灭或点亮LED灯的模式。 字节类型的数据使用八位表示数字。每个位都可以打开或关闭,因此非常适合跟踪我们的八个LED中的哪个是打开或关闭的。 - // Variable to hold the pattern of which LEDs are currently turned on or off
- byte leds = 0;
复制代码
在setup()函数中,我们只需将这三个引脚初始化为数字输出。 - void setup()
- {
- pinMode(latchPin, OUTPUT);
- pinMode(dataPin, OUTPUT);
- pinMode(clockPin, OUTPUT);
- }
复制代码
在loop()函数中,首先通过将变量“leds”的所有位设置为0来熄灭所有LED。然后调用名为updateShiftRegister() 的自定义函数,该函数将“leds”模式发送到移位寄存器,以便所有LED熄灭。稍后我们将讨论updateShiftRegister() 的工作方式。
程序暂停半秒,然后使用“for”循环和变量“i”开始从 0 计数到 7。每次,它使用Arduino函数bitSet()来设置变量“leds”中控制特定LED的位。然后它还调用 updateShiftRegister() 以便LED的状态根据变量“leds”中的内容而变化。
然后在“i”递增和下一个LED点亮之前有半秒的延迟。 - void loop()
- {
- leds = 0;
- updateShiftRegister();
- delay(500);
- for (int i = 0; i < 8; i++)
- {
- bitSet(leds, i);
- updateShiftRegister();
- delay(500);
- }
- }
复制代码
函数updateShiftRegister() ,首先将锁存器引脚设置为低电平,然后调用Arduino函数shiftOut() ,然后再次将锁存器引脚设置为高电平。
值得庆幸的是,Arduino提供了一个专门用于移位寄存器的辅助函数shiftOut() ,它允许我们在一次调用中简单地移位。您可以在Arduino的官方网站上探索有关该库的更多信息。
shiftOut() 函数有四个参数;前两个是分别用于数据和时钟的引脚。第三个参数指定要从数据的哪一端开始。我们将从最右边的位开始,它被称为“最低有效位”(LSB)。最后一个参数是要移入移位寄存器的实际数据,在本例中为“leds”。 - void updateShiftRegister()
- {
- digitalWrite(latchPin, LOW);
- shiftOut(dataPin, clockPin, LSBFIRST, leds);
- digitalWrite(latchPin, HIGH);
- }
复制代码
|