介绍
74HC595是一个8位串行输入、并行输出的位移缓存器。简单的说,74HC595 可以将3个 IO口 扩展为多个IO口。
应用
74HC595 主要用来扩展IO口,如果要用一个32 IO口 的51单片机(如STC89C52
)制作一个8x8x8的光立方,就可以利用74HC595 来扩展IO口。
8x8x8 光立方仅一层就需要64个IO口来控制
引脚及功能
- 15 和 1 到 7 脚 QA-QH(Q0-Q7):并行数据输出
- 9 脚 QH (Q7`):串行数据输出
- 10 脚 SCLK (MR) : 低电平复位引脚
- 11 脚 SCK( SH_CP) : 移位寄存器时钟输入
- 12 脚 RCK( ST_CP) : 存储寄存器时钟输入
- 13 脚 G(OE) : 输出有效
- 14 脚 SER( DS) : 串行数据输入
使用方法
-
首先令
MR端口
为高电平,OE端口
为低电平(一般将 MR 接VCC,OE 接GND
) -
初始状态下,Q0 - Q7输出口都是低电平0,同时寄存器中的值都是0(黄色的管道代表寄存器)
-
当
SH_CP端口
产生高脉冲时,DS 端口
的值会被压入寄存器,此时,寄存器中的位会下移一位,而最后一位会被挤出寄存器
-
当
ST_CP端口
产生高脉冲时,寄存器中的值会被输出到对应端口
使用示例
#include "reg52.h"
#include <intrins.h>
typedef unsigned char u8;
sbit SH = P2^0;
sbit ST = P2^2;
sbit DS = P2^1;
void main()
{
// 首先将ST_CP和SH_CP端口置为低电平,为后面产生高脉冲做准备
ST = 0;
SH = 0;
DS = 1; // 输入一个数据(0或1)
_nop_(); // 延时一下,因为产生高脉冲需要一定时间
SH = 1; // SH_CP端口产生高脉冲,DS端口的数据被压入寄存器
_nop_(); // 延时一下,因为产生高脉冲需要一定时间
ST = 1; // ST_CP 端口产生高脉冲,寄存器中的值输出到对应端口
while(1); // 无限循环,防止程序退出
}
运行结果如下:
我们可以根据这个原理,用3个IO口驱动8位流水灯:
#include "reg52.h"
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit SH = P2^0;
sbit ST = P2^2;
sbit DS = P2^1;
void sendDataTo595(u8 dat)
{
int i;
ST = 0;
for(i=0; i<8; i++)
{
SH = 0;
DS = dat >> 7;
dat <<= 1;
_nop_();
SH = 1;
_nop_();
}
ST = 1;
}
void delay(u16 n) // 12MHZ晶振毫秒延时函数
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
void main()
{
u8 ch = ~0x01;
while(1)
{
sendDataTo595(ch);
ch = _crol_(ch, 1);
delay(300);
}
}
运行结果如下:
级联
被挤出寄存器的值并没有消失,而是输出到了 Q7’ 端口。
根据这个原理,我们可以将一个74HC595的 Q7’ 端口与下一个的 DS 端口连接起来,使其可以操作更多的IO口。
下面,我们来利用3个IO口来驱动16位流水灯:
#include "reg52.h"
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit SH = P2^0;
sbit ST = P2^2;
sbit DS = P2^1;
void sendDataTo595(u16 dat)
{
int i;
ST = 0;
for(i=0; i<16; i++)
{
SH = 0;
DS = dat >> 15;
dat <<= 1;
_nop_();
SH = 1;
_nop_();
}
ST = 1;
}
void delay(u16 n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
void main()
{
u16 ch = ~0x0001;
while(1)
{
sendDataTo595(ch);
ch = _irol_(ch, 1);
delay(300);
}
}
运行结果如下: