1、扩展Arduino:数字输出端口 3 Comments · Posted by flamingoeda in Arduino 随着你对Arduino的深入理解和应用,相信很快就会遇到Arduino端口不够用的情况了。比如你可能需要在你的项目里控制更多的LED或者继 电器,但却发现12似乎是一个很难超越的数字;或者你的声音项目里需要更多的电位器,但是Arduino板上6个模拟输入接口的限制却让你捉襟见肘。 如果此时Arduino的处理能力还尚能满足你的要求,只是接口数目不够,能够采用的一种办法就是对Arduino的数字端口和模拟端口进行扩展。 下图就是一个Arduino数字输出端口扩展板,
2、利用它原理上你可以将Arduino上的3个数字输出端口扩展成8个数字输出端口,通俗说来就是3个换8 个;-) 实验这块板最简单的办法是用三根数字连接线,分别将该扩展板上的SCK,RCK和SER引脚与传感器扩展板上的数字I/O的8、9和10号引脚相连接: 相应的测试代码如下所示: int dataPin = 8; // SER int latchPin = 9; // RCK int clockPin = 10; // SCK void setup() { pinMode(latchPin, OUTPUT); pinMode(clockPin, O
3、UTPUT); pinMode(dataPin, OUTPUT); } void loop() { for (int j = 0; j < 255; j++) { // start transmit data digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, j); // end transmit data digitalWrite(latchPin, HIGH); delay(500); } } 上述代码中最核心的是对函
4、数shiftOut()的调用,它的作用往扩展板上的8个数字引脚上写一个字节,该字节的每一位分别对应扩展板上8个数字输出I/O引脚中的一个。除此之外,shiftOut()函数在调用之前需要调用digitalWrite()将RCK置低,调用完成之后再置高,这是由芯片的控制时序决定的:-) 程序运行时的效果相当于一个递增的计数器,在扩展板的8个输出端口上分别接8个LED灯,可以看到相应的累加效果: 今天调试8*8双色LED显示屏,用三个74HC595级联,一点心得: 1、连接方式:三个595的11、12脚相连,第一级的14脚接MCU的串行数据输出,第一级的9(QH)接第二级的14脚,第
5、二级的9(QH)接第三级的14脚,如有更多级可以一直串下去。 2、数据输出:先将第三级(最后一级)的数据输出(只需发出移位脉冲,不要发锁存脉冲),然后是上一级,直到所有级的数据全部发完(数据现在是一一对应),这时MCU发出锁存脉冲,这样数据即可对号入座了。 以上信息希望对刚开始用595的朋友有用,由于水平有限,不足或错误之处请各位多多指教。 如果读到这你以为一切就结束了的话,那可就大错特错了;-)除了单个使用之外,这一扩展板其实是可以通过相应的连接线实现级连的。也就是说,如果两块相连的话,你就可以用Arduino上的三个数字I/O端口扩展出16个数字输出端口,如果三块相连
6、的话,你就可以用Arduino上的三个数字I/O端口扩展出24个数字输出端口来。理认上讲这样的扩展是可以一直做下去的,但受限于处理器的处理能力和电源大小、外部干扰等的影响,这样的扩展在实际应用中当然是有一定限制的,至于是多少嘛 ,那就得由实际的应用场景来决定了。 下面来看两块数字输出扩展板如果级联使用。在上述接好的电路的基础上,我们只需要再用一根数字输出扩展板连接线,将第一块数字输出扩展板上的输出端口(OUTPUT),与第二块数字输出扩展板上的输入端口(INPUT)连接起来,电路部分就算完成了: 程序部分我们对上面的程序做一点点小的修改,由于是两块数字输出扩展板,因此我们需要分别调用两
7、次shiftOut()函数,来为两块数字输出扩展板分别设置不同的值: int dataPin = 8; // SER int latchPin = 9; // RCK int clockPin = 10; // SCK void setup() { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { for (int j = 0; j < 255; j++) { // start trans
8、mit data digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, j); shiftOut(dataPin, clockPin, MSBFIRST, 255 - j); // end transmit data digitalWrite(latchPin, HIGH); delay(500); } } 需要注意的是,我们为数字输出扩展板提供的数据,其实是一级一级推到不同的扩展板上的,也就是说上面的两条shiftOut()函数执行完之后,第一
9、条shitfOut()函数所指定的值其实被写到了第二块扩展板上,而第二条shiftOut()函数所指定的值则写到了第一块扩展板上。 上述代码在运行时的效果相当于在第二块扩展板上实现了一个递增的计数器,在第一块扩展板上实现了一个递减的计数器,如果你还不是那不明白的话,那就接上16个LED好好观察一下效果吧,另外适时补充一下二进制数据的基本常识可能也是必要的;-) Arduino采用的ATmega168芯片带12个数字I/O管脚,其中每个都可以对一个数字量进行控制,从而实现类似于点亮一个发光二极管这样的功能。在实际的工程应用里,有时我们可能会遇到需要对更多的数字量进行控制的场合,比如同时控制1
10、6个发光二极管,这时Arduino自带的数字I/O管脚就不够用了,必须进行相应的扩展。其中一种可行的办法就是借助74HC595这样一个8位串入并出移位寄存器,这个芯片能够多个级连起来一起使用,因此理论上能够通过Arduino上有限的几个管脚(最少三个)产生任意多个的数字输出。 74HC595同数据相关的引脚可以分为三类: DS:串行数据输入,接Arduino的某个数字I/O引脚。 Q0~Q7:8位并行数据输出,可以直接控制8个LED,或者是七段数码管的8个引脚。 Q7′:级联输出端,与下一个74HC595的DS相连,实现多个芯片之间的级联。 74HC595同控制相关的引脚一共有
11、四个: SH_CP:移位寄存器的时钟输入。上升沿时移位寄存器中的数据依次移动一位,即Q0中的数据移到Q1中,Q1中的数据移到Q2中,依次类推;下降沿时移位寄存器中的数据保持不变。 ST_CP:存储寄存器的时钟输入。上升沿时移位寄存器中的数据进入存储寄存器,下降沿时存储寄存器中的数据保持不变。应用时通常将ST_CP置为低点平,移位结束后再在ST_CP端产生一个正脉冲更新显示数据。 MR:重置(RESET),低电平时将移位寄存器中的数据清零,应用时通常将它直接连高电平(VCC)。 OE:输出允许,高电平时禁止输出(高阻态)。引脚不紧张的情况下可以用Arduino的一个引脚来控制它,这
12、样可以很方便地产生闪烁和熄灭的效果。实际应用时可以将它直接连低电平(GND)。 对于一个最简单的74HC595应用来讲,可以用Arduino的三个数字I/O端口分别控制DS、SH_CP和ST_CP,然后将MR和OE分别接VCC和地。下面是利用74HC595来控制8个LED的原理图: One Response to “74HC595串入并出8位移位寄存器” i3dx Says: December 26th, 2007 at 9:09 pm 订正:Arduino 带有 0-7 8-13 14-19 共三组,20个数字IO口。 只是14-19常用于模拟输入端0-5口使用,但是基本数字
13、io功 能仍然保留。 Arduino mini 另有20 21两个数字io可使用。 与74LS595(8位输出锁存移位寄存器)的使用方法 74LS595的数据端: QA--QH: 八位并行输出端,可以直接控制数码管的8个段。 QH': 级联输出端。我将它接下一个595的SI端。 SI: 串行数据输入端。 74LS595的控制端说明: /SCLR(10脚): 低点平时将移位寄存器的数据清零。通常我将它接Vcc。 SCK(11脚):上升沿时数据寄存器的数据移位。QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。我通
14、常都选微秒级) RCK(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将RCK置为低电平,当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。 /G(13脚): 高电平时禁止输出(高阻态)。如果的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。 注: 1)74164和74595功能相仿,都是8位串行输入转并行输出移位寄存器。74164的驱动电流(25mA)比74595(35mA)的要小,14脚封装,体积也小一些。 2)74595的主要优点是具有数据存
15、储寄存器,在移位的过程中,输出端的数据可以保持不变。这在串行速度慢的场合很有用处,数码管没有闪烁感。 3)595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,在正常使用时SCLR为高电平, G为低电平。从SER每输入一位数据,串行输595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,如下面的真值表,在正常使用时SCLR为高电平, G为低电平。从SER每输入一位数据,串行输入时钟SCK上升沿有效一次,直到八位数据输入完毕,输出时钟上升沿有效一次,此时,输入的数据就被送到了输出端。入时钟SCK上升沿有效一次,直到八位数据输入完毕,输出时钟上升沿有效一次,此时,输入的数据就被送到了
16、输出端。 其实,看了这么多595的资料,觉得没什么难的,关键是看懂其时序图,说到底,就是下面三步(引用): 第一步:目的:将要准备输入的位数据移入74HC595数据输入端上。 方法:送位数据到 P1.0。 第二步:目的:将位数据逐位移入74HC595,即数据串入 方法:P1.2产生一上升沿,将P1.0上的数据移入74HC595中.从低到高。 第三步:目的:并行输出数据。即数据并出 方法:P1.1产生一上升沿,将由P1.0上已移入数据寄存器中的数据 送入到
17、输出锁存器。 说明: 从上可分析:从P1.2产生一上升沿(移入数据)和P1.1产生一上升沿 (输出数据)是二个独立过程,实际应用时互不干扰。即可输出数据的 同时移入数据。 而具体编程方法为 如:R0中存放3FH,LED数码管显示“0” ;*****接口定义: DS_595 EQU P1.0 ;串行数据输入(595-14) CH_595 EQU P1.2 ;移位时钟脉冲(595-11) CT_595 EQU P1.1 ;输出锁存器控制脉冲(595-12) ;*****将移位寄存器内的数据锁存到输出寄存器并显示 OUT_595:






