- 在LED点阵上绘制图案最主要的应用两个模块:
- LED点阵模块(笔者所用的是16*16)
- 74HC595模块
首先介绍74HC191模块,该模块最主要的功能就是扩展C51的IO口,实现串转并的功能。该模块的内部结构这里就不多说,主要来讲解一些如何使用。
一般来说买来的74HC191模块中,RCK,SCLK,SER三个管脚会被引出,前两个分别是存储寄存器的时钟输入和移位寄存器的时钟输入,SER是串行数据的输入端,我们也是通过这三个管脚与C51的IO口进行连接。
此外,QAX系列都是并行数据的输出端,可以跟受控的模块相连。
- 了解到这几个管脚就可以愉快的联线以及编程了!
接下来我们看一下如何把数据传入595模块进行处理
typedef unsigned int u16;
typedef unsigned char u8;
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^6;
//通过595发送一个字节的数据
void HC595(u8 dat)
{
u8 a;
SRCLK = 1;
RCLK = 1;
for(a=0;a<8;a++) //循环八次传入一个字节
{
SER=dat>>7;
dat<<=1;
SRCLK=0;
_nop_();
_nop_();
SRCLK=1;
}
RCLK=0;
_nop_();
_nop_();
RCLK=1;
}
接下来介绍以下LED点阵模块,这个模块只要记住四个字就是“行高列低”,意思是如果要点亮点阵中某一个LED,应该要控制它的行管脚输入高电平,列管脚输入低电平。
- 那么如何降两者结合起来,显示出图像或者字符呢?
由于笔者使用的是16 * 16的点阵,4个595芯片级联。于是我们把点阵分成四块。
右下-左下-右上-左上,每一块为8*8。
为了让不同位置的LED同时亮起,我们采用动态显示扫描的方法。这里的扫描时间小于人肉眼可以识别的时间。
接线:74HC595的三个输入端根据定义分别与单片机的IO端相连,595的A的输出端与控制LED点阵的上半屏的输入端相连,B与下半屏相连。
取字模:可以使用字模提取软件或者把二进制数据自己算成16进制
以下是我字模提取的结果(设计的是贱贱的yas queens)
它生成的段选结果,而位选扫描要我们自己写
比方说:
u8 code ledwei[]=
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
};
编程:
#include "reg51.h"
#include "intrins.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
u8 code ledwei[]=
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
};
u8 code ledduan[]=
{
0x07,0x18,0x07,0xC0,0x5E,0xC5,0x1E,0x00,0xD7,0x15,0xDD,0x00,0x00,0x00,0x00,0x00,
0x00,0xF8,0xA8,0xAB,0x02,0xFB,0xAA,0xA8,0x03,0xFA,0x0B,0xF8,0x00,0xB8,0xA8,0xE8,
};
void delay(u16 i)
{
while(i--);
}
//通过595发送四个字节的数据
void HC595(u8 dat1,u8 dat2,u8 dat3,u8 dat4)
{
u8 a;
SRCLK = 1;
RCLK = 1;
for(a=0;a<8;a++) //右下
{
SER = dat1>>7;
dat1<<=1;
SRCLK = 0;
_nop_();
_nop_();
SRCLK = 1;
}
for(a=0;a<8;a++) //左下
{
SER = dat2>>7;
dat2<<=1;
SRCLK = 0;
_nop_();
_nop_();
SRCLK = 1;
}
for(a=0;a<8;a++) //右上
{
SER = dat3>>7;
dat3<<=1;
SRCLK = 0;
_nop_();
_nop_();
SRCLK = 1;
}
for(a=0;a<8;a++) //左上
{
SER = dat4>>7;
dat4<<=1;
SRCLK = 0;
_nop_();
_nop_();
SRCLK = 1;
}
RCLK=0;
_nop_();
_nop_();
RCLK=1;
}
void main()
{
u8 i;
while(1)
{
for(i=0;i<16;i++)
{
HC595(~ledwei[i+16],~ledwei[i],ledduan[16+i],ledduan[i]);
delay(10);
}
}
}
附上成果图