1616点阵LED显示屏整个过程及C语言程序1.docx

上传人:b****6 文档编号:13869742 上传时间:2023-06-18 格式:DOCX 页数:24 大小:277.19KB
下载 相关 举报
1616点阵LED显示屏整个过程及C语言程序1.docx_第1页
第1页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第2页
第2页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第3页
第3页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第4页
第4页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第5页
第5页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第6页
第6页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第7页
第7页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第8页
第8页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第9页
第9页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第10页
第10页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第11页
第11页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第12页
第12页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第13页
第13页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第14页
第14页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第15页
第15页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第16页
第16页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第17页
第17页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第18页
第18页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第19页
第19页 / 共24页
1616点阵LED显示屏整个过程及C语言程序1.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

1616点阵LED显示屏整个过程及C语言程序1.docx

《1616点阵LED显示屏整个过程及C语言程序1.docx》由会员分享,可在线阅读,更多相关《1616点阵LED显示屏整个过程及C语言程序1.docx(24页珍藏版)》请在冰点文库上搜索。

1616点阵LED显示屏整个过程及C语言程序1.docx

1616点阵LED显示屏整个过程及C语言程序1

16×16点阵LED显示屏整个过程及C语言程序

7.1功能要求

设计一个室内用16×16点阵LED图文显示屏,要求在目测条件下LED显示屏各点亮度均匀、充足,可显示图形和文字,显示图形或文字应稳定、清晰无串扰。

图形或文字显示有静止、移入移出等显示方式。

7.2方案论证

从理论上说,不论显示图形还是文字,只要控制与组成这些图形或文字的各个点所在位置相对应的LED器件发光,就可以得到我们想要的显示结果,这种同时控制各个发光点亮灭的方法称为静态驱动显示方式。

16×16的点阵共有256个发光二极管,显然单片机没有这么多端口,如果我们采用锁存器来扩展端口,按8位的锁存器来计算,16×16的点阵需要256/8=32个锁存器。

这个数字很庞大,因为我们仅仅是16×16的点阵,在实际应用中的显示屏往往要大的多,这样在锁存器上花的成本将是一个很庞大的数字。

因此在实际应用中的显示屏几乎都不采用这种设计,而采用另一种称为动态扫描的显示方法。

动态扫描的意思简单地说就是逐行轮流点亮,这样扫描驱动电路就可以实现多行(比如16行)的同名列共用一套列驱动器。

具体就16×16的点阵来说,我们把所有同一行的发光管的阳极连在一起,把所有同一列的发光管的阴极连在一起(共阳的接法),先送出对应第一行发光管亮灭的数据并锁存,然后选通第一行使其燃亮一定的时间,然后熄灭;再送出第二行的数据并锁存,然后选通第二行使其燃亮相同的时间,然后熄灭;……第十六行之后又重新燃亮第一行,这样反复轮回。

当这样轮回的速度足够快(每秒24次以上),由于人眼的视觉暂留现象,我们就能看到显示屏上稳定的图形了。

采用扫描方式进行显示时,每行有一个行驱动器,各行的同名列共用一个列驱动器。

显示数据通常存储在单片机的存储器中,按8位一个字节的形式顺序排放。

显示时要把一行中各列的数据都传送到相应的列驱动器上去,这就存在一个显示数据传输的问题。

从控制电路到列驱动器的数据传输可以采用并行方式或串行方式。

显然,采用并行方式时,从控制电路到列驱动器的线路数量大,相应的硬件数目多。

当列数很多时,并行传输的方案是不可取的。

采用串行传输的方法,控制电路可以只用一根信号线,将列数据一位一位传往列驱动器,在硬件方面无疑是十分经济的。

但是,串行传输过程较长,数据按顺序一位一位地输出给列驱动器,只有当一行的各列数据都已传输到位之后,这一行的各列才能并行地进行显示。

这样,对于一行的显示过程就可以分解成列数据准备(传输)和列数据显示两个部分。

对于串行传输方式来说,列数据准备时间可能相当长,在行扫描周期确定的情况下,留给行显示的时间就太少了,以至影响到LED的亮度。

解决串行传输中列数据准备和列数据显示的时间矛盾问题,可以采用重叠处理的方法。

即在显示本行各列数据的同时,传送下一行的列数据。

为了达到重叠处理的目的,列数据的显示就需要具有锁存功能。

经过上述分析,可以归纳出列驱动器电路应具备的主要功能。

对于列数据准备来说,它应能实现串入并出的移位功能;对于列数据显示来说,应具有并行锁存的功能。

这样,本行已准备好的数据打入并行锁存器进行显示时,串并移位寄存器就可以准备下一行的列数据,而不会影响本行的显示。

图7.1为显示屏电路实现的结构框图。

图7.1显示屏电路框图

7.3系统硬件电路的设计

硬件电路大致上可以分成单片机系统及外围电路、列驱动电路和行驱动电路三部分。

7.3.1单片机系统及外围电路

单片机采用89C51或其兼容系列的芯片,采用24M或更高频率的晶振,以获得较高的刷新频率,使显示更稳定。

单片机的串口与列驱动器相连,用来送显示数据。

P1口低4位与行驱动器相连,送出行选信号;P1.5~P1.7口则用来发送控制信号。

P0和P2口空着,在有必要时可以扩展系统的ROM和RAM。

16×16点阵显示屏的硬件原理图如图7.2。

图7.216×16点阵显示屏硬件原理图

7.3.2列驱动电路

列驱动电路由集成电路74HC595构成,它具有一个8位串入并出的移位寄存器和一个8位输出锁存器的结构,而且移位寄存器和输出锁存器的控制是各自独立的,可以实现在显示本行各列数据的同时,传送下一行的列数据,即达到重叠处理的目的。

74HC595的外形及内部结构如图7.3所示。

它的输入侧有8个串行移位寄存器,每个移位寄存器的输出都连接一个输出锁存器。

引脚SI是串行数据的输入端。

引脚SCK是移位寄存器的移位时钟脉冲,在其上升沿发生移位,并将SI的下一个数据打入最低位。

移位后的各位信号出现在各移位寄存器的输出端,也就是输出锁存器的输入端。

RCK是输出锁存器的打入信号,其上升沿将移位寄存器的输出打入到输出锁存器。

引脚G是输出三态门的开放信号,只有当其为低时锁存器的输出才开放,否则为高阻态。

SCLR信号是移位寄存器的清零输入端,当其为低时移位寄存器的输出全部为零。

由于SCK和RCK两个信号是互相独立的,所以能够做到输入串行移位与输出锁存互不干扰。

芯片的输出端为QA~QH,最高位QH可作为多片74HC595级联应用时,向上一级的级联输出。

但因QH受输出锁存器打入控制,所以还从输出锁存器前引出了QH’,作为与移位寄存器完全同步的级联输出。

引脚说明

符号

引脚

描述

Q0…Q7

15,1,7

并行数据输出

GND

8

Q7’

9

串行数据输出

MR

10

主复位(低电平)

SHCP

11

移位寄存器时钟输入

STCP

12

存储寄存器时钟输入

OE

13

输出有效(低电平)

DS

14

串行数据输入

VCC

16

电源

图7.374HC595外形及内部逻辑结构图

7.3.3行驱动电路

单片机P1口低4位输出的行号经4/16线译码器74LS154译码后生成16条行选通信号线,再经过驱动器驱动对应的行线。

一条行线上要带动16列的LED进行显示,按每一LED器件20mA电流计算,16个LED同时发光时,需要320mA电流,选用三极管8550作为驱动管可满足要求。

74LS154引脚功能图及逻辑图如图原理:

这种单片4线—16线译码器非常适合用于高性能存储器的译码器。

当选通端(G1、G2)均为低电平时,可将地址端(ABCD)的二进制编码在一个对应的输出端,以低电平译出。

如果将G1和G2中的一个作为数据输入端,由ABCD对输出寻址,74LS154还可作1线-16线数据分配器。

引脚功能介绍:

A、B、C、D译码地址输入端(低电平有效)

G1、G2选通端(低电平有效)

0-15输出端(低电平有效)

功能表:

图174LS154引脚功能图及逻辑图

7.4系统程序的设计

显示屏软件的主要功能是向屏体提供显示数据,并产生各种控制信号,使屏幕按设计的要求显示。

根据软件分层次设计的原理,我们可把显示屏的软件系统分成两大层:

第一层是底层的显示驱动程序,第二层是上层的系统应用程序。

显示驱动程序负责向屏体送显示数据,并负责产生行扫描信号和其它控制信号,配合完成LED显示屏的扫描显示工作。

显示驱动程序由定时器T0中断程序实现。

系统应用程序完成系统环境设置(初始化)、显示效果处理等工作,由主程序来实现。

从有利于实现较复杂的算法(显示效果处理)和有利于程序结构化考虑,显示屏程序适宜采用C语言编写。

7.4.1显示驱动程序

显示驱动程序在进入中断后首先要对定时器T0重新赋初值以保证显示屏刷新率的稳定,1/16扫描的显示屏的刷新率(帧频)的计算公式如下:

式7-1

其中fosc为晶振频率,t0为定时器T0初值(工作在16位定时器模式)。

然后显示驱动程序查询当前燃亮的行号,从显示缓存区内读取下一行的显示数据,并通过串口发送给移位寄存器。

为消除在切换行显示数据的时候产生拖尾现象,驱动程序先要关闭显示屏,即消隐,等显示数据打入输出锁存器并锁存,然后再输出新的行号,重新打开显示。

图7.4为显示驱动程序(显示屏扫描函数)流程图。

系统主程序开始以后首先是对系统环境初始化,包括设置串口、定时器、中断和端口。

然后以“卷帘出”效果显示一个图形(☺),停留约3秒,接着向上滚动显示“我爱单片机☺”五个汉字及一个图形,停留约3秒,再向左跑马显示“我爱单片机☺”这五个汉字及一个图形,然后以“卷帘入”效果隐去图形(☺)。

由于单片机没有停机指令,所以我们可以设置系统程序不断地循环执行上述显示效果。

图7.5是系统主程序的流程图。

7.5调试及性能分析

LED显示屏硬件电路只要器件质量可靠,管脚焊接正确,一般无需调试即可正常工作。

软件部分需要调试的主要有显示屏刷新频率及显示效果两部分。

显示屏刷新率由定时器T0的溢出率和单片机的晶振频率决定,表7.1给出了实验调试时采用的频率及其对应的定时器T0初值。

表7.1显示屏刷新率(帧频)与T0初值关系表(24M晶振)

刷新率(Hz)

25

50

62.5

75

85

100

120

T0初值

0xec78

0xf63c

0xf830

0xf97e

0xfa42

0xfb1e

0xfbee

从理论上来说,24Hz以上的刷新率就能看到连续稳定的显示,刷新率越高,显示越稳定,同时刷新率越高,显示驱动程序占用的CPU时间也越多。

实验证明,在目测条件下刷新率40Hz以下的画面看起来闪烁较严重,刷新率50Hz以上的已基本觉察不出画面闪烁,刷新率达到85Hz以上时再增加画面闪烁将没有明显改善。

显示效果处理程序的内容及方法非常广泛,其调试过程在此不作具体讨论,读者可对照源程序自行分析。

这个方案设计的16×16点阵LED图文显示屏,电路简单,成本较低,且较容易扩展成更大的显示屏;显示屏各点亮度均匀、充足;显示图形或文字稳定、清晰无串扰;可用静止、移入移出等多种显示方式显示图形或文字。

7.6控制源程序清单

以下是16×16点阵LED电子显示屏的源程序,分别采用C及汇编编写,C程序在KeiluVision2V2.30(C51.exeV7.0)环境下调试通过。

/*--------------------------------------

16×16点阵LED显示屏程序

MCUAT89C51XAL24MHz

--------------------------------------*/

#include

#defineBLKN2//列锁存器数

sbitG=0x97;//P1.7为显示允许控制信号端口

sbitRCLK=0x96;//P1.6为输出锁存器时钟信号端

sbitSCLR=0x95;//P1.5为移位寄存器清○端

voiddelay(unsignedint);//延时函数

unsignedchardatadispram[32];//显示缓存

/*--------------------------------------

主函数voidmain(void)

--------------------------------------*/

voidmain(void)

{

unsignedcharcodeBmp[][32]={//字模表

{

0xF9,0xBF,0xC7,0xAF,0xF7,0xB7,0xF7,0xB7,0xF7,0xBF,0x00,0x01,0xF7,0xBF,0xF7,0xB7,

0xF1,0xD7,0xC7,0xCF,0x37,0xDF,0xF7,0xAF,0xF6,0x6D,0xF7,0xF5,0xD7,0xF9,0xEF,0xFD

}/*我*/,

{

0xFF,0x07,0xC0,0x6F,0xED,0xEF,0xF6,0xDF,0xC0,0x01,0xDD,0xFD,0xBD,0xFF,0xC0,0x03,

0xFB,0xFF,0xF8,0x0F,0xF3,0xDF,0xF4,0xBF,0xEF,0x3F,0x9C,0xCF,0x73,0xF1,0xCF,0xFB

}/*爱*/,

{

0xF7,0xDF,0xF9,0xCF,0xFB,0xBF,0xC0,0x07,0xDE,0xF7,0xC0,0x07,0xDE,0xF7,0xDE,0xF7,

0xC0,0x07,0xDE,0xF7,0xFE,0xFF,0x00,0x01,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF

}/*单*/,

{

0xFF,0xBF,0xEF,0xBF,0xEF,0xBF,0xEF,0xBB,0xE0,0x01,0xEF,0xFF,0xEF,0xFF,0xEF,0xFF,

0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xDF,0xEF,0xDF,0xEF,0xBF,0xEF,0x7F,0xEF

}/*片*/,

{

0xEF,0xFF,0xEF,0x07,0xEF,0x77,0x01,0x77,0xEF,0x77,0xEF,0x77,0xC7,0x77,0xCB,0x77,

0xAB,0x77,0xAF,0x77,0x6E,0xF7,0xEE,0xF5,0xED,0xF5,0xED,0xF5,0xEB,0xF9,0xEF,0xFF

}/*机*/,

{

0xF8,0x3F,0xE7,0xCF,0xDF,0xF7,0xBF,0xFB,0xB3,0x9B,0x73,0x9D,0x7F,0xFD,0x7F,0xFD,

0x6F,0xED,0x67,0xCD,0xB3,0x9B,0xB8,0x3B,0xDF,0xF7,0xE7,0xCF,0xF8,0x3F,0xFF,0xFF

}/*☺*/

};

registerunsignedchari,j,k,l;

SCON=0x00;//串口工作模式0:

移位寄存器方式

TMOD=0x01;//定时器T0工作方式1:

16位方式

TR0=1;//启动定时器T0

P1=0x3f;//P1端口初值:

允许接收、锁存、显示

IE=0x82;//允许定时器T0中断

while

(1)

{

delay(2000);//延时2秒

for(i=0;i<32;i++)//显示效果:

卷帘出┓

{

dispram[i]=Bmp[5][i];

if(i%2)delay(100);

}//━━━━━━━━┛

delay(3000);

for(i=0;i<6;i++)//显示效果:

上滚屏┓

{

for(j=0;j<16;j++)

{

for(k=0;k<15;k++)

{

dispram[k*BLKN]=dispram[(k+1)*BLKN];

dispram[k*BLKN+1]=dispram[(k+1)*BLKN+1];

}

dispram[30]=Bmp[i][j*BLKN];

dispram[31]=Bmp[i][j*BLKN+1];

delay(100);

}

}//━━━━━━━━┛

delay(3000);

for(i=0;i<6;i++)//显示效果:

左跑马┓

{

for(j=0;j<2;j++)

for(k=1;k<9;k++)

{

for(l=0;l<16;l++)

{

dispram[l*BLKN]=dispram[l*BLKN]<<1|dispram[l*BLKN+1]>>7;

dispram[l*BLKN+1]=dispram[l*BLKN+1]<<1|Bmp[i][l*BLKN+j]>>(8-k);

}

delay(100);

}//end(k=0;k<16;k++)

}//endfor(i=0;i<;i++)//━━━━━━━┛

delay(3000);

for(i=0;i<32;i++)//显示效果:

卷帘入┓

{

dispram[i]=0x00;

if(i%2)delay(100);

}//━━━━━━━━┛

}//endwhile

(1)

}

/*延时函数*/

voiddelay(unsignedintdt)

{

registerunsignedcharbt;

for(;dt;dt--)

for(bt=0;bt<255;bt++);

}

/*显示屏扫描(定时器T0中断)函数*/

voidleddisplay(void)interrupt1using1

{

registerunsignedchari,j=BLKN;

TH0=0xF8;//设定显示屏刷新率每秒62.5帧

TL0=0x30;

i=P1;//读取当前显示的行号

i=++i&0x0f;//行号加1,屏蔽高4位

do{

j--;

SBUF=dispram[i*BLKN+j];//送显示数据

while(!

TI);TI=0;

}while(j);//完成一行数据的发送

G=1;//消隐(关闭显示)

P1&=0xf0;//行号端口清○

RCLK=1;//显示数据打入输出锁存器

P1|=i;//写入行号

RCLK=0;//锁存显示数据

G=0;//打开显示

}

以下为用汇编编写的字符显示控制程序:

;************************************

;**

;*单个16*16点阵电子屏字符显示器*

;*AT89C5212MHZ晶振*

;************************************

;显示字用查表法,不占内存,字符用16*16共阳LED点阵,

;效果:

向上滚动显示19个字,再重复循环。

;R1:

查表偏址寄存器,B:

查表首址,R2:

扫描地址(从00-0FH)。

;R3:

滚动显示时控制移动速度,单字显示可控制静止显示的时间。

;************;

;中断入口程序;

;************;

;

ORG0000H

LJMPSTART

ORG0003H

RETI

ORG000BH

LJMPINTT0

ORG0013H

RETI

ORG001BH

RETI

ORG0023H

RETI

ORG002BH

RETI

;

;************;

;初始化程序;

;************;

;

;

;************;

;主程序;

;************;

;

START:

MOV20H,#00H;清标志,00H为第16行开始扫描标志,01为1帧扫描结束标志

MOVA,#0FFH;端口初始化

MOVP1,A

MOVP2,A

MOVP3,A

MOVP0,A

CLRP1.6;串行寄存器输入打入输出控制位

MOVTMOD,#01H;使用T0作16位定时器,行扫描用。

MOVTH0,#0FCH;1ms初值(12MHZ)

MOVTL0,#18H

MOVSCON,#00H;串口0方式传送显示字节

MOVIE,#82H;T0中断允许,总中断允许

MOVSP,#70H

MAIN:

LCALLDIS1;显示准备,黑屏,1.5秒

MOVDPTR,#TAB

LCALLMOVDISP;向上滚动显示一页(8个字)

INCDPH

LCALLMOVDISP;向上滚动显示一页(8个字)

INCDPH

LCALLMOVDISP;向上滚动显示一页(8个字)

AJMPMAIN

;

;

;********************;

;多字滚动显示子程序;

;********************;

;每次8个字,入口时定义好DPTR值

;

MOVDISP:

MOVB,#00H;向上移动显示,查表偏址暂存(从00开始)

DISLOOP:

MOVR3,#07H;移动速度

DISMOV:

MOVR2,#00H;第0行开始

MOVR1,B;

SETBTR0;开扫描(每次一帧)

WAITMOV:

JBC01H,DISMOV1;标志为1扫描一帧结束(16毫秒为1帧,每行1毫秒)

AJMPWAITMOV

DISMOV1:

DJNZR3,DISMOV;1帧重复显示(控制移动速度)

INCB;显示字的下一行(每行2字节)

INCB;

MOVA,R1;R1为0,8个字显示完

JZMOVOUT;

AJMPDISLOOP;

MOVOUT:

RET;移动显示结束

;

;

;*****************;

;单字显示子程序;

;*****************;

;显示表中某个字

DIS1:

MOVR3,#5AH;静止显示时间控制(16MS*#=1.6秒)

DIS11:

MOVR2,#00H;一帧扫描初始值(行地址从00-0FH)

MOVDPTR,#TAB;取表首址

MOVR1,#00H;查表偏址(显示第一个字)

SETBTR0;开扫描(每次一帧)

WAIT11:

JBC01H,DIS111;为1,扫描一帧结束

AJMPWAIT11

DIS111:

DJNZR3,DIS11

RET

;

;

;************;

;扫描程序;

;************;

;1MS刷新一次,每行显示1秒

INTT0:

PUSHACC

MOVTH0,#0FCH;1ms初值重装

MOVTL0,#18H

JBC00H,GOEND;16行扫描标志为1,结束

INCR1;取行右边字节偏址

MOVA,R1

MOVCA,@A+DPTR;查表

MOVSBUF,A;串口0方式发送

WAIT:

JBCTI,GO;等待发送完毕

AJMPWAIT;

GO:

DECR1;取行左边字节偏址

MOVA,R1

MOVCA,@A+DPTR

MOVSBUF,A

WAIT1:

JBCTI,GO1

AJMPWAIT1

GO1:

SETBP1.7;关行显示,准备刷新

NOP;串口寄存器数据稳定

SETBP1.6;产生上升沿,行数据打入输出端

NOP;

NOP;

CLRP1.6;恢复低电平

MOVA,R2;修改显示行地址

ORLA,#0F0H;修改显示行地址

MOVR2,A;修改显示行地址

MOVA,P1;修改显示行地址

ORLA,#0FH;修改显示行地址

ANLA,R2;修改显示行地址

MOVP1,A;修改完成

CLRP1.7;开行显示

INCR2;下一行扫描地址值

INCR1;

INCR1;下一行数据地址

MOVA,R2

ANLA,#0FH

JNZGO2

SETB00H;R2为10H,现为末行扫描,置标志

GO2:

POPACC

RETI

GOEND:

CLRTR0;一帧扫描完,关扫描

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2