Bootstrap

控制组——LED点阵屏学习笔记

LED点阵屏

介绍

LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列,以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合,如汽车报站器、广告屏以及公告牌等
LED点阵屏分类按颜色:单色、双色、全彩按像素:88、1616等 (大规模的LED点阵通常由很多个小点阵拼接而成)

双色点阵屏实际上可以显示三种颜色:每个点位有红色和蓝色两个LED,若同时显示则为黄色
大规模的点阵的行数/列数通常也设为8的倍数,可以避免内存浪费

显示原理

内部结构图:

可见8x8的单色LED点阵屏有十六个引脚,双色的有24个引脚
LED点阵屏的结构类似于数码管,只不过是数码管把每一列的像素以“8”字型排列而已
LED点阵屏与数码管一样,有共阴和共阳两种接法,不同的接法对应的电路结构不同
LED点阵屏需要进行逐行或逐列扫描,才能使所有LED同时显示
引脚对应关系:
在这里插入图片描述
在这里插入图片描述

74HC595

在这里插入图片描述
OE:output enable 输出使能,决定芯片能否输出,故使用时将JOE中的OE与GND连接,以读取输出数据
RCLK:register clock 寄存器时钟,决定数据输出与否
SRCLR:serial clear 串行数据清空
SRCLK:serial clock 串行时钟,决定上升沿移位频率
SER: 串行数据,具体数据输入端
QH‘:多片级联端,用于向下一片74HC595传输数据
通过对RCLK、SRCLK、SER赋值来进行输入,OE和SRCLR通过硬件处理

名称上面加一横线,代表该位为低电平有效或下降沿有效

74HC595是串行输入并行输出的移位寄存器,可用3根线输入串行数据,8根线输出并行数据,多片级联后,可输出16位、24位、32位等常用于IO口扩展
在这里插入图片描述
串行输入:
数据”个别地“输入,每次输入一位传输到寄存器
并行输出:
数据”整体地“输出,八位为整体同时输出给另一端
上升沿移位:由串行时钟控制,时钟每到达计时点一次(SERCLK值变为1),寄存器中的数据整体下移一位
上升沿锁存:由寄存器时钟控制,时钟每到达计时点一次(RCLK值变为1),寄存器中数据同时输出到“Q端”

三极管的使用

若想用电池直接接到LED点阵屏的I/O口上来供电,由于单片机I/O口的弱上拉模式,给高电平时点阵屏会比较暗,此时就可以用三极管来进行电平转换,使点阵屏变亮
PNP型:给0(低电平)时运作,导通VCC、电阻和I/O口的连接,给1时截止
NPN型:给1(高电平)时运作,导通VCC、电阻和I/O口的连接,给0时截止

使用74HC595来减少串口时,是直接通过芯片输出的,为恒压输出,会导致同一列/行上亮的LED数量较多时,亮度较暗,数量较少时则较亮
更好的有恒流输出的点阵屏,会自动根据此列/行上要亮的LED数量来改变电压,保证亮度统一

具体应用

图形显示

#include <REGX52.H>
#include "Delay.h"

sbit RCK=P3^5;	//对该地址做新声明,便于代码理解
sbit SCK=P3^6;
sbit SER=P3^4;

void _74HC595_WriteByte(unsigned char Byte)
{
	unsigned char a;
	for(a=0;a<8;a++)
	{
		SER=Byte&(0x80>>a);
		SCK=1;
		SCK=0;
	}
	RCK=1;
	RCK=0;
}
//通过74HC595来写入段码,参数为十六进制段码(对D即行的选择)
void MetrixLED_Show(unsigned char Column,Data)
{
	_74HC595_WriteByte(Data);  //先选行or先给高电平
	P0=~(0x80>>Column);		//再选列or再给低电平
	Delay(1);
	P0=0xFF;
	//先后顺序若错误,易导致显示错误,比如亮度改变或错位显示
}

void main()
{
	SCK=0;
	RCK=0;

	while(1)
	{
	MetrixLED_Show(0,0x3C);
	MetrixLED_Show(1,0x42);
	MetrixLED_Show(2,0xA9);
	MetrixLED_Show(3,0x85);
	MetrixLED_Show(4,0x85);
	MetrixLED_Show(5,0xA9);
	MetrixLED_Show(6,0x42);
	MetrixLED_Show(7,0x3C);
	}
}

这里用的MetrixLED_Show函数每次只使8x8矩阵中的一个LED亮,故想实现目的,就应将所有MetrixLED_Show函数放到while循环中,通过类似于扫描的方式来使多位LED同时亮

流动动画

流动动画的实现用到了数组来存储一长条Data,通过对取值范围的控制,实现了画面的“流动”/逐帧显示
由于我们的点阵屏大小有限,而一长条数据大概都要32位或64位等,要通过显示来逐一写出所对应的Data很耗费时间,故用到了文字采膜工具
在这里插入图片描述
新建图像——放大格点——文字输入或直接在点阵中点出所要显示的数据——点阵生成(C51格式)——复制到数组中

#include <REGX52.H>
#include "Delay.h"

sbit RCK=P3^5;
sbit SCK=P3^6;
sbit SER=P3^4;

void _74HC595_WriteByte(unsigned char Byte)
{
	unsigned char a;
	for(a=0;a<8;a++)
	{
		SER=Byte&(0x80>>a);
		SCK=1;
		SCK=0;
	}
	RCK=1;
	RCK=0;
}

void MetrixLED_Show(unsigned char Column,Data)
{
	_74HC595_WriteByte(Data);
	P0=~(0x80>>Column);
	Delay(1);
	P0=0xFF;
}

unsigned char code Animation[]=
// code 代表数组中的数据放到了FLASH中,而非RAM里,好处是不会占用内存本就不多的RAM太多内存,但在后续操作中无法进行更改 
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0x08,0x08,0x08,0xFF,0x00,0x0E,0x15,
0x15,0x15,0x08,0x00,0x7E,0x01,0x02,0x00,
0x7E,0x01,0x02,0x00,0x0E,0x11,0x11,0x0E,
0x00,0x7D,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
}
;
unsigned char i,offset,count;

void main()
{
	RCK=0;
	SCK=0;
	//单片机给电时两个时钟得到高电平值变为1,故须进行初始化清零
	while(1)
	{
		for(i=0;i<8;i++)
		{
			MetrixLED_Show(i,Animation[i+offset]);
			//offset即偏移,每过一段时间offset加一,动画跳一帧
		}
		count++;
		if(count>10)
		{
			offset++;
			count=0;
		}
		if(offset>36)
			offset=0;
	
	}
}

这里每一帧动画的切换间隔是不明确的,是通过循环的次数来进行切换,若想以一定的精准频率来逐帧流动,需用到定时器。

;