1、摘要LED点阵显示屏作为一种新兴的显示器件,是由多个独立的LED发光二极管封装而成. LED点阵显示屏可以显示数字或符号, 通常用来显示时间、速度、系统状态等。本设计是1个1616点阵LED电子显示屏的设计。整机以美国ATMEL公司生产的40脚单片机AT89S52为核心,介绍了以它为控制系统的LED点阵电子显示屏的动态设计和和LED书写屏过程。通过该芯片控制一个行驱动器74LS154和两个列驱动器74HC595来驱动显示屏显示。该电子显示屏可以显示各种文字或利用关闭书写信息,全屏能显示1个汉字,采用4块8 x 8点阵LED显示模块来组成1个16x16点阵显示模式。显示采用动态显示,使得图形或文
2、字能够实现静止、移入移出等多种显示方式。在液晶显示的信息指导下,用户可以进入LED书写屏模式进行书写文字或绘画图像,文中详细介绍了LED点阵显示的硬件设计思路、硬件电路各个部分的功能及原理、相应软件的程序设计,以及使用说明等。关键词:AT89S52单片机 LED点阵显示屏 LED点阵书写屏 光笔 动态显示一、 功能要求及方案论证1.1功能要求本方案设计一个电子显示屏,具体要求满足以下条件: :对于LED点阵显示屏模式 1.要求采用51单片机作为微控制器; 2.通过四个88的点阵LED进行文字显示; 3.在目测条件下LED显示屏各点亮度均匀、充足、稳定、清晰无串扰。 4.文字显示具有若干个字轮流
3、显示、滚动显示、分别从左右上下的方向移入和移出、分别从四个对角的方向移出等多种显示方式。:对于LED点阵书写屏模式1.用户可以利用光笔在LED屏幕上连续书写信息。2.把用户书写的信息连续输出。1.2点阵驱动方案论证列驱动有串入并出驱动和并入并出驱动,采用并行方式时,从控制电路到列驱动器的线路数量大,相应的硬件数目多。当列数很多时,并列传输的方案是不可取的。采用串行传输的方法,控制电路可以只用一根信号线,将列数据一位一位传往列驱动器,在硬件方面无疑是十分经济的,因此,通过综合的考虑选择芯片为数据移位寄存器74HC595,它具有一个8位串入并出的移位寄存器和一个8位输出锁存器的结构,而且移位寄存器
4、和输出锁存器的控制是各自独立的,可以实现在显示本行列数据的同时,传送下一行的列数据,既达到重叠处理的目的。74HC595的数据端:O0O7: 八位并行输出端,可以直接控制数码管的8个段。Q7: 级联输出端。我将它接下一个74HC595的SER端。SER: 串行数据输入端。74HC595的控制端说明:SRCLR(10脚): 低点平时将移位寄存器的数据清零,通常我将它接Vcc。SRCLK(11脚):上升沿时数据寄存器的数据移位。O0-O1-O2-.-O7;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。我通常都选微秒级)RCLK(12脚):上升沿时移位寄存器的数据进入数据存储寄存
5、器,下降沿时存储寄存器数据不变。通常我将RCLK置为低点平,当移位结束后,在RCLK端产生一个正脉冲(5V时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。E(13脚): 高电平时禁止输出(高阻态)。如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。74HC595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,如下面的真值表,在正常使用时SRCLR为高电平, E为低电平。从SER每输入一位数据,串行输入时钟SCLK上升沿有效一次,直到八位数据输入完毕,输出时钟上升沿有效一次,此时,输入的数据就被送到了输出端。列驱动电路如图1-
6、2(a)LED用的是动态显示原理,行驱动选择芯片为416译码器单元74HC154,其输入是一个16进制码,解码输出为低态扫描信号,点阵显示屏可以用少量I/O口接收控制器传输下来的大量数据,此方案为点阵显示屏系统中比较常用的,所用器件也比较常用,容易买到。行驱动电路如图1-2(b) (a) (b)图1-2二、理论分析与计算2.1光笔的选择 光笔是利用对光的敏感而设计的,即要求LED屏幕工作在微亮的模式下,微亮意为:高速、短时间地点亮、熄灭每一个LED灯,利用人眼的“视觉停留效应”,让人眼察觉不出LED灯的闪烁,人眼只会觉得它是在微亮。扫描过程中,光笔所在点的的LED灯亮的时间是非常短暂的,所以对
7、光敏器件有两个要求:响应速度快、灵敏。于是我选用了3DU33光敏三极管。光敏三极管和普通三极管相似,也有电流放大作用,只是它的集电极电流不只是受基极电路和电流控制,同时也受光辐射的控制。通常基极不引出,但一些光敏三极管的基极有引出,用于温度补偿和附加控制作用。当具有光敏特性的PN结受到光辐射时,形成光电流,由此产生光生电流由基极入发射极,从而在集电极回路中得到一个放大了相当于倍的信号电流。与光敏二极管相比,光敏三极管具有很大的光电流放大作用,即很高的灵敏度。3DU33在基极产生的光电流经过自身的放大能达到3ma左右,这电流足以让外接的8050(NPN三极管)进入深饱和,处于开关状态。tr、tf
8、(电平的上升、下降变化所需最小时间)均小于5微秒,而且3DU33是对波长为880nm的近红外光反应最灵敏(LED屏上的LED灯也是红光灯),这样一来,光笔对光的反应时很稳定了。为了人性化,在光笔的上面按一个按钮S1,当要书写字的时候用大拇指按住按钮S1就可以书写字了。光笔的电路图如2-1图2-1光笔电路2.2键盘的使用及设计键盘分为独立是键盘和行列式键盘,独立式键盘的按键比较的少,当需要的按键较多时,独立式键盘就要实现一键多功能,编程变得复杂。行列式键盘的按键比较多,不用一键多功能。本设计要求既可以多种方式显示信息,又要求用户能用光笔在LED屏幕上书写信息,需要的按键相对较多,因此,我们决定用
9、行列式键盘作为本设计的输入设备。行列式键盘的电路图如图2-2图2-2 行列是键盘电路行列式键盘上的各个键的功能分配如下表012345写擦减一加一清屏菜单上翻确定退出返回下翻注析:选择后请按确定键。写擦:把用笔写的信息全部擦除加一:写或查看下一个字减一:写或查看上一个字清屏:清除当前写的字附录:本设计可以实现的简单汉字男儿走四方;前不见古人;后不见来者;白了少年头;空山草木长等等及阿拉伯数字。附件:程序清单#include#include#include#define uchar unsigned char#define uint unsigned intsbit E=P35;sbit LE=P
10、36;uchar keyzhi,function,zhilu,ledlist,ledrow,word;uchar command;sbit SER=P20;sbit S595_RCLK=P21;sbit S595_SRCLK=P22;sbit E1=P27;bit shuxiep,xianship,key,writing;bit caidan,sfan,ok,exit,back,xfan,sure;/功能键标志位bit zduan; /中断标志位uchar idata dispram32=0;uchar idata guangbi32*5=0; char code led_list=/*- 文
11、字: 湖 -*/*- 宋体12; 此字体下对应的点阵为:宽x高=16x16 -*/0x42,0x00,0x22,0x3C,0x22,0x24,0x02,0x24,0x8F,0xBC,0x52,0x24,0x12,0x24,0x2F,0xBC,0x28,0xA4,0x28,0xA4,0xC8,0xA4,0x48,0xA4,0x4F,0xC4,0x40,0x44,0x40,0x94,0x41,0x08,/*- 文字: 南 -*/*- 宋体12; 此字体下对应的点阵为:宽x高=16x16 -*/0x01,0x00,0x01,0x04,0xFF,0xFE,0x01,0x00,0x02,0x00,0x3
12、F,0xFC,0x24,0x24,0x22,0x44,0x2F,0xF4,0x21,0x04,0x3F,0xFC,0x21,0x04,0x21,0x04,0x21,0x14,0x21,0x08,0x00,0x00,/*- 文字: 工 -*/*- 宋体12; 此字体下对应的点阵为:宽x高=16x16 -*/0x00,0x00,0x3F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x
13、00,0x00,0x00,/*- 文字: 学 -*/*- 宋体12; 此字体下对应的点阵为:宽x高=16x16 -*/0x01,0x08,0x10,0x8C,0x0C,0xC8,0x08,0x90,0x7F,0xFE,0x40,0x04,0x8F,0xE8,0x00,0x40,0x00,0x80,0x7F,0xFE,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x02,0x80,0x01,0x00,/*- 文字: 院 -*/*- 宋体12; 此字体下对应的点阵为:宽x高=16x16 -*/0x00,0x80,0xF8,0x40,0x8F,0xFE,0x94,
14、0x04,0xA0,0x00,0xA3,0xF8,0x90,0x00,0x88,0x00,0x8F,0xFE,0xA9,0x20,0x91,0x20,0x81,0x20,0x82,0x22,0x82,0x22,0x84,0x22,0x88,0x1E,/*- 图像: 笑脸 -*/*- 宋体12; 此字体下对应的点阵为:宽x高=16x16 -*/0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x4C,0x32,0x8C,0x31,0x80,0x01,0x80,0x01,0x90,0x09,0x98,0x19,0x8C,0x31,0x47,0xE2,0x40,0x0
15、2,0x20,0x04,0x18,0x18,0x07,0xE0, ;/*延时函数*/ void delay(uint m)while(-m); /*键扫函数*/uchar keyscan(void)uchar scan,tmp; P1=0xf0; /发全行0扫描码 if(P1&0xf0)!=0xf0) /若有键按下 delay(1000); / 延时去抖 if(P1&0xf0)!=0xf0) /延时再判键是否还按下 scan=0xfe; while(scan&0x10)!=0) /逐行扫描 P1=scan; /输出行扫描码 if(P1&0xf0)!=0xf0) /本行有键按下 if(caida
16、n=1)key=1; tmp=(P1&0xf0)|0x0f; return (scan)|(tmp); /还回键值 else scan=(scan1)|0x01; /行扫描码左移一位 return (0); /无键按下,还回0 /*液晶LCD写指令程序*/void write_command(uchar command) delay(100); rs=0; rw=0; P0=command; E=1; _nop_(); _nop_(); E=0;/*液晶LCD清屏程序*/void lcd_clear(void) command=0x01; write_command(command); com
17、mand=0x34; write_command(command); command=0x30; write_command(command);/*液晶LCD功能设置*/void lcd_set(void) command=0x34; /功能设定 8位扩充指令 write_command(command); command=0x30; /基本指令集 write_command(command); command=0x01; /清屏,DDRAM的地址归零 write_command(command); command=0x06; /DDRAM地址加1 write_command(command)
18、; command=0x0c; /显示开,光标关,反白关 write_command(command); /*液晶LCD写数据程序*/void write_data(uchar data0) delay(100); rs=1; rw=0; P0=data0; E=1; _nop_(); _nop_(); E=0;/*移位寄存器接受一个字节数据函数*/void input(uchar word) uchar i; for(i=0;i=7;i+) SER=word&0x01; /串行输入 word=_cror_(word,1); /循环右移 S595_SRCLK=0; _nop_();_nop_(
19、); S595_SRCLK=1;/上升沿数据左移 /*将移位寄存器的数据锁存到输出寄存器并显示函数*/void output() S595_RCLK=0; _nop_();_nop_(); S595_RCLK=1; _nop_();_nop_(); S595_RCLK=0; /*LED显示屏的程序区*/*显示缓冲区初始化函数*/void dispram_csh() uchar c; for(c=0;c32;c+)dispramc=led_list5*32+c; /*显示缓冲区清零函数*/void dispram_clear() uchar c; for(c=0;c16;c+) dispram2
20、*c+1=0x00;dispram2*c=0x00;input(dispramc*2+1);input(dispramc*2);output();P0=P0&0xf0|c; /*LED16*16提示符显示函数*/ void led_tsf_display() uchar a; E1=0; /选择芯片154 for(a=0;a=15;a+) input(disprama*2+1);input(disprama*2);output();P0=P0&0xf0|a;delay(70); /*LED16*16轮流显示函数*/ void led_lunliu_display() uchar r,m,n;
21、E1=0; /选择芯片154 for(m=0;m=4;m+) /轮流显示字的个数 for(n=0;n=30;n+) /每个字显示的次数 for(r=0;r=15;r+) /行扫描的次数 input(led_listm*32+r*2+1); input(led_listm*32+r*2); output(); P0=P0&0xf0|r; delay(100); keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|
22、keyzhi=0x48|keyzhi=0x88)break; /*LED16*16滚动显示函数*/ void led_gundong_display() uchar r,m,n; E1=0; /选择芯片154for(m=0;m=64;m+) /轮流显示字的个数 for(n=0;n=12;n+) /每个字显示的次数 for(r=0;r=15;r+) /行扫描的次数 input(led_listm*2+r*2+1); input(led_listm*2+r*2); output(); P0=P0&0xf0|r; delay(100); keyzhi=keyscan();if(keyzhi=0x84
23、|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; /*LED16*16右移显示函数*/ void led_youyi_display() uchar r,m,n,l; E1=0; /选择芯片154 for(m=0;m=4;m+) /显示的字数 for(n=0;n2;n+) /右移的次数 for(l=1;l=8;l+) for(r=0;r1|dispram2*r1|led_listm*32+2*r+1-n(8-
24、l); input(dispram2*r+1); input(dispram2*r); output(); P0=P0&0xf0|r; delay(250); keyzhi=keyscan(); if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; /*LED16*16左移显示函数*/ void led_zuoyi_display() using 2 uchar h,m,n,k; E1=0; /选择芯片154 for(m=0;m=4;m+) for(n=0;n2;n+) /左移的次数 for(k=1;k=8;k+) for(h=0;
25、h=15;h+) /每行左移一位 dispram2*h=dispram2*h7; dispram2*h+1=dispram2*h+1(8-k); input(dispram2*h+1); input(dispram2*h); output(); P0=P0&0xf0|h; delay(250); keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; /
26、*LED16*16上移显示函数*/ void led_shangyi_display() uchar r,m,l; E1=0; /选择芯片154 for(m=0;m=4;m+) /显示的字数 for(l=0;l=15;l+) /上移的次数 for(r=0;r=14;r+) /每行上移一行 dispram2*r=dispram2*(r+1);dispram2*r+1=dispram2*(r+1)+1; input(dispram2*r+1); input(dispram2*r);output(); P0=P0&0xf0|r; delay(250); dispram30=led_listm*32+
27、2*l; /每个字的行送显示缓冲区dispram31=led_listm*32+2*l+1;keyzhi=keyscan(); if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; /*LED16*16下移显示函数*/ void led_xiayi_display() uchar a,m,k; E1=0; /选择芯片154 for(m=0;m=4;m+) /显示的字数 for(k=0;k=15;k+) /下移的次数 for(a=0;a=14;a+) /每行下移一行 dispram30-2*a=dispram30-2*(a+1); d
28、ispram30-2*a+1=dispram30-2*(a+1)+1;input(dispram2*a+1); input(dispram2*a); output();P0=P0&0xf0|a; delay(250); dispram0=led_listm*32+30-2*k; /每个字的行送显示缓冲区 dispram1=led_listm*32+30-2*k+1; keyzhi=keyscan(); if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; /*向四个正方移动*/void led_four_display() ucha
29、r n; for(n=0;n4;n+) /显示次序 if(n=1)led_youyi_display(); if(n=0)led_zuoyi_display(); if(n=2)led_shangyi_display(); if(n=3)led_xiayi_display(); keyzhi=keyscan(); if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; delay(250); /*LED16*16向四角移动显示函数*/ void led_sijiao_display() uchar i,a,m,k; E1=0; /选择
30、芯片154 for(m=0;m6;m+) /显示顺序 for(i=0;i=15;i+) dispram2*i=led_listm*32+2*i; dispram2*i+1=led_listm*32+2*i+1; input(dispram2*i+1);input(dispram2*i); output(); P0=P0&0xf0|i; delay(600); if(m=0)for(k=0;k=15;k+) for(a=0;a=15;a+)/次序1向左上角移动显示 dispram2*a=dispram2*(a+1);dispram2*a+1=dispram2*(a+1)+1;if(a=15)di
31、spram30=0x00;dispram31=0x00;dispram2*a=dispram2*a7;dispram2*a+1=dispram2*a+11;input(dispram2*a+1);input(dispram2*a);output();P0=P0&0xf0|a;delay(300); keyzhi=keyscan(); if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; if(m=1) /次序2向右上角移动显示 for(k=0;k=15;k+) for(a=0;a1|dispram2*a1;input(dispram
32、2*a+1);input(dispram2*a);output();P0=P0&0xf0|a;delay(300); keyzhi=keyscan(); if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; if(m=2) /次序3静止显示 for(k=0;k=30;k+) for(a=0;a=15;a+) input(dispram2*a+1);input(dispram2*a);output();P0=P0&0xf0|a;delay(100); keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x2
33、8|keyzhi=0x48|keyzhi=0x88)break; if(m=3) /次序4向左下角移动显示 for(k=0;k=15;k+) for(a=0;a=15;a+) dispram30-2*a=dispram30-2*(a+1);dispram30-2*a+1=dispram30-2*(a+1)+1;if(a=15)dispram0=0x00;dispram1=0x00;dispram2*a=dispram2*a7;dispram2*a+1=dispram2*a+11;input(dispram2*a+1);input(dispram2*a);output();P0=P0&0xf0|
34、a;delay(300); keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; if(m=4)/次序5向右下角移动显示 for(k=0;k=15;k+) for(a=0;a1|dispram2*a1;input(dispram2*a+1);input(dispram2*a);output();P0=P0&0xf0|a;delay(300); keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; if(m
35、=5) /次序6静止显示 for(k=0;k=30;k+) for(a=0;a=15;a+) input(dispram2*a+1);input(dispram2*a);output();P0=P0&0xf0|a;delay(100); keyzhi=keyscan(); if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; keyzhi=keyscan();if(keyzhi=0x84|keyzhi=0x28|keyzhi=0x48|keyzhi=0x88)break; /*LED书写屏的程序区*/*显示缓冲区清零函数*/void dispram_word_clear() uchar c; for(c=0;c16;c+) guangbi