51单片机LED点阵控制原理、74HC595工作原理及字母滚动显示实验代码详解
目录
1. 74HC595工作原理图解
2.LED点阵控制原理
3.点阵LED实验
3.1 配置74HC595代码
3.2 D点阵LED显示H
3.3 滚动LED
(1) 滚动扫描图示
(2)程序代码
4.遇到奇怪的bug
1. 74HC595工作原理图解
: 输出使能,输入低电平允许输出,因此需要用接线帽j24让oe和地短接。(但是我普中A2的板子,不管oe接vcc还是gnd都能输出,奇了怪了,不知道是不是个例)
:低点平时将移位寄存器的数据清零,因此常接高电平VCC
:上升沿时数据寄存器的数据移位。QA–>QB–>QC–>…–>QH(如果有扩 展,还会移到QH'),下降沿移位寄存器数据不变
: 串行数据输入端
: 上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。
QA–QH: 八位并行输出端。 QH': 级联输出端。将它接下一个 595 的 SER 端。
要输入的数据串行的从 输入移位寄存器,当
上升沿,比特数据在移位寄存器中移动(往高地址)。当
上升沿时移位寄存器的数据进入数据存储寄存器,最终并行的发送出Q1-QH口。
如果你需要级联(可能为了扩展更多IO口),当移位寄存器继续移位,最高位会溢出通过下一个595芯片进入其移位寄存器。
2.LED点阵控制原理
LED点阵排列呈矩阵状排布,P35,P34,P36通过74HC595芯片控制每一行LED正极,P00~P07连接每一列阴极。这样连接一方面也因为该单片机芯片是弱上拉,强下拉。
一行,一列可以确定一个LED,一个时刻只能操作一行或一列上的LED,有关显示图形的(涉及多行多列’同时‘显示),可以类似数码管显示多位,在LED点阵上逐行或逐列扫描,利用电子电路的快,骗过眼睛。
3.点阵LED实验
3.1 配置74HC595代码
因为RCLK与头文件<REGX52.H>中RCLK重名,我们换一个位变量名RCK
sbit RCK = P3^5; sbit SRCLK = P3^6; sbit SER = P3^4; //sbit只能在外部定义全局变量,是SFR(特殊功能寄存器)的bit
3.2 D点阵LED显示H
#include <REGX52.H> #include <Delay1ms.H> sbit RCK = P3^5; sbit SRCLK = P3^6; sbit SER = P3^4; /*74HC595输出byte*/ void _74Hc595_WriteByte(unsigned char byte) { unsigned int i; //将形参byte从高位到低位输入移位寄存器 for(i=0;i<8;i++) { SER = byte&(0x80>>i); SRCLK = 1;//上升沿接收SER并移位 SRCLK = 0;//复位 } RCK = 1;//将移位寄存器并行发送到数据寄存器最终输出 RCK =0;//复位 } /*选择在led点阵上第0列到第7列(共8列)上第Column列,根据Data二进制0/1显示led*/ void MatrixLed_ShowColumn(unsigned char Column,Data) { _74Hc595_WriteByte(Data); P0 = ~(0x80>>Column);//P0控制着选择第几列被选中 Delay1ms(1);//太快切换会暗 P0 = 0xFF;//消影 } int main() { SRCLK = 0; RCK = 0; while(1) { //快速的依次在八列上显示 MatrixLed_ShowColumn(0,0x00); MatrixLed_ShowColumn(1,0xFF); MatrixLed_ShowColumn(2,0x10); MatrixLed_ShowColumn(3,0x10); MatrixLed_ShowColumn(4,0x10); MatrixLed_ShowColumn(5,0x10); MatrixLed_ShowColumn(6,0xFF); MatrixLed_ShowColumn(7,0x00); } }
3.3 滚动LED
(1) 滚动扫描图示
………………移动
接下来,重新回到,同时因为前后的空白,能够不至于滚动到E后突然跳到L,而是跳到L前面空白,让滚动更平滑。
(2)程序代码
#include <REGX52.H> #include <Delay1ms.H> sbit RCK = P3^5; sbit SRCLK = P3^6; sbit SER = P3^4; //存放要滚动字母形的每一列74HC595输出二进制状态,如上图0x行所写 unsigned char Scroll_letter[44] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x01,0x01,0x01,0x3c,0x42,0x81,0x81,0x42,0x3c,0x00,0x80,0x60,0x18,0x06,0x01,0x06,0x18,0x60,0x80,0x00,0xff,0x91,0x91,0x91,0x91,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //可以unsigned char code Scroll_letter[44] 将该数组放到flash程序存储空间里,不占用RAM,但是这样无法更改数组 void _74Hc595_WriteByte(unsigned char byte) { unsigned int i; for(i=0;i<8;i++) { SER = byte&(0x80>>i); SRCLK = 1; SRCLK = 0; } RCK = 1; RCK =0; } void MatrixLed_ShowColumn(unsigned char Column,Data) { _74Hc595_WriteByte(Data); P0 = ~(0x80>>Column); Delay1ms(1); P0 = 0xFF; } int main() { //偏移量,led最多显示8列,而偏移量决定显示从Scroll_letter数组那一列开始的八列 unsigned char start_col = 0; //i决定显示led中八列中任何一列 //count也是为了保证滚动平滑型 unsigned char i,count=0; SRCLK = 0; RCK = 0; while(1) { for(i=0;i<8;i++) { MatrixLed_ShowColumn(i,Scroll_letter[start_col+i]); } count++; //让每八列停留10个count自加时间(也可以用定时器) if(count>10) { count = 0; start_col++; } //当偏移量走到能和i能把最后一个字母E都显示完,则重新滚动 if(start_col==36) start_col=0; } }
4.遇到奇怪的bug
/* 将第一行第一列灯点亮 */
#include <REGX52.H> sbit RCK = P3^5; sbit SRCLK = P3^6; sbit SER = P3^4; void Column1_74Hc595_WriteByte(unsigned char byte) { unsigned char i; P0_7 = 0;//第一列被选中,阴极赋低电平 for(i=0;i<8;i++) { SER = byte&(0x80>>i);// 当byte=0x80 即 1000 0000 ,则第一行赋高电平 SRCLK = 1; SRCLK = 0; } RCK = 1; RCK =0; } int main() { SRCLK = 0; RCK = 0; //将第一行第一列灯点亮 Column1_74Hc595_WriteByte(0x80); while(1) { } }
点亮了:
复位后,灭了:
/* 将第一列灯点亮 */
#include <REGX52.H> sbit RCK = P3^5; sbit SRCLK = P3^6; sbit SER = P3^4; void Column1_74Hc595_WriteByte(unsigned char byte) { unsigned char i; P0_7 = 0;//第一列被选中,阴极赋低电平 for(i=0;i<8;i++) { SER = byte&(0x80>>i);// 当byte=0xff 即 1111 1111 ,则八行都赋高电平 SRCLK = 1; SRCLK = 0; } RCK = 1; RCK =0; } int main() { SRCLK = 0; RCK = 0; //将第一列灯点亮 Column1_74Hc595_WriteByte(0xff); while(1) { } }
点亮了:
复位后,还是点亮了: