用移位寄存器来扩展 8位移位寄存器

8位移位寄存器(由移位寄存器扩展)
今天我们将使用几个基本的电子“积木”,移位寄存器 。这些方便的设备可以用于各种目的,例如数据转换、缓冲和存储,但今天我们将看到它们也可以用于扩展Arduino数字I/O端口的数量 。
原文:加拿大人DroneBotWorkshop.com翻译:DIY百事可乐
通过学习使用移位寄存器,你将为设计师的工具箱增加另一个方便的工具 。
目录1简介1.1扩展您的Arduino
2移位寄存器2.1移位寄存器的类型2.1.1串行输入-并行输出2.1.2并行输入-串行输出2.1.3并行输入-并行输出&串行输入-串行输出2.2移位寄存器的工作原理2.3级联移位寄存器
3 74HC575和74HC165移位寄存器3.1 74HC595-8位串行输入-并行输出3.2 74HC165-8位并行输入-串行输出
4.74HC595的附加输出端口4.1 Arduino & 74HC595连接4.2 Arduino shiftOut()功能4.3 Arduino & 74HC595草图
5.驱动7段显示器5.1 7段LED显示器5.2 74HC595 7段显示器连接5.3 74HC595 7段显示器原理图
6.74hc165的附加输入端口6.1 Arduino shiftIn()函数6.2 Arduino & 74HC165连接6.3 Arduino & 74HC165代码
7.74HC595和74HC165一起用7.1 74HC595和74HC165连接7.2 74HC595和74HC165代码17.3 74HC595和74HC165代码2——激动人心!
8.结论
-
扩展您的ArduinoArduino已经有很多数字I/O端口 。事实上,Arduino Mega 250有54个数字I/O引脚和另外16个模拟输入,可以兼作数字I/O引脚 。因此,对于70个潜在的I/O引脚,通常不需要更多 。但有时你确实需要更多 。
以大家熟悉的“LED立方体”为例 。一个4x4x4的立方体需要64个led,如果你“借用”几个模拟引脚,这在Arduino Mega 2560的能力范围内 。但是你已经达到极限了 。
如果你想扩展到一个5x5x5的立方体,那么你就不走运了 。为此,你需要125个led,你不能用Arduino单独控制它们 。
即使是使用标准(即未寻址)RGB LED的4x4x4立方体也将超过极限 。
有许多方法可以解决这些问题,包括在矩阵中运行led或使用移位寄存器 。移位寄存器将允许您仅使用几个Arduino I/O引脚来寻址大量led 。
有时,您有许多传感器、显示器或其他I/O设备,并且您不能为LED或开关保留许多引脚,但您需要一个多LED显示器或键盘 。移位寄存器又可以派上用场了 。
让我们来看看这些设备的使用方法 。
移位寄存器移位寄存器是用于转换、存储或传输二进制数据的时序逻辑电路 。
这些设备用于串行和并行数据之间的转换 。它们可用于数据通信电路以及存储和缓冲电路 。许多复杂的电子电路,如微处理器和微控制器,在内部使用移位寄存器 。
移位寄存器的类型移位寄存器在其输入和输出端处理串行和并行数据,并且可以在这些格式之间转换 。
移位寄存器有四种基本类型:
串行输入-并行输出并行输入-串行输出并行到串行输出(PISO)移位寄存器将并行数据转换为串行数据 。它用于通信并将多个输入端口转换为串行数据 。
并行输入–并行输出和串行输入–串行输出你可能觉得这两个很奇怪 。为什么需要移位寄存器输出与输入格式相同的数据?
答案是,它可以用作缓冲器,在特定数量的时钟周期内保存数据 。我们今天使用的移位寄存器都使用类似的缓冲器来保存其输入和输出上的数据,因此当寄存器移位时,数据不会改变 。
移位寄存器的工作原理内部移位寄存器由许多基本逻辑门组成,其中许多被排列成“触发器” 。
如果您不熟悉触发器,它是一个基本的电子电路,可用于保存来自其输入的数据值 。它是一个基本的构建模块,无处不在,包含在许多形式的存储器电路中 。
串行输入-并行输出或SIPO寄存器使用一系列触发器,并行输出上的每一位对应一个触发器 。此处的插图显示了一个4位设备 。
当串行数据的第一位被计时时,它被存储在触发器中并出现在其输出端 。
下一位数据将原始位推到下一个触发器 。
随着串行数据的输入,该过程继续 。请注意,触发器仅在输入时更新输入值 。
最后,当并行输出中的所有数据都计时时,就可以读取它了 。在大多数移位寄存器中,一个额外的缓冲区保存并行数据,在所有数据输入时钟之前,它不会改变 。
PISO或并行输入串行输出移位寄存器的结构如下
图中的“MUX”部分实际上是由许多分立的逻辑门组成,用来在合适的时间将数据馈入相关的触发器 。
这很重要,因为PISO移位寄存器需要分别为并行数据的每一位计时 。这意味着并行输入上的数据在被读取时不能改变 。类似地,大多数实际设计使用缓冲器来存储并行数据 。
级联移位寄存器移位寄存器是根据它们处理的位数来分类的 。上图所示的是4位寄存器,而我们今天要用的两个移位寄存器都是8位器件 。
如果需要增加一个移位寄存器可以处理的并行数据量,可以用另一个移位寄存器级联 。所以两个8位移位寄存器可以支持16位,加上一个支持24位,以此类推 。
你不需要连接到微控制器来级联移位寄存器,所以这是一个不使用大量端口来驱动大量led或读取大量开关的好方法 。
74HC575和74HC165移位寄存器今天,我们将使用两个非常常见和容易获得的移位寄存器,即74HC595 SIPO和74HC165 PISO 。让我们仔细看看这些芯片 。
7HC595-8位串行输入-并行输出74HC575是一个8级串行移位寄存器,也有一个内部存储寄存器 。存储寄存器缓冲输出数据,可以独立于移位寄存器计时 。这可以防止数据在加载过程中发生变化 。
74HC595有一个“三态”输出 。这意味着并行数据输出端的引脚可以处于三种不同状态 。
低的
高的
关闭
OFF状态为高阻态,有效断开芯片的输出 。这种技术允许多个三态芯片驱动同一总线,并且在任何给定时间只有其中一个是活动的 。
DIP封装的74HC575引脚排列如下:
串行数据通过DS引脚(引脚14)输入 。可以使用Q7’引脚级联这些器件,以增加可以控制的并行输出数量 。
输出使能(引脚13)控制三态总线,如果为低电平,则输出总线使能 。
7hc 165–8位并行输入–串行输出74HC165是一个带串行输出的8位并行加载移位寄存器 。它具有互补输出,其中一个可以连接到另一个74HC165以级联它们 。
该器件用于并行到串行数据转换,引脚排列如下:
和74HC595一样,这是一个非常常见的集成电路,你几乎可以从任何电子供应商那里得到 。
74HC595的附加输出端口我们将从74HC595 SIPO(串行输入-并行输出)移位寄存器开始实验 。
74HC595允许我们扩展Arduino上的数字I/O端口的数量 。在这些实验中,我们将使用它来驱动一些led,我们将使用Arduino来控制这些led 。
Arduino & 74HC595连接以下是我们如何将74HC595连接到Arduino和八个led 。
请注意,电源两端都加了一个去耦电容,在使用74HC595等TTL芯片时是个不错的主意 。我用的是100uf的电容,但是10uf以上的任何值都可以正常工作 。确保观察电容器的极性 。
在我的试验板上,我用一个82220欧姆的电阻阵列取代了8个降压电阻 。当您需要大量相同的电阻时,这是一个方便的元件 。当然,如果没有阵列,可以使用分立电阻 。
这里有许多电线,所以请仔细检查你的布线 。可以先连接LED降压电阻组合,然后对电阻施加5伏电压 。如果接线正确,您将点亮LED 。对所有八个电阻-LED对重复测试 。在连接74HC595和Arduino之前,请执行此操作 。
一旦所有这些都连接起来,您就可以继续编写一些代码来使其工作 。
ardnoshiftout()函数使用Arduino与移位寄存器“对话”有几种方式 。一种方法是使用SPI总线,它允许您利用现有的库来简化代码编写 。
另一种方法是使用Arduino上的任何标准I/O引脚来设置定时器和交换串行数据 。这是我们将用来处理74HC595移位寄存器的方法 。
Arduino提供了一个shiftOut()函数来简化串行连接上的数据移动 。它可以获得一个字节值,并以串行格式输出,与另一个引脚上的时钟脉冲同步 。您可以选择两个方向来输出数据 。
MSB优先–最高位优先 。所以二进制数10110010会从“101”开始,或者从左到右一次输出一位 。
LSB优先–最低有效位优先 。在这种情况下,二进制数10110010将从“010”开始,或者从右到左一次输出一位 。
我们将在代码中使用这个函数 。
Arduino和74HC595代码我们的代码非常简单 。这个移出函数可以将我们的数据发送到移位寄存器和设置定时器信号 。
/* 74hc 595 shift register demulation 174 HC 595-demo . inocountinbinarianddisplayon 8 LEDs modified from " hello world " example by carlynmaw、TomIgoeandDavidA 。mellisdronebotworkshop 2020 https://dronebotworkshop . com *///define connections to 74hc 595//ST _ CP pin 12 constintlatchpin = 10;//SH _ CP pin 11 constintclockpin = 11;//ds pin 14 constintdatapin = 12;void setup(){//setuppinsautputspinmode(latch pin,OUTPUT);pinMode(clockPin,输出);pinMode(数据引脚,输出);} void loop(){//count from 0 to 255 anddisplayinbinary for(intnumberToDisplay = 0;NumberToDisplay我们首先给连接到74HC595的管脚分配变量名 。然后将所有这些引脚设为输出 。然后我们进入循环 。
我们使用for-next循环从0计数到255,增量为1 。在每次递增时,我们将计数器值写入移位寄存器 。latch引脚用于在我们准备好之前保存数据,以便载入移位寄存器时显示器不会闪烁 。
半秒钟的延迟后,下一个数字被加载 。
结果是LED显示从0到255的二进制数 。
您可以试验代码,操作一些值,并观察对LED的影响 。尝试将shiftOut语句中的MSBFIRST参数更改为LSBFIRST,看看会发生什么 。
这是理解基本移位寄存器操作的简单方法 。
驱动7段显示器74HC575的另一个用途是驱动7段LED显示屏 。你可以用它来显示连接到一台显示器上的数字,也可以级联多台74HC595来驱动多台显示器 。
7段LED显示屏典型的7段LED显示屏布局如下:
请注意,在“7段”显示中实际上有八个LED元件,第八个LED用作小数点 。在某些显示中,这可以用冒号代替 。
LED显示屏有两种配置:
公共阳极–所有led使用公共阳极(正极)连接 。
公共阴极-所有发光二极管都与一个公共阴极(负电极)相连 。
两种显示器类型使用相同的引脚排列,因此了解您的类型非常重要 。一个很好的判断方法(除了参考监视器零件号)是在“二极管测试”功能上使用万用表 。当与正确的极性连接时,它可以用来点亮LED元件 。
普通阴极显示器比较常见,是我们会用来做实验的类型 。
74HC595 7段监视器连接由于共阴极7段LED显示器实际上只将八个LED连接到一个共阴极(负极)端子,因此它与我们在第一个实验中使用的八个LED没有什么不同 。所以我们可以使用完全相同的电路来布线 。
使用连接图中的图表将显示引脚连接到降压电阻 。COM引脚(共阴极)连接到Arduino的地 。请注意,显示器将有两个COM引脚,您只需要连接一个 。
完成所有连接后,您可以通过运行前面的代码来测试它,该代码应该测试所有LED段,包括小数点 。
但是要真正展示一些连贯的东西,我们需要不同的代码 。
74HC595 7段显示代码这是我们将用来测试我们的7段显示器的代码 。
/* 74hc 595 shift register with 7-segmentled display 74hc 595-7 seg display . inocountinhexfrom 0-fand display on 7-segmentcommoncathodeleddisplaydronebotworkshop 2020 http s://dronebotworkshop . com *///define connections to 74hc 595//ST _ CP pin 12 constintlatchpin = 10;//SH _ CP pin 11 constintclockpin = 11;//ds pin 14 constintdatapin = 12;//Patternsforcharacters0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,FintdatArray[16]= { b 11111100000,B11011010,B11110010,b 11100110,b 11100110,B10110110,b 1011110,B10111110,b 1111000000000,b 111110,b 11110000000,b 111111111void setup(){//setuppinsautputspinmode(latch pin,OUTPUT);pinMode(clockPin,输出);pinMode(数据引脚,输出);} void loop(){//count from 0 to 15 for(int num = 0;这个num代码与前面的代码有许多相似之处,当你认为它很好地完成了同样的事情时,这并不奇怪 。
我们从定义与74HC595的联系开始 。
然后我们创建一个16个元素的数组,每个元素代表要在7段LED上显示的字符模式 。
这些元素以二进制形式编写,因此很容易理解它们是如何工作的 。在二进制字节中,每一位代表一个LED段 。从MSB到LSB(从左到右),它们代表显示器中的以下部分:
a–b–c–d–e–f–g–DP
当该位设为“1”时,每段LED点亮,“0”表示熄灭 。
数组是有序的,所以元素0是“0”的字符 。元素1是诸如“1”的字符 。它是十六进制的,所以元素15是“F” 。
看看数组元素,你会看到排列 。
在再次设置时,我们将连接设置为输出,然后进入循环 。
我们再次使用计数器,只是这次在0和15之间 。我们将在LED显示屏上以十六进制格式显示这些值 。
我们一次遍历一个元素,并使用shiftOut将数组中的数据发送到移位寄存器 。
加载代码并观察显示 。如果一切都连接正确,你会看到它从0数到f,然后重复 。
74HC165的附加输入端口现在我们知道了如何使用移位寄存器添加输出端口,是时候反过来添加一些输入端口了 。对于这项工作,我们将使用74HC165 。
我们将使用74HC165移位寄存器和八个触摸按钮开关 。移位寄存器将从开关获得8个输入,并将它们作为串行数据发送到Arduino 。
函数的作用是Arduino再次拥有了接收串行数据的专用功能 。
函数中的一个字节一次移动串行数据 。可以设置为先取MSB或LSB 。它通常与74HC165或CD4021BE等移位寄存器一起使用 。
和它的表亲shiftOut函数一样,shiftIn函数也提供时钟信号来同步数据传输 。
Arduino & 74HC165连接74HC165的输入需要拉低以防止错误读数,因此除了八个按钮开关之外,我们还需要八个下拉电阻 。我用的是10k的电阻,但是4.7k到27k的任何值都可以正常工作 。
同样,我使用了一个100uf的去耦电容,以确保连接时注意极性 。
一旦你把它们连接在一起,我们就可以专注于我们将用来完成这项工作的代码 。
Arduino & 74HC165代码我们的代码非常简单,因为它所做的只是读取按钮的状态,并在串行监视器上显示结果 。但要知道如何从buttons和74HC165获取数据,你只需要做这些 。
/* 74hc 165 shift registerdemation174 HC 165-demo . inoreadfrom 8 switchesanddisplayvaluesonserialmonitordronebotworkshop 2020 https://dronebotworkshop . com *///define connections to 74hc 165//plpin 1 int load = 7;//cepin 15 intclockenablepin = 4;//q 7 pin 7 int data in = 5;//CP pin 2 intclokin = 6;void setup(){//setupserialmonitorserial . begin(9600);//setup 74 HC 165 connectionspinmode(load,OUTPUT);pinMode(clockEnablePin,输出);pinMode(时钟,输出);pinMode(数据输入,输入);} void loop(){//WritepulsetoloadpindigitalWrite(load,LOW);delay微秒(5);digitalWrite(高负载);delay微秒(5);//getdata from 74 HC 165 digital write(clock in,高电平);digitalWrite(clockEnablePin,低电平);byteincoming=shiftIn(dataIn,clockIn,LSB first);digitalWrite(clockEnablePin,高电平);//printtoserialmonitorserial . print(" pin States:\ r \ n ");Serial.println(传入,BIN);延迟(200);}该代码与我们之前的所有代码一样,定义了IC的四个连接 。
在设置中,我们初始化串行监视器,然后根据需要设置连接 。
在循环中,我们首先向load引脚写入一个脉冲,使其将并行输入的数据加载到缓冲器中进行处理 。
接下来,我们设置74HC165发送数据,然后使用shiftIn函数获取数据,首先是LSB(最低有效位) 。我们通过拉高时钟引脚来实现,这意味着我们完成了 。
最后,我们将结果打印到串行监视器上 。
加载代码,打开串行监视器并观察输出 。你会马上注意到一些事情 。
所有数据输出保持高电平,与电路板上的布线相反 。按下按钮将使其读数变低,即使这与实际发生的情况相反 。
这是因为我们使用74HC165的反相输出 。我们的数据正好相反 。
我将在后面的代码中向您展示如何以正确的方式将其恢复 。继续读!
我们刚才用的例子有很多实际应用,其中一个很明显是作为小键盘(虽然有更好的方法来制作大键盘) 。对于需要大量开关的项目,这是一种有用的设计技术 。
该电路的一个重要应用是配合DIP开关或跳线使用,这些开关或跳线只是偶尔设置 。您可以使用74NC165来减少读取8位DIP开关所需的连接数量,只需在设置程序中读取它,以便它只能在设备通电或复位时读取 。
74HC595和74HC165一起使用 。当然,如果不采取额外的步骤将所有这些led和开关连接在一起,那将是一种浪费!所以我们开始吧 。
74HC595和74HC165已连接如果你像我一样在自己的无焊面包板上构建每个演示,那么将它们连接在一起非常简单 。
在其中一次演示中,Arduino与其面包板断开了连接,无论是哪一个都没有关系 。将连接留在面包板上,以便您可以将它们重新连接到另一个Arduino 。您可以将5v和接地连接连接到其他试验板电源轨 。
完成后,尝试在Arduino上运行前面的代码,一切应该仍然正常 。如果有什么东西坏了,请检查一下你的线路 。当你加入项目的时候,可能有什么东西被断开了——这里有很多电线!
测试完一切,就可以检查代码同时使用74HC165和74HC595了 。
74HC595和74HC165代码1因为我们的演示本质上是两个演示的融合,所以我们的代码完全相同 。你会发现这段代码和之前的代码有很多相似之处,这不是偶然的——有些是字面上的剪切和粘贴!
该代码的目的是简单地使用LED来显示按钮的状态 。作为示范,效果不错 。我保证在这之后我们会继续做一些更令人兴奋的事情!
/* 74hc 595 & 74hc 165 shift registerdemaration74hc 595-to-74ch 365 . inoinputfor8 buttonsusing 74hc 165 outputto 0 LEDs using 74hc 595 dronebotworkshop 2020 https://dronebotworkshop . com *///defineconnectionsto 74hc 165//plpin 1 int load = 7;//cepin 15 intclockenablepin = 4;//q 7 pin 7 int data in = 5;//CP pin 2 intclokin = 6;//defineconnectionsto 74hc 595//ST _ CP pin 12 constintlatchpin = 10;//SH _ CP pin 11 constintclockpin = 11;//ds pin 14 constintdatapin = 12;void setup(){//setupserialmonitorserial . begin(9600);//74HC165pinspinMode(load,OUTPUT);pinMode(clockEnablePin,输出);pinMode(时钟,输出);pinMode(数据输入,输入);//74HC595pinspinMode(latchPin,输出);pinMode(clockPin,输出);pinMode(数据引脚,输出);} void loop(){//read switches//WritepulsetoloadpindigitalWrite(load,LOW);delay微秒(5);digitalWrite(高负载);delay微秒(5);//getdata from 74 HC 165 digital write(clock in,高电平);digitalWrite(clockEnablePin,低电平);byteincoming=shiftIn(dataIn,clockIn,LSB first);digitalWrite(clockEnablePin,高电平);//printtoserialmonitorserial . print(" pin States:\ r \ n ");Serial.println(传入,BIN);//WritetoLEDs//ST _ cplowtokeepledsfromchangingwhilereindingserialdata digital write(latch pin,LOW);//shiftouthebitshiftout(data pin,clockPin,LSBFIRST,~ incoming);//ST _ CPHIGHchangeLEDsdigitalWrite(latch pin,高);延迟(500);}我们再次定义两个集成电路的引脚连接 。在设置中,我们初始化串行监视器,并根据需要设置连接 。
【用移位寄存器来扩展 8位移位寄存器】首先循环我们之前用来从74HC165读取按钮值的相同例程 。同样,我们将数据插入一个名为“输入”的8位字节,并在串行监视器上显示其值 。
接下来,我们使用之前使用的相同代码将数据写入74HC595 。但是我们改变了发送到移位寄存器的数据 。
请记住,我们来自交换机的数据是相反的 。如果我们把它发送到74HC595,它会工作,但除非我们按下按钮,否则led将全部亮起 。
为了反转数据,当我们在shiftOut函数中使用它时,我们在“incoming”变量前面使用“~”符号 。波浪号(tilde)符号反转二进制数据,将每个零变为一,反之亦然 。这正是我们需要做的 。
您还会注意到,与早期的74HC595代码不同的一点是,我们首先发送数据LSB 。这与我们从按钮接收它的方式相匹配 。第一,发送MSB可以,但是LED显示会反 。
装上试试吧 。
很有趣,不是吗?
好吧,它确实不是,但它确实展示了如何获得并行数据(开关输入),使用移位寄存器将其转换为串行,发送到Arduino,发送回第二个移位寄存器并进行转换 。它再次回到平行状态(LED输出) 。这有点令人兴奋 。
如果你不是很激动,请不要着急 。现在我们有8个开关和8个led,我们可以做其他事情 。
74HC595和74HC165代码2–激动人心!为了给我们的演示添加一些素材,让我们使用八个开关来选择LED灯的闪烁模式 。因为我们有八个开关,所以我们可以选择八种模式 。
这是我们如何做的代码:
/* 74hc 595 & 74hc 165 shift registerdemaration274 HC 595-to-74ch 365-pattern . inoinputfrom 8 button using 74hc 165 output to 8 led using 74hc 595 selectledpatternusingpustut ondronebotworkshop 2020 https://dronebotworkshop . com *///defineconnectionsto 74hc 165//plpin 1 int load = 7;//cepin 15 intclockenablepin = 4;//q 7 pin 7 int data in = 5;//CP pin 2 intclokin = 6;//defineconnectionsto 74hc 595//ST _ CP pin 12 constintlatchpin = 10;//SH _ CP pin 11 constintclockpin = 11;//ds pin 14 constintdatapin = 12;//definedataarrayintdataarray[8];void setup(){//setupserialmonitorserial . begin(9600);//74HC165pinspinMode(load,OUTPUT);pinMode(clockEnablePin,输出);pinMode(时钟,输出);pinMode(数据输入,输入);//74HC595pinspinMode(latchPin,输出);pinMode(clockPin,输出);pinMode(数据引脚,输出);} void loop(){//read switches//WritepulsetoloadpindigitalWrite(load,LOW);delay微秒(5);digitalWrite(高负载);delay微秒(5);//getdata from 74 HC 165 digital write(clock in,高电平);digitalWrite(clockEnablePin,低电平);byteincoming=shiftIn(dataIn,clockIn,LSB first);digitalWrite(clockEnablePin,高电平);//printtoserialmonitorserial . print(" pin States:\ r \ n ");Serial.println(传入,BIN);//SetuparrayforLEDpatternswitch(incoming){ caseb 11111110:data rray[0]= b 11111111;data rray[1]= b 01111110;data rray[2]= b 10111101;data rray[3]= b 11011011;data rray[4]= b 11100111;data rray[5]= b 11011011;data rray[6]= b 10111101;data rray[7]= b 01111110;打破;case b 1111101:data array[0]= b 00000001;data rray[1]= b 00000010;data rray[2]= b 00000100;data rray[3]= b 00001000;data rray[4]= b 00010000;data rray[5]= b 00100000;data rray[6]= b 01000000;data rray[7]= b 10000000;打破;case b 1111011:data array[0]= b 10000001;data rray[1]= b 01000010;data rray[2]= b 00100100;data rray[3]= b 00011000;data rray[4]= b 00000000;data rray[5]= b 00100100;data rray[6]= b 01000010;data rray[7]= b 10000001;打破;case b 11110111:data rray[0]= b 10101010;data rray[1]= b 01010101;data rray[2]= b 10101010;data rray[3]= b 01010101;data rray[4]= b 10101010;data rray[5]= b 01010101;data rray[6]= b 10101010;data rray[7]= b 01010101;打破;case b 11101111:data rray[0]= b 10000000;data rray[1]= b 00000001;data rray[2]= b 01000000;data rray[3]= b 00000010;data rray[4]= b 00100000;data rray[5]= b 00000100;data rray[6]= b 00010000;data rray[7]= b 00001000;打破;case b 11011111:data rray[0]= b 11000000;data rray[1]= b 01100000;data rray[2]= b 00110000;data rray[3]= b 00011000;data rray[4]= b 00001100;data rray[5]= b 00000110;data rray[6]= b 00000011;data rray[7]= b 10000001;打破;case b 10111111:data rray[0]= b 11100000;data rray[1]= b 01110000;data rray[2]= b 00111000;data rray[3]= b 00011100;data rray[4]= b 00001110;data rray[5]= b 00000111;data rray[6]= b 10000011;data rray[7]= b 11000001;打破;case b 0111111:data rray[0]= b 10001000;data rray[1]= b 01000100;data rray[2]= b 00100010;data rray[3]= b 00010001;data rray[4]= b 10001000;data rray[5]= b 01000100;data rray[6]= b 00100010;data rray[7]= b 00010001;打破;默认:break}//WritetoLEDs//count from 0 to 7 for(int num = 0;Num,如你所见,我再次借用了之前所有演示的编码 。事实上,这段代码中只有一处不同,那就是允许您选择LED模式的switch-case语句 。
我们使用保存开关值的“传入”字节作为语句的开关 。然后我们有八种情况,每个开关一种 。如果你想允许两个按钮同时按下,你大概可以添加更多的按钮,但八个对我来说已经足够了!
在每种情况下,我们用LED图案填充datArray阵列,以二进制形式编写以便于查看 。在每个字节中,“1”表示LED打开,“0”表示LED关闭 。
我在数组中使用了八个元素来简化它,但是你可以把它加到任何你喜欢的数字上 。只需更改数组定义并遍历数组元素的for-next循环中的数字 。
我将模式切换之间的延迟设置为200毫秒,但您可以更改它 。更好的是,尝试在每个案例评估中使用延迟作为一个变量,这样您就可以使模式以不同的速度运行 。
代码像预期的那样工作,而且看起来很有趣 。
您可以通过级联74HC595来添加更多led来改进代码 。您也可以通过在一个模拟输入端添加一个电位计,并使用它来设置延迟时间,从而使速度可变 。74HC595上的使能输入可以由PWM驱动,以改变LED亮度,您可以用第二个电位计控制它 。
您甚至可以添加一些MOSFET来驱动更大的led,并制作自己的特效!
一个简单的演示,潜力无限 。
结论移位寄存器可能是基本的构建模块,如果您需要向项目添加额外的输入或输出,它们会非常有用 。它们既便宜又容易使用 。

    推荐阅读