74HC595是一个8位串行输入、并行输出的位移缓存器:并行输出为三态输出。在SCK 的上升沿,串行数据由SDL输入到内部的8位位移缓存器,并由Q7’输出,而并行输出则是在LCK的上升沿将在8位位移缓存器的数据存入到8位并行输出缓存器。当串行数据输入端OE的控制信号为低使能时,并行输出端的输出值等于并行输出缓存器所存储的值。
注意:74HC595的移位特性是串行输入,并行输出。
引脚编号 | 74HC595D | 74HC595 | 74HC595点阵模块 | 功能介绍 |
---|---|---|---|---|
15 | Q0 | QA | \ | 一位并行输出位 |
1~7 | Q1~Q7 | QB~QH | \ | 七位并行输出位 |
8 | GND | VSS | GND | 电源地 |
9 | Q7’ | QH’ | \ | 级联位,若输入位数大于8位,先进入的位会从此口连续输出,用于多片之间的级联 |
10 | MR | SRCLR | 5V | 主复位,低有效,一般直接接到VCC拉高 |
11 | SH_CP | SRCLK | CLK | 移位寄存器时钟输入 |
12 | ST_CP | RCLK | LE | 存储寄存器时钟输入 |
13 | OE | OE | GND | 输出使能位,低有效,一般全程给低电平 |
14 | DS | SER | DI | 串行数据输入位 |
16 | VCC | VDD | 5V | 电源5V |
① 在SRCLK上升沿时,来自SER的数据可以存入移位寄存器。移位寄存器只有8位,如果数据溢出,溢出的数据从QH’输出(图中用空心箭头表示)。
② 在RCLK上升沿时,移位寄存器的8位数据全部传给存储寄存器(图中用虚线表示)。此时如果OE是低电平,8位数据会并行输出。
③ SRCLR在低电平时可以清空移位寄存器,一般只在第一次安全上电时拉低,其它时间置高。OE在低电平时允许输出,高电平输出三态。三态既不是高电平,也不是低电平,被称为高阻态。实际应用时OE常常设为低电平。
④ 假设来自于控制芯片的数据是ABCD EFGH,每个字母表示1bit数据,非0即1。那么会把高位的数字A最先存入移位寄存器,第1个数据会从QH输出,存入的第8个数据会从QA输出。
⑤ QH’ 的级联作用:
a. 应用场景:8×8 共阳极LED点阵1088BS,驱动此点阵共需要8位段选端和8位位选端,共16位串行数据输入。
b. 移位过程:SER 的数据输入端串行输入时,在 SRCLK 的上升沿将数据移入移位寄存器内,每个 SRCLK 上升沿移入一位单bit数据,最先输入的一直向后移直到8个 SRCLK 上升沿后,移位寄存器填满,此时若数据输入端还有数据输入,下一个 SRCLK 上升沿到来时,最先输入的1bit数据就会从 QH’ 输出(此处可理解为队列,先进先出)。在RCLK的上升沿,数据会从移位寄存器进入存储寄存器中,当OE低有效时,存储寄存器中的值从 QA ~ QH 并行输出。
c. 级联实现:将第一片 74HC595 的 QH’ 串行输出端接到第二片的数据输入端 SER ,实现级联功能。经过16个时钟SRCLK 上升沿后,数据已经全部移位进入移位寄存器,一次共输入16位数据,那么第一位输入的串行数据会在第二片 74HC595 芯片的 QH 输出,此时给一个上升沿的 SRCLK 信号就可以将信号移入存储寄存器,OE 信号持续给低, 即可输出。
(1) LED点阵屏简介:
通过LED(发光二极管)组成,以灯珠亮灭来显示文字、图片、动画、视频等,LED点阵显示屏制作简单,安装方便,被广泛应用于各种公共场合,如汽车报站器、广告屏、银行窗口屏、叫号屏以及停车系统等。
(4) LED点阵模块共阳极和共阴极区分:
① 根据其内部接线方式被分为两种:共阳极(BS)和共阴极(AS)。
② 共阳极即每个LED管的阳极共接在行线上,列输入的信号为1不亮,为0亮。
③ 共阴极和共阳极模块相反,每个LED管的阴极共接在行线上,列输入的信号为0不亮,为1亮。
④ 一般只需根据点阵第一个引脚的极性来定义,第一个引脚为阳极则为共阳,反之则为共阴。
74HC595点阵模块 | 功能说明 |
---|---|
DI | 串行数据输入 |
LE | 锁存器时钟输入 |
CLK | 移位寄存器时钟输入 |
NC | 空脚,不接 |
VCC | 模块供电接口,可用单片机的5V电源口供电 |
GND | 电源地 |
74HC595点阵模块 | Arduino UNO R3 |
---|---|
DI | D8 |
LE | D9 |
CLK | D10 |
VCC | 5V |
GND | GND |
(1)本实验采用Arduino UNO R3开发板及自主搭建电路的方式,实现预设功能。
(3)实现功能:点亮8*8共阳极点阵的第一个LED灯,LED位置(1,1)。
代码实现:
//8*8共阳极点阵实验
//点亮8*8共阳极点阵的第一个LED灯,LED位置(1,1)
#define DIO 8 //DI
#define S_CLK 10 //CLK
#define R_CLK 9 //LE
void setup()
{
pinMode(DIO, OUTPUT);
pinMode(S_CLK, OUTPUT);
pinMode(R_CLK, OUTPUT);
}
void loop()
{
//ROW 0x80 , COL 0xfe
int i, dat;//i循环次数 dat需要发送的数据
dat = 0xfe;//发送列值
for (i = 0; i < 8; i++) //循环8次
{
digitalWrite(S_CLK, LOW);
digitalWrite(R_CLK, LOW);
if (dat & 0x01) //发送1
{
digitalWrite(DIO, HIGH);
}
else //发送0
{
digitalWrite(DIO, LOW);
}
digitalWrite(S_CLK, HIGH);
dat >>= 1;//数据右移
}
dat = 0x80;//发送行值
for (i = 0; i < 8; i++) //循环8次
{
digitalWrite(S_CLK, LOW);
digitalWrite(R_CLK, LOW);
if (dat & 0x01) //发送1
{
digitalWrite(DIO, HIGH);
}
else //发送0
{
digitalWrite(DIO, LOW);
}
digitalWrite(S_CLK, HIGH);
dat >>= 1;//数据右移
}
digitalWrite(R_CLK, HIGH);
}
代码实现:
//8*8共阳极点阵实验
//8*8共阳极点阵,点亮指定行列LED
#define DI 8
#define CLK 10
#define LE 9
int number[16]={1,0,0,1,1,1,0,0,1,0,1,0,1,0,1,1};//列数据10011100,行数据10101011
void setup()
{
pinMode(DI, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LE, OUTPUT);
}
void loop()
{
digitalWrite(LE, LOW);//存储寄存器时钟输入,串行输入数据时置0
for (int i = 0; i < 16; i++)
{
DI_data(number[i]);//先发送列数据,再发送行数据
}
digitalWrite(LE, HIGH);//存储寄存器时钟输入,并行输出数据时置1
}
void DI_data(int num)
{
digitalWrite(CLK, LOW);//移位寄存器时钟输入,CLK为低电平
digitalWrite(DI, num);//串行数据输入
digitalWrite(CLK, HIGH);//CLK上升沿,DI发送数据
}
(1)本实验采用Arduino UNO R3开发板及自主搭建电路的方式,实现预设功能。
(3)实现功能:不用shiftOut函数,点阵显示汉字“中”。
代码实现:
//8*8共阳极点阵实验
//不用shiftOut函数,点阵显示汉字“中”
#define DI 8
#define CLK 10
#define LE 9
uint8_t ROW[8][8] = {
{0, 1, 1, 1, 1, 1, 1, 1}, //第一列
{1, 0, 1, 1, 1, 1, 1, 1}, //第二列
{1, 1, 0, 1, 1, 1, 1, 1}, //第三列
{1, 1, 1, 0, 1, 1, 1, 1}, //第四列
{1, 1, 1, 1, 0, 1, 1, 1}, //第五列
{1, 1, 1, 1, 1, 0, 1, 1}, //第六列
{1, 1, 1, 1, 1, 1, 0, 1}, //第七列
{1, 1, 1, 1, 1, 1, 1, 0} //第八列
};
uint8_t COL[8][8] = { //汉字“中”
{0, 0, 0, 1, 0, 0, 0, 0}, //第一行
{0, 0, 0, 1, 0, 0, 0, 0}, //第二行
{1, 1, 1, 1, 1, 1, 1, 0}, //第三行
{1, 0, 0, 1, 0, 0, 1, 0}, //第四行
{1, 1, 1, 1, 1, 1, 1, 0}, //第五行
{0, 0, 0, 1, 0, 0, 0, 0}, //第六行
{0, 0, 0, 1, 0, 0, 0, 0}, //第七行
{0, 0, 0, 1, 0, 0, 0, 0} //第八行
};
void setup()
{
pinMode(DI, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LE, OUTPUT);
}
void loop()
{
for (int z = 0; z < 8; z++)
{
ROW_COL(z);
}
}
void DI_data(int num)
{
digitalWrite(CLK, LOW);//移位寄存器时钟输入,CLK为低电平
digitalWrite(DI, num);//串行数据输入
digitalWrite(CLK, HIGH);//CLK上升沿,DI发送数据
}
void ROW_COL(int k)
{
digitalWrite(LE, LOW);//存储寄存器时钟输入,串行输入数据时置0
for (int i = 0; i < 8; i++)
{
DI_data(ROW[k][i]);//发送列数据
}
for (int j = 0; j < 8; j++)
{
DI_data(COL[k][j]);//发送行数据
}
digitalWrite(LE, HIGH);//存储寄存器时钟输入,并行输出数据时置1
}
(1)本实验采用Arduino UNO R3开发板及自主搭建电路的方式,实现预设功能。
(3)实现功能:用shiftOut函数,点阵显示汉字“甲”。
代码实现:
//8*8共阳极点阵实验
//用shiftOut函数,点阵显示汉字“甲”
#define LE 9
#define CLK 10
#define DI 8
unsigned int ROW_COL[8][2] = { //汉字“甲”
{0x7f, 0x00}, //第一个字节是列数据,第二个字节是行数据
{0xbf, 0x7C},
{0xdf, 0x54},
{0xef, 0x7C},
{0xf7, 0x54},
{0xfb, 0x7C},
{0xfd, 0x10},
{0xfe, 0x10}
};
void setup()
{
pinMode(LE, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(DI, OUTPUT);
}
void loop()
{
show(ROW_COL);
}
void show(unsigned int a[8][2])
{
for ( int i = 0; i < 8; i++)
{
digitalWrite(LE, LOW);
for (int j = 0; j < 2; j++)
{
shiftOut(DI, CLK, LSBFIRST, a[i][j]);//一次向移位寄存器写入一个字节(8个位)
}
digitalWrite(LE, HIGH);
}
}
参考资料1: 点阵模块原理学习
参考资料2: 电子设计教程49:16*16LED点阵屏驱动-74HC595的原理
参考资料3: 74HC595工作原理及FPGA实现数码管驱动方法
参考资料4: 《别再找了!这是有史以来最棒的Arduino教程系列》感谢佑來老师的奉献无私!
参考资料5: Arduino+2片74hc595 驱动8x8(共阳)点阵(1008BS)
参考资料6: Arduino中shiftOut怎么用?
参考资料7: 用Arduino操控STM32控制通常在51上才用的六脚8*8LED矩阵