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