一.介绍
双色点阵只比单色点阵多了8个 引脚,该图的点阵是共阳接法
1.74HC595原理介绍
output enable输出使能,只有使能了,才会有输出
一般来说,名字上面加一条横线,就代表了它低电平有效或者是下降沿有效
RCLK是寄存器时钟(register clock)
直接接到VCC就代表,不进行清空
SRCLR是串形清零端(serial clear)
串行时钟和串行数据
QH' 是用于多片级联
补充:串行和并行
串行通信:
串行通信:计算机与I/O设备之间,同一时刻,只能传输一个bit位的信号。传输数据按顺序依次一bit位接一bit位进行传输,通常数据在一根数据线或一对差分线上传输。比如,当传输1字节信息时,并行通讯有8根信号线实现同时传输,假如耗时为1T,而串行是在一根信号线上,把数据排成一行、一位一位传输,需要传8次,因此耗时为8T。
并行通信:
并行通信是和串行通信相对的数据传输的方式。并行通信:计算机与I/O设备之间,通过多条传输线,可以同时传输多个bit位的信号。
因此可总结出二者的特性:
并行通讯的效率高,但是成本高、对信号线路要求高,一般应用于快速设备之间近距离传输,譬如CPU 与存储设备、存储器与存储器、主机与打印机等都采用并行通讯。
串行通讯效率较低,但是对信号线路要求低,抗干扰能力强,同时成本也相对较低,一般用于计算机与计算机、计算机与外设之间远距离通讯。
本文为CSDN博主「Steven邵」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sym_robot/article/details/113182977
SERCLK需要在有上升沿的时候才能够进行移位,也就是从0变为1.而不是单独的高电平
同理RCLK也需要有上升沿。
左侧为移位寄存器,右侧为输出寄存器(存了什么就输出什么)
扩展IO口后的数据会减慢
问题:如果没有IO口的限制,可以将点阵屏的行和列引脚全部变成单片机的IO口吗?
解决:不行,由于单片机是弱上拉,它对与高电平的驱动会很弱,而对低电平的驱动会很强
类似于在VCC处接上一个电阻,而在GND处只有一根导线
即使联通,电流很弱,点阵屏也会非常暗
那如果非要这么干,那就可以在VCC处接上三极管,对电流进行放大,同时也要接上一个电阻防止被烧坏
补充:三极管发大电路
小电流控制大电流,属于电流控制型
左侧接了两个电源负极,会在高浓度N型掺杂处汇聚大量的电子
单位时间内,发生飘移运动的电子数量是填补空穴的电子的数量的β倍
两个电路的电流汇总形成发大电流
pnp型三极管给低电平的时候就会导通,给高电平的时候就会截止
npn型三极管给1的时候,三极管导通,给0的时候就截止
而74HC595高电平驱动能力依然很弱,为恒压输出(故一列中,亮度随亮灯的数目增加而减弱)
有的芯片是横流输出的(灯亮的多会加大电流)
74HC595上的8个二极管可以进行单独操作,可以用于进行测试
sfr:将寄存器的名称和对应的地址进行声明,声明之后就可以直接进行操作(是对整个寄存器而言的并不能单独操作每一位)
sbit:对寄存器的每一位进行声明,就可以对某一位单独操作而不影响其他位
&=:用于清零,0xFE与原数据相&可以清零最低位
|=:可以用于对某一位进行置1操作
^=:将某一位与1进行异或,一样就置1 ,不一样就置0;可以对某一位进行取反
2.对74HC595进行测试
以P3^5进行举例:
P3^5指的是P3的第五位(^此处的异或符号并不是异或的意思)
新版51——A2的74HC595
3.代码实现
补充:数码管的段选和位选
以数码管为例,段选就是每一个数码管的八个LED
位选
1.问题:残影
解决:消影
P0相当于位选
2.优化:
后面将P0口寄存器(只有位可以使用sbit进行改名)进行名称替换
#define MATRIX_PORT P0
进行宏定义,方便以后修改
3.完整代码实现
(1)蝴蝶结显示(固定帧)
(2)显示动画
1.模块化点阵屏
2.文字取模
3.有关报错解决
解决:
由于在两个.c文件中,都声明了全局变量i,会导致重复定义
而且Keli_C51遵循C89标准,函数体中所有变量定义必须放在开头
如果大家使用较老的编译器时遇到下面的代码可能会提示错误,因为较老的编译器要求.c文件中的局部变量定义必须放在所有执行语句前,块开头处。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int i = 0; // c89和C99都没问题
if (i > 0)
{
int j = 0; // C89和C99都没问题
}
for (int k = 0; k < 5; ++k) // C89有问题,C99正常
{
i = k;
printf("i = %d.\n", i);
}
int m = 0; // C89有问题,C99正常
}上面的程序如果在较老的编译器下使用.c文件保存并编译的时候会出错,注意,i、j的定义是没有任何问题的,因为它们都处于局部块的开始处。但是k和m的定义就会有问题,因为它们前面有可执行语句,所以m和k应该定义在i的前后。我当时使用VS2008的时候会报错,但是现在使用VS2013编译上面程序时不会有任何问题,所以,这个使用方法到底对不对,还是要看大家的编译器,C99以后基本都使用变量就近定义的方式,因为这样十分清晰。
总之,为了移植性更强一些,建议大家编写C语言的时候尽量将局部变量都定义在可执行语句前,块的开始处,这样不管是新的编译器或者老的编译器都可以正常编译。不过,随着变量定义就近原则的方便性的体现,可能使用变量就近定义会更好一些,至于如何抉择,大家可以根据项目需求和实际的情况而定。
————————————————
版权声明:本文为CSDN博主「君临丶天下」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dan15188387481/article/details/49687943
4.有关速度解释
在写移位显示的过程中,设置了变量offset,count
由于我在写代码的时候,将count和offset的循环写在了for循环里面
如图
而视频当中的代码是写在for循环的外面
下面判断哪一个方式,点阵屏帧率大
.
.
.
.
.
.
.
答案是:前者
为什么?
自我理解:count是字符,所以最大可以到253(8位2进制),前者在count满足15的时候,并没有进行清零,所以会加到250多去,相当于延时的时长比后者更长
优化:
(1)
(2)
单片机里面有两种存储
一种是程序运行时的暂存器RAM
一种是放在Flash里面的程序存储器(程序空间较RAM会大一些)
但放在falsh当中的数组元素不能进行更改,flash的内容是只读的