16×16LED点阵屏原理图及驱动程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
16×16LED点阵屏原理图及驱动程序
这是我玩LED点阵屏的第一块电路板,也是学习单片机入门的第一个实验器材。
它由4片30mm×30mm的8×8红色高亮点阵模块与两片74HC595、两片74HC138、16只8550晶体管、一片74HC244集装在一块宽高65mm×210mm的双面PCB板上,它应该是一组级联安装的LED 屏的一个单元模块,拿到它时,我正在学习《无线电》杂志2007/11期刊上杜洋的一组文章,刚刚做好了ISP下载线,只做了“一个发光二极管的控制实验”,面对这个既好玩又陌生的玩意,真是无从下手,通过上网学习,解析研究,前后弄了两个多月,最后在《无线电》杂志2005/12期的配文程序的帮助下,终于踏进了点阵控制的门槛,两年过去了,我又玩了许多单片机控制器件,但这块屏却一直摆在我的桌案上,每当遇到难题时,看看它那稳定清晰的显示,我都能找到许多灵感;最近、在摆弄一块并行驱动的16×64点阵屏时(前几篇文章介绍了)时,因为用的还是这段程序,就又想起了它,虽然程序已经详解过了,但是,为了留记一段经历、一段回忆,决定还是“貂续狗尾”写在这里,留着自己欣赏吧。
一.原理图:
二.汉字左右移动驱动程序
/****************************************************************************** ********
16×16LED点阵屏原理图及C源汉字左右移动显示驱动程序————wannenggong
单片机:AT89S52
引脚说明:P0.0/P0.1/P0.2/P0.3控制由两片74HC138组成的行驱动控制4-16译码器的A/B/C/D端
P1.0/P1.1控制列驱动控制74HC595的OE/ST端,595的14脚(DS)经244连接RXD,595的12脚(SH)经244连接TXD。
******************************************************************************* ********/
#include <AT89x51.H>
#define uchar unsigned char
#define uint unsigned int
#define K 5 //移动速度控制变量。
uchar col,disrow; //列移动计数变量。
行扫描计数变量。
uint word,zishu; //字形码计数变量。
uchar code HZ[];
uchar BUFF[5]; //64列时应将数值设为11
void two_out(); //显示数据输出函数
void loadoneline_L(void); //取字码数据函数
//void loadoneline_R(void);
void sendoneline_L(void); //生成显示数据函数
//void sendoneline_R(void);
/********************************************************************
关于595第13脚的问题:原附图中13脚是接GND的,是电路板的原始设计,调试过程中将IC引脚与电路板隔离后经244引出做为OE引脚,其作用仅为配合延时适度的调整屏显亮度,若13脚接GND,则为全亮度显示,与其他控制并无干涉。
********************************************************************/
sbit OE=P1^0; //显示开关(595第13脚)。
sbit ST=P1^1; //锁存控制(595第11脚)。
此处原错标为12脚,特此更正!
/****************************************************************************** *******/
void delay(uint p){
uint i,j;
for(i=0;i<p;i++){
for(j=0;j<5;j++)
{;}}
}
/****************************************************************************** ********
左移显示数据生成模块:(功能相当于有返回值的函数 )
******************************************************************************* ********/
uchar two_onebyteL(uchar h1,uchar h2)
{
uchar temp,tempcol; //输出变量;列移动位数变量。
if(col<8) tempcol=col;
else tempcol=col-8;
temp=(h1<<tempcol)|(h2>>(8-tempcol)); //左移显示
temp=255-temp;
return temp; //将显示数据返回显示输出函数。
}
/**************************************************************************
右移显示数据生成模块:
***************************************************************************/ /*uchar two_onebyteR(uchar h1,uchar h2)
{
uchar temp,tempcol;
if(col<8) tempcol=col;
else tempcol=col-8;
temp=(h1>>tempcol)|(h2<<(8-tempcol)); //右移显示
temp=255-temp;
return temp;
}*/
/****************************************************************************** *******
左移待显示数据调取函数
******************************************************************************* ******/
void loadoneline_L(void)
{
char s; //此处不要用uchar定义s
for(s=0;s<2;s++) //s值为屏数加1(16*16为一屏)
{
BUFF[2*s]=HZ[word+32*s+2*disrow];
BUFF[2*s+1]=HZ[word+1+32*s+2*disrow]; //左移显示
}
}
/****************************************************************************** ******
右移待显示数据调取函数
******************************************************************************* ******/
/*void loadoneline_R(void)
{
char s; //此处不要用uchar定义s
for(s=0;s<2;s++)
{
BUFF[2*s+1]=HZ[word+32*s+2*disrow];
BUFF[2*s]=HZ[word+1+32*s+2*disrow]; //右移显示
}
}*/
/****************************************************************************** ****
左移显示数据输出函数 : 为显示数据生成模块的h1、h2赋值并且输出合成后的新的h1、h2数据
******************************************************************************* ****/
void sendoneline_L(void)
{
char s;uchar inc;
if(col<8)inc=0;else inc=1;
for(s=1+inc;s>=0+inc;s--){ //左移显示:单屏s=1+,4屏s=7+,8屏s=15+;SBUF=two_onebyteL(BUFF[s],BUFF[s+1]);while(!TI);TI=0;
}
}
/****************************************************************************** ****
右移显示数据输出函数 :
******************************************************************************* ****/
/*void sendoneline_R(void)
{
char s;uchar inc;
if(col<8)inc=0;else inc=1;
for(s=0+inc;s<2+inc;s++){ //右移显示:单屏s=1+,4屏s=7+,8屏s=15+;
SBUF=two_onebyteR(BUFF[s],BUFF[s+1]);while(!TI);TI=0;
}
}*/
/****************************************************************************** *******
主函数:
******************************************************************************* ******/
void main(void)
{
col=0;word=0,zishu=0; // 列移动计数变量、汉字码位数变量每字32个码
while(1)
{
while(col<16)
{uchar i;
for(i=0;i<K;i++)
{
for(disrow=0;disrow<16;disrow++)
{
//if(zishu<=224) //根据字数确定移动方向(以字数乘32为基数根据显示情况调整) //{
loadoneline_L();
sendoneline_L();
//}
//else
//{
//loadoneline_R();
//sendoneline_R();
//}
P0=0xf8+disrow; //行扫描首地址为8,因P0高4位空置,故0xf8,0x08均可。
OE=1;ST=1; //显示关 ,595置数
delay(20); //改变延时值可适度调整显示屏亮度(不闪烁范围值15-20)
OE=0;ST=0; //显示开、与OE=1对应 , 595锁存
} // 完成一个汉字的显示
} // 重复K次
col++; // 列移动变量+1
} // 16列移动完成
col=0; //每移动完成16列数据就加入一个新字模数据
//zishu=zishu+32;
//if(zishu>=512)zishu=0; //改变移动方向
word=word+32;
if(word>=128)word=0; //重新从第一个字开始显示
} // 无限重复
} // 主函数结束
/****************************************************************************** *******
数组的字模取码方式为阳码、顺向、逐行。
******************************************************************************* ******/
uchar code HZ[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
0x01,0x00,0x01,0x04,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x08,0x7F,0xFC,0x00,0x00 ,
0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x00,0x00 ,/*"吉",0*/
0x21,0x04,0x10,0x88,0x10,0x50,0xFD,0xFE,0x04,0x20,0x08,0x20,0x11,0xFC,0x38,0x20 ,
0x54,0x20,0x94,0x20,0x13,0xFE,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20 ,/*"祥",1*/
0x10,0x00,0x10,0x00,0x18,0x00,0x10,0x7E,0xFE,0x42,0x22,0x42,0x22,0x42,0x22,0x42 ,
0x22,0x42,0x24,0x42,0x14,0x42,0x08,0x42,0x14,0x7E,0x23,0x42,0x42,0x42,0x80,0x00 ,/*"如",2*/
0x01,0x00,0x3F,0xFC,0x08,0x20,0x04,0x40,0xFF,0xFE,0x00,0x00,0x1F,0xF0,0x12,0x10 ,
0x11,0x10,0x1F,0xF0,0x00,0x00,0x29,0x08,0x28,0x84,0x68,0x14,0x07,0xF0,0x00,0x00 ,/*"意",3*/
};
此程序是实际演示应用程序,是在我的UV2窗口中粘贴过来的,如有应用,反向操作即可。
其实程序前的接口设置已经叙述的很详细了,即使没有图纸也能应用。
由于本程序只是用来演示左右移动的效果,一般应用时应该只是一个方向,(如欲左移显示时需将相关右移的部分变绿,或加以控制,否则,就乱套了)所以,只要对程序进行删减,可以很方便的用于实际控制,本程序只用于16*16点阵的控制,当扩展为屏组控制时,程序的修改应非难事,参照上篇文章,应能知道该加入的语句。
弄了许久,总算把这段视频放在这里了,又是注册,又是上传视频的,还莫名其妙的被屏蔽了好几次,又由于没有设置为“公开”还一度找不到文件地址,最终还是借助了“一键 i 贴吧”才找到了地址转了过来,这段视频在我的QQ空间里好久,拍的并不好,本来演示的很好不知为何拍成视频后闪烁的很厉害,慢慢琢磨吧。
编辑说明:本文写作已经很长时间了,经常有朋友就一些问题进行交流,最近更有朋友指出了一些内容上的疏失,就此我重新找出了这块试验板,重新核查了线路,重新演示了程序,发现确实有遗漏之处,就此对文章进行了编辑,同时,对网友bebackin1988对此文的认真梳理,表示感谢。