电路及驱动原理
上图是CS1088B的8x8
LED点阵的部分技术文档截图,最下面就是这个点阵模块的基本电路图。
其实很简单,每一横行控制LED的一极,每一竖列又控制LED的另一极。又因为是一个矩阵,所以每一个LED都有一个控制其单独发光的一个二进制值,能控制8x8坐标轴上任意一个LED的亮灭。
举个例子,假设每一横行我都接LED的正极,即基本电路图中的位置9、14、8、12、1、7、2、5位置,都接主机(如第一片74HC595D)的正极(如第一片74HC595D的8个并出口QA~QH),每一列我都接LED的负极即基本电路中
的位置13、3、4、10、6、11、15、16,都接主机(如第二片)的负极(如第二片74HC595D的8个并出口QA~QH)。
连接好以后,等于构成了完全控制LED正负极电平的能力,在程序中给8x8坐标轴内对应的LED点发送指定的高低电平信号就可以灵活控制其的亮灭。
电路图
以上为两片74HC595D串联后和8x8点阵连接的电路图,单片机和74HC595D连接省略。
注意:
控制LED点阵行(正极)的,第一片的QA要从LED点阵的正向的从上往下数,第一行开始连接,一直连接到第一片的QH结束
控制LED点阵列(负极)的,第二片的QA要从LED点阵正向从左往右数,第一列开始连接,一直连接到第二片的QH结束
这里的连接开始和结束顺序直接决定了后面程序中向74HC595D芯片送入的16位数据中,每个二进制位对应控制的行和列,所以一定要连接正确
规律:每颗LED的正极都接横行,每颗LED的负极都接竖列
规律:第一片74HC595D控制LED点阵的横行,第二片74HC595D控制LED点阵的竖列
电路图和实物电路对照
对应实际焊接完成的电路,方向、位置对应如下图:
此电路板是7cmx9cm的,底部标有“7CM*9CM”字样的,就是将来显示汉字的底边,对应的一边就是汉字的顶边。这幅图就是字体正确的显示方向。
红色字标出的位置分别接第一片74HC595D的8个并出口,来控制ELD点阵的正极;蓝色字标出的位置分别接第二片74HC595D的8个并出口,来控制ELD点阵的负极。
电路图和实物电路对照:
这样将实物和电路图对照一下,就很清晰了。在焊接上为了方便和美观,接第二片的负极(列)做了个右侧的走向。
理解74HC595D工作原理
常规情况下,电路中使用单颗74HC595D芯片,从串行数据的输入到并行数据的输出,要经历以下3个步骤:
向74HC595D的SI引脚输送一个数据并向SCK引脚做上升沿后,数据将会进入移位寄存器中,数据依次从QH引脚逐个向QA引脚方向移动,直到8位数据全部输入完毕
输入完毕后,向RCK引脚做上升沿,将移位寄存器中的8位数据拷贝到锁存器中固化、锁定
如果OE引脚一直是输出使能的,则会立即并行输出8位数据到QA~QH引脚上
注意:
第1步中向SI输送8位串行数据时,最先送入的数据在最高位,即QH引脚对应的移位寄存器中,而不是QA引脚。第二送入的数据在次高位,即QH引脚对应的以为寄存器中。最后送入的一位数据在最低位,即QA引脚对应的移位寄存器中。
74HC595D的串行数据移位遵循“先送高位,再送低位,由高位至低位输送”的原则。
这一点一定要理解清楚,这对后面理解16位数据每一位如何控制LED点阵的行和列至关重要
16位二进制数控制点阵的行与列
刚才有提到,后面写程序控制点阵时,要向74HC595D发送16位二进制数据。
两片74HC595D串联后,就有16个并出引脚,正好对应这16位二进制数据。其中的8位数据控制行,另外8位数据控制列。
下面来看一个示意图,看看16位二进制数中的每一位是如何控制行和列的:
再次回顾电路图:
第一片74HC595D的8个并出引脚,分别连接LED点阵每一行的正极位置,即:第一片74HC595D控制行
第二片74HC595D的8个并出引脚,分别连接LED点阵每一列的负极位置,即:第二片74HC595D控制列
注意:
由于两片74HC595D是串联的,也就是说,如果先发送了一个8位数据,那么是先会进到第一片74HC595D的锁存器中的。**同时遵循“先送高位,再送低位,由高位至低位输送”的原则,最先送入的数据在最高位(QH引脚对应的移位寄存器中),最后送入的数据再最低位(QA引脚对应的移位寄存器中)。
此时第一片74HC595D中已有8位数据了。再继续发送8位数据,那么在第一片74HC595D中的8位数据,会被逐次挤到第二片74HC595D中。也就是说,第一片74HC595D移位寄存器中的8位数据是第二次发送的新的8位数据。
实验分析:让LED点阵第二行第二列的LED单独亮起
再来分析一下这个电路图。
第一片74HC595D的8个并行输出引脚,分别连接LED点阵每一行的正极位置。
即:第一片74HC595D控制行。那么想要某个LED亮,这个LED所在行必须要输入高电平
第二片74HC595D的8个并行输出引脚,分别连接LED点阵每一列的负极位置。
即:第二片74HC595D控制列。那么想要某个LED亮,这个LED所在行必须要输入低电平
上面两个条件必须同时成立,某个LED才会因为两端有电位差而亮起。
再回顾上图,总结如下:
16位二进制数中的第1~第8位,依次控制LED点阵的列。
16位二进制数中的第9~第16位,依次控制LED点阵的行。
因为两片74HC595D串联后,第一次8位串行数据输入完毕后,再输入另外8位串行数据,第一次输入的8位穿行数据会被挤进第二片74HC595D的移位寄存器中。再结合电路图中,LED点阵的每一横行接第一片74HC595D,LED点阵的每一竖列接第二片74HC595D,所以,在16位二进制数中,我们要先把前8位先输入进去,就能控制列(因为先输入8位数据会挤进第二片74HC595D中,第二片74HC595D连着每颗LED的负极),再把后8位输入进去,就能控制行(因为后输入的8位数据会进到第一片74HC595D中,第一片74HC595D连着每颗LED的正极)。
再根据电路图,先绘制一下如果要单独点亮第二行第二列的LED,每行每列二进制的值是多少:
上面提到过,LED接正极的位置,提供高电平,并且LED接负极的位置提供低电平,两个条件都满足,才能使LED点亮。那么可以得出:
行(从上到下)(对应第一片74HC595D)值依次为:0 1 0 0 0 0 0 0
列(从左到右)(对应第二片74HC595D)值依次为:1 0 1 1 1 1 1 1
以上16位值就是单独点亮第二行第二列的LED的正确值。但是顺序还需要验证一下,要和电路图对应。
按照“先输入列,后输入行”的规律,先要输入第二片74HC595D的8位串行数据。那么每一次输入到芯片内的原理释义如下:
第二片74HC595D – 第1次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 空 空 空 空 空 空 空
第二片74HC595D – 第2次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 0 空 空 空 空 空 空
第二片74HC595D – 第3次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 0 1 空 空 空 空 空
第二片74HC595D – 第4次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 0 1 1 空 空 空 空
第二片74HC595D – 第5次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 0 1 1 1 空 空 空
第二片74HC595D – 第6次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 0 1 1 1 1 空 空
第二片74HC595D – 第7次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 0 1 1 1 1 1 空
第二片74HC595D – 第8次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 1 0 1 1 1 1 1 1
可以看到上面8次输入串行数据,每一次输入进去的新数据用红色加粗字体表示。确实是由高向低位逐个送入的。
按照“先输入列,后输入行”的规律,再输入第一片74HC595D的8位串行数据。那么每一次输入到芯片内的原理释义如下:
第一片74HC595D – 第9次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 空 空 空 空 空 空 空
第一片74HC595D – 第10次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 0 空 空 空 空 空 空
第一片74HC595D – 第11次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 1 0 空 空 空 空 空
第一片74HC595D – 第12次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 1 0 0 空 空 空 空
第一片74HC595D – 第13次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 1 0 0 0 空 空 空
第一片74HC595D – 第14次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 1 0 0 0 0 空 空
第一片74HC595D – 第15次输入串行数据:1
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 1 0 0 0 0 1 空
第一片74HC595D – 第16次输入串行数据:0
并出引脚符号 QH QG QF QE QD QC QB QA
锁存器(存储寄存器)
移位寄存器
SI串行输入数据 0 1 0 0 0 0 0 0
可以看到上面8次输入串行数据,每一次输入进去的新数据用红色加粗字体表示。确实是由高向低位逐个送入的。
注意:
要深刻理解为什么会这样变化,并且这样位移后是怎么对应到下图的LED点阵中的
以上规律,如下图所示:
图中,游泳圈位置就是要单独点亮的第二行第二列的LED。
图中,底部和右侧分别写着“行 rows”和“列
cols”箭头指向的顺序,就是行和列上二进制数字排列的顺序,以此构成16位二进制数。
每一位对应控制的行和列都用彩色线条对应连接表示。
实验验证,编写程序:让LED点阵右上角的LED单独亮起
源代码:
/**
* 单文件实验程序
* 两片74HC595D串联后,控制5*6LED点阵
*
* Created by SteveJrong on 2019/12/22.
* Version: 1.0
*
* Copyright 2019 SteveJrong. All rights reserved.
*/
#include<reg52.h>
// 定义STC89C52RC给74HC595D输入串行数据的引脚(物理编号:14)
sbit SI_DS = P1 ^2;
// 定义STC89C52RC连接74HC595D存储寄存器的引脚(物理编号:12)
sbit RCK_STCP = P1 ^3;
// 定义STC89C52RC连接74HC595D移位寄存器的引脚(物理编号:11)
sbit SCK_SHCP = P1 ^4;
// 定义STC89C52RC连接74HC595D移位寄存器清零输入的引脚(物理编号:10)
sbit SCLR_MR = P1 ^5;
// 定义STC89C52RC连接74HC595D输出使能控制端的引脚(物理编号:13)
sbit G_OE_SHCP = P1 ^6;
void delay(unsigned int n) {
int i, j;
for (i = n; i > 0; i--)
for (j = 110; j > 0; j--);
}
/**
* 并行输出数据
* 向74HC595D的锁存器(存储寄存器)时钟输入引脚发送高低电平信号,通知74HC959D将存在锁存器内的数据并行输出到QA~QH引脚上
*/
void lighting() {
RCK_STCP = 1;
delay(1);
RCK_STCP = 0;
}
void disable_output() {
G_OE_SHCP = 1;
}
void enable_output() {
G_OE_SHCP = 0;
}
/**
* 发送串行数据到74HC595D
*
* @param inputData 要传入的数据
*/
void send_data(int binaryArray[]) {
int i = 0;
for (; i < 16; i++) {
SI_DS = binaryArray[i];
SCK_SHCP = 0;
SCK_SHCP = 1;
}
}
/**
* 主入口
*/
void main() {
int i = 0, j = 0, binaryArray[1][16] = {
{1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0},
};
// 初始时,存储寄存器置为低电平
RCK_STCP = 0;
// 初始时,移位寄存器置为低电平
SCK_SHCP = 0;
enable_output();
for (; i < 1; i++) {
send_data(binaryArray[i]);
lighting();
}
}
实验验证,效果:让LED点阵右上角的LED单独亮起
可以看到,程序预期执行,点亮了第二行第二列的LED。
汉字程序
项目仓库地址:
https://gitee.com/stevejrong1024/festive-lantern.git
文件:
labs / lab5.c
另外在以下位置增加了一个8x8点阵的16位二进制数生成器,就不用一个个对着电路图去手写了。网页上勾选好checkbox以后,直接粘贴进ten这个三维数组中即可。注意要改三维数组中一维和二维的数组总长度:
labs / lab5-led-font-generator / led-font-generator.html
已知问题:
如果同时显示的LED点较多,整体显示时的闪烁频率会稍慢一些,不知道是什么原因,STC
89C52RC性能不足?
STC 89C52RC RAM太小,显示的文字多了会造成编译后的文件过大,写不进单片机中,提示空间不足。后期计划使用STC89C516替换之。
直接写二进制的办法挺笨的。原来想着直接写16进制数,写一些方法转换成二进制数,就不用写这么多0和1了,但是试了很多种方法,在电脑的IDE上跑的没毛病,但是烧录进单片机后,就不是IDE中的结果了。可能单片机还是有局限性吧,有些功能不能被很好的支持?!
总结
想要循环显示汉字,不能用任何延时函数,延时可以用空循环。
原先看到网上的一个74HC595D的位移原理,理解成了先送低位再送高位,这也符合正常人的理解逻辑。但后来在写文档的时候总发现16进制数和引脚的接法对不上,但是LED确实又亮起了。后来正确的是先送高位再送低位,这样才对的上。
焊功差,焊接51最小系统时出了不少问题,需要多焊接。
脑子想不出来时,纸上画一画,什么都有了。
评论(0)
您还未登录,请登录后发表或查看评论