当我们在搭建arduino项目时,时常因为需要接入按钮、传感器、舵机、LED等而遇到I/O口不足的问题,此时就需要使用到74HC595。
74HC595是一个8位串行输入、并行输出(SIPO,Serial-In-Parallel-Out)的移位寄存器。其具有8个输出引脚,而只需要3个输入引脚。并可以串接多个IC实现更多输出引脚需求。
引脚图
74HC595引脚图
GND | 连接到Arduino的GND |
VCC | 连接到Arduino的5V |
SER | |
SRCLK | 移位寄存器时钟,74HC595由上升沿驱动,当向移位寄存器写入数据时,SRCLK必须为高电平。 |
RCLK(latch) | 锁存器时钟,高电平时,移位寄存器的内容拷贝到锁存寄存器,同时表现为输出。Latch相当于一个阀门。 |
SRCLR | 低电平有效。可以一次性将移位寄存器所有位置为0。通常情况此引脚连接高电平。 |
OE | 低电平有效。高电平时输出引脚禁用或为高阻态。低电平时输出引脚正常工作。 |
QA-QH | 输出引脚,可以连接LED或者7段数码管 |
QH‘ | 可用于串接74HC595。当此引脚连接到SER引脚,并同时给2个IC同样的时钟,则可认为是一个具有16个输出的IC。在保证电源供应的情况下,可以串接多个IC。 |
工作原理
74HC595具有2个寄存器(可理解为2个存储容器),每个可以存储8位(bit)数据。
- 一个叫做移位寄存器,用于接收输入数据。
- 当74HC595接收到时钟脉冲时:
- 移位寄存器中的位置向左移动一位。
- 移位寄存器的Bit0(右边第一位)接收当前DATA引脚的数据,如果脉冲上升沿时data引脚为高电平则为1并写入移位寄存器,反之则为0。
- 当使能(高电平)RCLK(latch)引脚时,移位寄存器中的数据会拷贝到第二个寄存器,存储(锁存)寄存器。其每个位(bit)均对应连接到QA-QH输出引脚,因此当存储(锁存)寄存器中内容发生变化时,相应的表现在输出引脚上。
移位寄存器和锁存寄存器原理图
实验1:使用Arduino和74HC595控制LED
实验材料
- 5mm LED *8
- 220欧电阻 *8
- 74HC595芯片 *1
- 面包板 *1
- Arduino Uno R3 *1
- 杜邦线 若干
面包板视图
Arduino代码
int latchPin = 5; //RCLK int clockPin = 6; // SRCLK int dataPin = 4; // SER byte leds = 0; void setup() { // put your setup code here, to run once: pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { // put your main code here, to run repeatedly: leds = 0; // all leds off updateShiftReg(); delay(500); for(int i=0; i<8; i++){ bitSet(leds, i); updateShiftReg(); delay(500); } } void updateShiftReg(){ digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); } |
代码解析
byte leds = 0; |
byte数据类型为8位(bit),刚好能对应8个输出以及8个led。
bitSet(leds, i); |
bitSet(x, n):设置变量的某一位(位置为1)。
- X:要设置位的变量
- n:要设置变量的哪一位,从最右边0开始为最低有效位。
updateShiftReg(); |
updateShiftReg()函数首先将latch锁存引脚置为低电平,然后调用shiftOut()移位函数,然后再将latch锁存引脚置为高电平实现输出。
shiftOut(dataPin, clockPin, LSBFIRST, leds); |
shiftOut(dataPin, clockPin, bitOrder, value)函数可以实现每次调用时对寄存器进行移位操作。
- 参数1和2位数据和时钟。
- 参数3指定从数据的那一端开始,如果从最右边的位开始向左移,则称为“Least Significant Bit First”(LSBFIRST)。反之则从左边的位开始向右移,则称为Most Significant Bit First”(MSBFIRST)。
- 参数4为实际需要进入移位寄存器的数据。允许的数据类型:byte。
实验二:使用PWM控制LED的亮度
原理:
通过控制IC的OE引脚来控制LED的亮度。OE(Output Enable)引脚位低电平有效,高电平时位禁止输出,低电平时为正常输出。当通过analogWrite() 函数使用PWM控制,则可以实现LED的亮度调节。
实际再PWM的高电平时,OE引脚会短暂的金庸IC输出,但此过程高于人眼所能感知的频率,因此能实现亮度明暗的变化。
面包板视图
Arduino代码
int latchPin = 5; //RCLK int clockPin = 6; // SRCLK int dataPin = 4; // SER int oePin = 3; // OE Ctrl PWM byte leds = 0; void setup() { // put your setup code here, to run once: pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(oePin, OUTPUT); } void loop() { // put your main code here, to run repeatedly: setBright(255); leds = 0; // all leds off updateShiftReg(); delay(500); for(int i=0; i<8; i++){ bitSet(leds, i); updateShiftReg(); delay(500); } for(byte br=255; br>0; br–){ setBright(br); delay(50); } } void updateShiftReg(){ digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); } void setBright(byte br){ analogWrite(oePin, 255-br); } |
实践:注意确认引脚连接无误后再接通电源
视频:文章修改时无法添加视频