基于单片机控制的LED点阵屏 含设计报告 电路原理图 C语言程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

电子系统综合设计与训练系部:工业中心
项目:LED点阵显示屏
班级:D自集成111班
姓名:万文强(第4组)
指导老师:杨老师
时间:6月10日-7月12日
前言
LED是发光二极管英文Light Emitting Diode 的简称,是六十年代末发展起来的一种半导体显示器件,七十年代,随着半导体材料合成技术、单晶制造技术和P-N结形成技术的研究进展,发光二极管在发光颜色、亮度等性能得以提高并迅速进入批量化和实用化。

进入八十年代后,LED在发光波长范围和性能方面大大提高,并开始形成平板显示产品即LED显示屏。

LED电子显示屏是利用发光二极管点阵模块或像素单元组成的平面式显示屏幕。

它是集微电子技术、光电子技术、计算机技术、信息处理技术于一体的显示系统,是目前国际上极为先进的显示媒体。

由于它具有发光效率高、使用寿命长、组态灵活、色彩丰富、工作性能稳定以及对室内室外环境适应能力强等优点而日渐成为显示媒体中的佼佼者。

在我国改革开放之后,特别是进入90年代国民经济高速增长,对公众场合发布信息的需求日益强烈,LED显示屏的出现正好适应了这一市场形势,因而在LED 显示屏的设计制造技术与应用水平上都得到了迅速的提高,生产也得到了迅速的发展,并逐步形成产业,成为光电子行业的新兴产业领域。

LED显示屏经历了从单色、双色图文显示屏,到图像显示屏的发展过程。

LED电子显示屏是由几万--几十万个半导体发光二极管像素点均匀排列组成。

用不同的材料可以制造不同色彩的LED像素点。

目前应用最广的是红色、绿色、黄色。

而蓝色和纯绿色LED的开发已经达到了实用阶段。

随着信息产业的高速发展,LED显示屏作为信息传播的一种重要手段成为现代信息化社会的一个闪亮标志。

近年LED显示屏已广泛应用于室内、外需要进行服务内容和服务宗旨宣传的公众场所如银行、营业部、车站、机场、港口、体育场馆等信息的发布,政府机关政策、政令,各类市场行情信息的发部和宣传等。

目前,对于那些需要显示的信息量不是很大,分辨率不是很高,又需要制造成本相对比较低的场合,使用大、小屏幕LED点阵显示器是比较经济适用的,它可以用单片机控制实现显示字符、数字、汉字和简单图形,可以根据需要使用不同字号、字型。

汉字显示方式是先根据所需要的汉字提取汉字点阵(如16×16点阵),将点阵文件存入ROM,形成新的汉字编码。

而在使用时则需要先根据新的汉字编码组成语言,再由MCU根据新编码提取相应的点阵进行汉字显示。

具体显示技术和原理将会在正文中得到详细论述。

LED显示屏分为图文显示屏和视频显示屏,均由LED矩阵块组成。

图文显示屏可与计算机同步显示汉字、英文文本和图形;视频显示屏采用微型计算机进行控制,图文、图像并茂,以实时、同步、清晰的信息传播方式播放各种信息,还可显示二维、三维动画、录像、电视、VCD节目以及现场实况。

LED显示屏显示画面色彩鲜艳,立体感强,静如油画,动如电影,广泛应用于车站、码头、机场、商场、医院、宾馆、银行、证券市场、建筑市场、拍卖行、工业企业管理和其它公共场所。

LED显示屏可以显示变化的数字、文字、图形图像;不仅可以用于室内环境还可以用于室外环境,具有投影仪、电视墙、液晶显示屏无法比拟的优点。

目录
1实验目的 (1)
2实验要求 (1)
3实验器件 (1)
4工作原理 (4)
5软件设计 (5)
6硬件设计 (8)
7系统调试及分析 (35)
8成果 (36)
9心得体会 (38)
附录 (40)
一.实验目的
1.利用PLD控制点阵显示;
2.掌握LED点阵显示的电路设计与编程
3.制作PCB板,学会调试电路
二.实验要求
(1)51单片机和LED点阵显模块,设计16*32点阵显示硬件电路,并编制相应程序,实现数字、中英文字符的显示,滚动显示
(2)设计实现左移右移,温度时间的显示。

三.实验器件
1)74HC595 12个
2)74HC138 2个
3)4953 8个
4)245 4个
5) 电容(含点解电容)
6)电源插座
7)扁平电缆 1个
8)MAX232 1个
9)89C52 1个
10)S8550
11) DS18B20 1个
12)ADC0832 1个
13) AT24C04 1个
14) DS1302 1个
15)电阻(含可变电阻)
16)LED
17)SIP2
18)扬声器
19)开关
20)按钮
21)晶振
三.工作原理
由16块8x8LED点阵拼合而成,可同时显示4个汉字。

12片74HC595完成显示屏的列驱动。

两块电路板之间用排线连接。

在CPU的内部RAM开辟一块显示缓存区.CPU控制板读取flash内部的汉字点阵编码,写入到显示缓存区。

然后读取显存中第一行数据,通过ISP接口驱动74HC595,将串行数据转为并行,然后将接通对应的行,显示1ms后,取下一行的数据,同样显示1ms,直到第16行,完成一次扫描。

再把显存中的数据整体左移一位,再扫描一遍。

如此把全部的汉字依次移人显存并显示,便实现了汉字从右向左移,全部汉字移完后对时间、温度和安全天数的寄存器刷新一次
只要每列交替显示的时间适当,利用人眼的视觉暂留特性,看上去16列LED 同时点亮,即看上去整个字符同时显示。

然后再从第1列依次扫描显示至48列,如此循环多次,以确保显示出的字符具有足够的亮度。

为实现字符平滑移动显示的效果,在上面实现的4个字符静态显示一定时间后,再次扫描显示时,每个LED模块的第1列从每个字符的第2列数据开始扫描显示,即第1个LED模块显示第1个字符的第2列、第3列、……、第16列和第2个字符的第1列,第2个LED模块显示第2个字符的第2列、第3列、……、第16列和第3个字符的第1列、第2列、……。

当第三次扫描显示时,每个LED 模块的第1列从每个字符的第3列数据开始扫描显示,即第1个LED模块显示第1个字符的第3列、第4列、……、第16列和第2个字符的第1列、第2列,第2个LED模块显示第2个字符的第3列、第4列、……、第16列和第3个字符的第1列、第2列、……。

如此实现了字符的平滑移动显示。

四.硬件设计
1.设计方案
硬件系统框图
注:16*48LED点阵显示同上
2.各芯片介绍
1)74HC595
硅结构的CMOS器件,兼容低电压TTL电路,遵守JEDEC标准。

74HC595是具有8位移位寄存器和一个存储器,三态输出功能。

移位寄存器和存储器是分别的时钟。

数据在SHcp的上升沿输入到移位寄存器中,在STcp的上升沿输入到存储寄存器中去。

如果两个时钟连在一起,则移位寄存器总是比存储寄存器早一个脉冲。

移位寄存器有一个串行移位输入(Ds),和一个串行输出(Q7’),和一个异步的低电平复位,存储寄存器有一个并行8位的,具备三态的总线输出,当使能OE时(为低电平),存储寄存器的数据输出到总线。

各端口具体功能如下:
Q0…Q7 8位并行数据输出,其中Q0为第15脚
GND 第8脚地
Q7’ 第9脚串行数据输出
MR 第10脚主复位(低电平)
SHCP 第11脚移位寄存器时钟输入
STCP 第12脚存储寄存器时钟输入
OE 第13脚输出有效(低电平)
DS 第14脚串行数据输入
VCC 第16脚电源
2)74HC138
74HC138是一款高速CMOS器件,74HC138引脚兼容低功耗肖特基TTL(LSTTL)系列。

74HC138译码器可接受3位二进制加权地址输入(A0, A1和A2),并当使能时,提供8个互斥的低有效输出(Y0至Y7)。

74HC138特有3个使能输入端:两个低有效(E1和E2)和一个高有效(E3)。

除非E1和E2置低且E3置高,否则74HC138将保持所有输出为高。

利用这种复合使能特性,仅需4片74HC138芯片和1个反相器,即可轻松实现并行扩展,组合成为一个1-32(5线到32线)译码器。

任选一个低有效使能输入端作为数据输入,而把其余的使能输入端作为选通端,则74HC138亦可充当一个8输出多路分配器,未使用的使能输入端必须保持绑定在各自合适的高有效或低有效状态。

3)74HC4953 行驱动管,功率管
多用于LED点阵显示屏驱动,当每一显示行需要的电流是比较大时,要使用行驱动管,每片4953内部有两个行驱动管,可以驱动2个显示行。

其内部是两个CMOS管,1、3脚VCC,2、4脚控制脚,2脚控制7、8脚的输出,4脚控制5、6脚的输出,只有当2脚为“0”时,7、8才会输出,否则输出为高阻状态(漏极开路),只有当4脚为“0”时,5、6才会输出,否则输出为高阻状态(漏极开路)。

4)74HC245
总线收发器(bus transceiver),典型的CMOS型三态缓冲门电路。

由于单片机或CPU的数据/地址/控制总线端口都有一定的负载能力,如果负载超过其负载能力,一般应加驱动器。

另外,也可以使用74HC244等其他缓冲门电路。

74HC244是单向,74HC245是双向。

第1脚DIR,为输入输出端口转换用,DIR=“1”高电平时信号由“A”端输入“B”端输出,DIR=“0”低电平时信号由“B”端输入“A”端输出。

第2~9脚“A”信号输入输出端,A0=B0,A7=B7,A0与B0是一组,如果DIR=“1”OE=“0”则A1输入B1输出,其它类同。

如果DIR=“0”OE=“0”则B1输入A1输出,其它类同。

第11~18脚“B”信号输入输出端,功能与“A”端一样,不再描述。

第19脚OE,使能端,若该脚为“1”A/B端的信号将不导通,只有为“0”时A/B端才被启用,该脚也就是起到开关的作用。

第10脚GND,电源地。

第20脚VCC,电源正极。

五.软件设计
1.流程图
注:16行
图9 软件系统框图
2.程序代码
#include <AT89x51.H>
#define uchar unsigned char
#define uint unsigned int
#define light 6 //定义亮度
uchar code hanzi[]; //汉字字模
uchar code timer[12][16]; //0~9数字
uchar code sw[]; //138驱动数据
void Show_word(); //待机显示按三秒间隔分别显示年、月日、星期、时分秒。

void Show_pass(); //不显示一个字
void Send_data(unsigned char *d); /*串口发送一行*/
/******************************************/
sbit resget=P0^2; //时钟复位
sbit key_moda=P0^3; //模式转换
sbit key_up=P0^4; //时钟加
sbit key_Down=P0^5; //时钟减
sbit T_CLK=P2^3; //DS1302引脚连接
sbit T_IO =P2^2;
sbit T_RST=P2^1;
sbit ACC0=ACC^0; //1bit数据存储位
sbit ACC7=ACC^7;
sbit STR=P1^7; //锁存
sbit CLK=P3^1; //时钟
sbit Data= P3^0; //数据
sbit E=P1^4;
uchar starts_time[7]={0x00,0x10,0x22,0x11,0x06,0x07,0x06}; //初始化后设置
uchar Move,Speed,Flicker,line,Sec,Cent,Hour,Year,Month,Day,Week; //时间变量
uchar a,b,f,h,msec,id,x; //标志计数器a为自动转换显示时间,b为手动与自动标志uint zimuo; //字模计数器
uchar BUFF[10]; //缓存
void RTInputByte(uchar); /* 输入1Byte */
uchar RTOutputByte(void); /* 输出1Byte */
void W1302(uchar, uchar); // 向DS1302写入一个字节
uchar R1302(uchar); // 从DS1302读出一个字节
void Set1302(uchar *); // 写DS1302时间
void du1302(); // 读时间
void DelayMs(void); // 延时
void Set(uchar,uchar ); // 变量调整
void in_data(); // 调整移动数据
void rxd_data(); // 串口发送移动数据
/*主函数*/
void main()
{
Move=0;
zimuo=0;
TMOD=0x01; //16位定时
TH0=0x3c; //25ms晶振为24M
TL0=0xb0;
EA=1;
TR0=1;
ET0=1;
SCON=0; //初始化串口为工作方式0(同步通信方式,TxD输出同步脉冲)
while(zimuo<512)
{
while(Move<16) //数据移位。

{
for(Speed=0;Speed<2;Speed++) //移动速度
{
for(line=0;line<16;line++)
{
in_data(); //调整移动数据
rxd_data();
P1=sw[line];
STR=1;STR=0;
P1_7=1;
DelayMs(); //延时,等待一段时间,让这列显示的内容在人眼内产生“视觉暂留”现象。

*/
}
}
Move++; //移动一步
}
Move=0;
zimuo=zimuo+32;
}
zimuo=0;
while(1) //重复循环显示
{
if(resget==0)
{ DelayMs();
if(resget==0)
Set1302(starts_time); //初始化
W1302(0x8e,0x00); //控制命令,WP=0,写操作
W1302(0x90,0xa5); //打开充电二级管一个二级管串联一个2K 电阻
}
du1302(); //读取秒分时日月星期年
if (key_moda==0) //设置和选择项目键
{ DelayMs();
if(key_moda==0)
{
if(id++==9) {id=0;}
h=0;msec=0; //清闪烁标志
while(key_moda==0){ Show_word();}
}
}
if(id!=0)
{
if (key_up==0) //增加
{
DelayMs();
if(key_up==0)
{
while(key_up==0)
{Show_word();} //调用显示
h=0;msec=0; //清闪烁标志
Set(id,0); //调用时间调调整}
}
if (key_Down==0) //减少
{
DelayMs();
if(key_Down==0)
{
while(key_Down==0)
{Show_word();} //调用显示
h=0;msec=0; //清闪烁标志
Set(id,1); //调用时间调调整
}
}
}
else
{
if (key_up==0) //增加
{
DelayMs();
if(key_up==0)
{
while(key_up==0)
{Show_word();} //调用显示
h=0;msec=0; //清闪烁标志
if(b!=0) //手动调整显示的内容
{
if(f++==3) //f为显示转换标志
f=0;
}
}
}
}
Show_word(); //待机显示按三秒间隔分别显示年、月日、星期、时分秒。

}
}
/************************************************/
void Show_word() //串行输出显示
{ uchar h;
for(h=0;h<16;h++)
{
if((id==0)&(f==0)|(id==1)) //f为三秒转换显示
{
Send_data(&timer[0][0]); //不显示
if((Flicker==1)&(id==1)) //闪烁标志为1时不亮,为零时亮
{ Show_pass(); //不显示一个字
Show_pass();
}
else
{
Send_data(&timer[2][h]); //20年
Send_data(&timer[0][h]);
Send_data(&timer[Year/16][h]); //年值
Send_data(&timer[Year%16][h]);
}
Send_data(&hanzi[h*2+641]); //年字符
Send_data(&hanzi[h*2+640]);
Send_data(&timer[0]);
//不显示
}
if((id==0)&(f==1)|(id==2)|(id==3))
{
if((Flicker==1)&(id==2)) //闪烁标志为1时不亮,为零时亮{ Show_pass(); //不显示一个字
}
else
{
if(Month/16<1)
Send_data(&timer[0]); //月十位为零时不显示
else
Send_data(&timer[Month/16][h]); //月值
Send_data(&timer[Month%16][h]);
}
Send_data(&hanzi[h*2+673]); //月字符
Send_data(&hanzi[h*2+672]);
if((Flicker==1)&(id==3)) //闪烁标志为1时不亮,为零时亮
{ Show_pass(); //不显示一个字
}
else
{
Send_data(&timer[Day/16][h]); //日值
Send_data(&timer[Day%16][h]);
}
Send_data(&hanzi[h*2+961]); //日字符
Send_data(&hanzi[h*2+960]);
}
if((id==0)&(f==2)|(id==4)) //f为三秒转换显示
{
Send_data(&timer[0]); //不显示
Send_data(&hanzi[h*2+705]); //星字符
Send_data(&hanzi[h*2+704]);
Send_data(&hanzi[h*2+737]); //期字符
Send_data(&hanzi[h*2+736]);
if((Flicker==1)&(id==4)) //闪烁标志为1时不亮,为零时亮
{ Show_pass(); //不显示一个字
}
else
{
Send_data(&hanzi[Week%16*32+h*2+737]); //星期值
Send_data(&hanzi[Week%16*32+h*2+736]);
}
Send_data(&timer[0][0]); //不显示
}
if((id==0)&(f==3)|(id>4)) //f为三秒转换显示
{
if((Flicker==1)&(id==5)) //闪烁标志为1时不亮,为零时亮
{
Show_pass(); //不显示一个字
}
else
{
if(Hour/16<1)
Send_data(&timer[0][0]); //时十位小于1时不显示
else
Send_data(&timer[Hour/16][h]); //时值
Send_data(&timer[Hour%16][h]);
}
Send_data(&timer[10][h]); //两个点
if((Flicker==1)&(id==6)) //闪烁标志为1时不亮,为零时亮
{
Show_pass(); //不显示一个字
}
else
{
Send_data(&timer[Cent/16][h]);
Send_data(&timer[Cent%16][h]); //分值
}
Send_data(&timer[10][h]); //两个点
if((Flicker==1)&(id==7)) //闪烁标志为1时不亮,为零时亮
{
Show_pass(); //不显示一个字
}
else
{
Send_data(&timer[Sec/16][h]); //秒
Send_data(&timer[Sec%16][h]);
}
}
if(id>7) //id大于7时为对显示转换模式设置
{ if((Flicker==1)&(id==8))
{ Show_pass();
Show_pass();
Show_pass();
Show_pass();
}
else if(b==0)
{
Send_data(&hanzi[h*2+993]); //显示汉字“自”
Send_data(&hanzi[h*2+992]);
Send_data(&hanzi[h*2+1057]); //显示汉字“动”
Send_data(&hanzi[h*2+1056]);
Send_data(&hanzi[h*2+1089]); //显示汉字“模”
Send_data(&hanzi[h*2+1088]);
Send_data(&hanzi[h*2+1121]); //显示汉字“式”
Send_data(&hanzi[h*2+1120]);
}
else
{
Send_data(&hanzi[h*2+1025]); //显示汉字“手”
Send_data(&hanzi[h*2+1024]);
Send_data(&hanzi[h*2+1057]); //显示汉字“动”
Send_data(&hanzi[h*2+1056]);
Send_data(&hanzi[h*2+1089]); //显示汉字“模”
Send_data(&hanzi[h*2+1088]);
Send_data(&hanzi[h*2+1121]); //显示汉字“式”
Send_data(&hanzi[h*2+1120]);
}
if(id==9)
{
if(b==1) //手动模式
{
id=0;f=0;
}
else
{
Send_data(&hanzi[h*2+993]); //显示汉字“自”
Send_data(&hanzi[h*2+992]);
Send_data(&hanzi[h*2+1057]); //显示汉字“动”
Send_data(&hanzi[h*2+1056]);
if(Flicker==1)
{
Show_pass();
}
else
{
Send_data(&timer[a/16][h]); //转换时间
Send_data(&timer[a%16][h]);
}
Send_data(&hanzi[h*2+1153]); //显示汉字“秒”
Send_data(&hanzi[h*2+1152]);
}
}
}
P1=sw[h]; //输出行信号
STR=1;STR=0;
P1_7=1; //锁存为高,595锁存信号DelayMs(); //延时,等待一段时间,让这列显示的内容在人眼内产生“视觉暂留”现象。

*/
}
}
//temp=255-temp;
//return temp;
void timer_1(void) interrupt 1 //中断入口,闪烁
{
TH0=0x3C; //25ms定时晶振24M
TL0=0xB0;
if(msec++==40) //1000ms
{ msec=0;
x++;
if(x>=a)
{ x=0;
if(b==0) //自动模式
{if(f++==3)
f=0; //f显示转换计数器,d为用户设置的自动转换时间的值。

}
}
if(h++==4) //5秒后进入正常走时。

{id=0;h=0;}
}
if(msec<20)
Flicker=0; //闪烁标志反转
else
Flicker=1;
}
/***********************输出一个字的不显示数据。

*****************/
void Show_pass()
{
Send_data(&timer[0][0]); //不显示
Send_data(&timer[0][0]); //不显示
}
/**********************************************************/
void in_data(void) //调整数据
{
char s;
for(s=4;s>=0;s--) //i为向后先择字节计数器,zimuoo 为向后先字计数器
{
BUFF[2*s+1]=hanzi[zimuo+32*s+2*line]; //把第一个字模的第一个字节放
入BUFF0中,第二个字模和第一个字节放入BUFF2中
BUFF[2*s]=hanzi[zimuo+1+32*s+2*line]; //把第一个字模的第二个字节放入BUFF1中,第二个字模的第二个字节放入BUFF3中
}
}
/***********************发送移动的数据****************************/
void rxd_data(void) //串行发送数据
{
uchar s;
uchar inc,tempyid,temp;
if(Move<8)
inc=0;
else
inc=1;
for(s=0+inc;s<8+inc;s++) //发送8字节数据
{
if(Move<8)
tempyid=Move;
else
tempyid=Move-8;
temp=(BUFF[s]>>tempyid)|(BUFF[s+1]<<(8-tempyid)); //h1左移tempyid位后和h2右移8-tempyid相或,取出移位后的数据。

temp=255-temp;
SBUF=temp; //把BUFF中的字节从大到小移位相或后发送输出。

while(TI==0); //等待发送完毕
TI=0;
}
}
/*******************************************************/
void Send_data(unsigned char *d) /*从串口发送数据*/
{
SBUF=*d;
while(TI==0); //等待发送完毕
TI=0;
}
//根据选择调整相应项目
void Set(uchar sel,uchar sel_1)
{
uchar address,time;
uchar max,min;
if(sel==9) {address=0xc2; max=20;min=1;} //自动转换时间时最大为20秒。

if(sel==8) {address=0xc0; max=1;min=0;} //显示自动转换或手动转换。

为零自动,为1手动。

if(sel==7) {address=0x80; max=0;min=0;} //秒
if(sel==6) {address=0x82; max=59;min=0;} //分钟
if(sel==5) {address=0x84; max=23;min=0;} //小时
if(sel==4) {address=0x8a; max=7; min=1;} //星期
if(sel==3) {address=0x86; max=31;min=1;} //日
if(sel==2) {address=0x88; max=12;min=1;} //月
if(sel==1) {address=0x8c; max=99;min=0;} //年
time=R1302(address+1)/16*10+R1302(address+1)%16;
if (sel_1==0) time++; else time--;
if(time>max) time=min;
if(time<min) time=max;
W1302(0x8e,0x00);
W1302(address,time/10*16+time%10);
W1302(0x8e,0x80);
}
/**************************延时***********************/
void DelayMs(void)
{
uchar TempCyc;
for(TempCyc=100;TempCyc>1;TempCyc--)
{;}
}
//********DS1302读写程序***************//
/********************************************************************
函数名:RTInputByte()
功能:实时时钟写入一字节
说明:往DS1302写入1Byte数据(内部函数)
入口参数:d 写入的数据
返回值:无
***********************************************************************/ void RTInputByte(uchar d)
{
uchar h;
ACC = d;
for(h=8; h>0; h--)
{
T_IO = ACC0; /*相当于汇编中的RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函数名:RTOutputByte()
功能:实时时钟读取一字节
说明:从DS1302读取1Byte数据(内部函数)
入口参数:无
返回值:ACC
设计:zhaojunjie 日期:2002-03-19
修改:日期:
***********************************************************************/ uchar RTOutputByte(void)
{
uchar h;
for(h=8; h>0; h--)
{
ACC = ACC >>1; /*相当于汇编中的RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
函数名:W1302()
功能:往DS1302写入数据
说明:先写地址,后写命令/数据(内部函数)
调用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返回值:无
***********************************************************************/ void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令*/
RTInputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函数名:R1302()
功能:读取DS1302某地址的数据
说明:先写地址,后读命令/数据(内部函数)
调用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返回值:ucData :读取的数据
***********************************************************************/ uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令*/
ucData = RTOutputByte(); /* 读1Byte数据*/
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函数名:Set1302()
功能:设置初始时间
说明:先写地址,后读命令/数据(寄存器多字节方式)
调用:W1302()
入口参数:pClock: 设置时钟数据地址格式为: 秒分时日月星期年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返回值:无
***********************************************************************/ void Set1302(uchar *pClock)
{
uchar h;
uchar ucAddr = 0x80;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
for(h =7; h>0; h--)
{
W1302(ucAddr,*pClock); /* 秒分时日月星期年*/
pClock++;
ucAddr +=2;
}
W1302(0xc0,0x01);
W1302(0XC2,0X03); //初始自动转换显示时间为3秒。

W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
}
/******************读取DS1302中的时间****************/
void du1302()
{
Sec=R1302(0x81); //对取秒分时日月星期年
Cent=R1302(0x83);
Hour=R1302(0x85);
Day=R1302(0x87);
Month=R1302(0x89);
Week=R1302(0x8b);
Year=R1302(0x8d);
b=R1302(0xc1);
a=R1302(0xc3);
a=a/16*10+a%16;
}
uchar code sw[16]={0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 };/*16行段码*/
const uchar code timer[12][16]={ /*0~9字符*/
/*-- 文字: 0 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xE3,0xDD,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xDD,0xE3,0xFF,0xF F,
/*-- 文字: 1 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xEF,0xE7,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,
/*-- 文字: 2 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xC7,0xBB,0x7D,0x7F,0x7F,0xBF,0xCF,0xF7,0xFB,0xFD,0xFD,0x01,0xFF,0xFF,
/*-- 文字: 3 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xC7,0xBB,0x7D,0x7F,0xBF,0xC7,0xBF,0x7F,0x7F,0x7D,0xBB,0xC7,0xFF,0xFF,
/*-- 文字: 4 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xCF,0xCF,0xD7,0xD7,0xDB,0xDB,0xDD,0xDD,0xDE,0x00,0xDF,0xDF,0xFF,0xFF ,
/*-- 文字: 5 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0x01,0xFD,0xFD,0xFD,0xC5,0xB9,0x7D,0x7F,0x7F,0x7D,0xBB,0xC7,0xFF,0xFF, /*-- 文字: 6 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xC7,0xBB,0x7D,0xFD,0xFD,0xC5,0xB9,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF, /*-- 文字: 7 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0x01,0x7F,0xBF,0xDF,0xDF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xFF,0xFF,
/*-- 文字: 8 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xE3,0xDD,0xBE,0xBE,0xDD,0xE3,0xDD,0xBE,0xBE,0xBE,0xDD,0xE3,0xFF,0xF F,
/*-- 文字: 9 --*/
/*-- Book Antiqua12; 此字体下对应的点阵为:宽x高=8x20 --*/
0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x3B,0x47,0x7F,0x7F,0x7F,0xBD,0xC3,0xFF,0xFF,
/*-- 文字: : --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0xFF,0xFF,0xFF,0xFF,0xE7,0xE7,0xFF,0xFF,0xFF,0xFF,0xE7,0xE7,0xFF,0xFF,0xFF,0xFF,
/*-- - -- ** 宋体, 12 **
/*--黑屏字符--*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, };
const uchar code hanzi[]={/*移动显示汉字字模,*/
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, 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, 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, 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, /*-- 文字: 演--*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x40,0x80,0x20,0x40,0x2F,0xFE,0x08,0x02,
0x90,0x04,0x67,0xFC,0x20,0x40,0x0F,0xFC,
0x14,0x44,0x27,0xFC,0xE4,0x44,0x27,0xFC,
0x20,0x00,0x21,0x10,0x23,0x0C,0x24,0x04,
/*-- 文字: 示--*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x10,0x3F,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0xFF,0xFE,0x01,0x00,
0x01,0x00,0x09,0x20,0x19,0x18,0x21,0x0C,
0x41,0x04,0x01,0x00,0x05,0x00,0x02,0x00,
/*-- 文字: 的--*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x10,0x40,0x10,0x40,0x22,0x44,0x7F,0x7E,
0x42,0x84,0x43,0x04,0x42,0x04,0x42,0x84,
0x7E,0x64,0x42,0x24,0x42,0x04,0x42,0x04,
0x42,0x04,0x7E,0x04,0x42,0x28,0x00,0x10,
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x00,0x10,0x1F,0xF8,0x10,0x10,0x10,0x10,
0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,
0x14,0x50,0x44,0x44,0x34,0x4C,0x14,0x50,
0x04,0x40,0x04,0x44,0xFF,0xFE,0x00,0x00,
/*-- 文字: 示--*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x00,0x10,0x3F,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0xFF,0xFE,0x01,0x00,
0x01,0x00,0x09,0x20,0x19,0x18,0x21,0x0C,
0x41,0x04,0x01,0x00,0x05,0x00,0x02,0x00,
/*-- 文字: 屏--*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x00,0x08,0x3F,0xFC,0x20,0x08,0x20,0x08,
0x3F,0xF8,0x22,0x20,0x21,0x48,0x2F,0xFC,
0x22,0x20,0x22,0x24,0x3F,0xFE,0x22,0x20,
0x22,0x20,0x42,0x20,0x84,0x20,0x08,0x20,
/*-- 文字: --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 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,
/*-- 文字: --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 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,
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x08,0x04,0x08,0x7E,0x08,0x44,0x08,
0x47,0xFE,0x44,0x08,0x44,0x08,0x7C,0x88,
0x44,0x48,0x44,0x48,0x44,0x08,0x44,0x08,
0x7C,0x08,0x44,0x48,0x00,0x28,0x00,0x10,
/*-- 文字: 间8--*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x20,0x04,0x1B,0xFE,0x08,0x04,0x40,0x24,
0x4F,0xF4,0x48,0x24,0x48,0x24,0x48,0x24,
0x4F,0xE4,0x48,0x24,0x48,0x24,0x48,0x24,
0x4F,0xE4,0x48,0x24,0x40,0x14,0x40,0x08,
/*-- 文字: :11--*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x06,0x00,0x0F,0x00,
0x0F,0x00,0x06,0x00,0x00,0x00,0x06,0x00,
0x0F,0x00,0x0F,0x00,0x06,0x00,0x00,0x00,
/*-- 文字: 2 --*/
/*-- 华文新魏12; 此字体下对应的点阵为:宽x高=16x17 --*/ 0x00,0x00,0x07,0xE0,0x08,0x10,0x10,0x10,
0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x40,
0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,
0x08,0x00,0x10,0x00,0x3F,0xF8,0x00,0x00,
/*-- 文字: 0 --*/
/*-- 华文新魏12; 此字体下对应的点阵为:宽x高=16x17 --*/ 0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x1F,0xF0,0x00,0x00,
/*-- 文字: 1 --*/
/*-- 华文新魏12; 此字体下对应的点阵为:宽x高=16x17 --*/ 0x00,0x00,0x0C,0x00,0x14,0x00,0x24,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,
0x04,0x00,0x04,0x00,0x07,0xC0,0x00,0x00,
/*-- 文字: 2 --*/
/*-- 华文新魏12; 此字体下对应的点阵为:宽x高=16x17 --*/ 0x00,0x00,0x07,0xE0,0x08,0x10,0x10,0x10,
0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x40,
0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,
0x08,0x00,0x10,0x00,0x3F,0xF8,0x00,0x00,
/*-- 文字: 1 --*/
/*-- 华文新魏12; 此字体下对应的点阵为:宽x高=16x17 --*/ 0x00,0x00,0x0C,0x00,0x14,0x00,0x24,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,
0x04,0x00,0x04,0x00,0x07,0xC0,0x00,0x00,
/*-- 文字: 月--*/
/*-- 华文新魏12; 此字体下对应的点阵为:宽x高=16x17 --*/ 0x00,0x00,0x0F,0xF0,0x08,0x10,0x08,0x10,
0x08,0x10,0x0F,0xF0,0x08,0x10,0x08,0x10,
0x08,0x10,0x0F,0xF0,0x08,0x10,0x08,0x10,
0x10,0x10,0x10,0x10,0x20,0x50,0x40,0x20
};
六.系统调试及分析
把显示屏电路和显示屏驱动电路分别做在两块电路板上,显示屏电路的行扫描信号输出管脚和列显示信号数据输出管脚分别引用两排的排针引出,排针长的那一头接到电路板的底层,以方便插入驱动电路的插槽中。

同样在驱动电路用两排插槽将行扫描信号输出管脚和列显示信号数据输出管脚引出,在画PCB时应当注意屏电路PCB中两排排针之间的距离要与驱动电路PCB中两排插槽之间的距离一样,才能保证能正确地将显示屏电路板排到驱动电路电路板上方。

1.硬件调试出现错误及解决方案:
计数器的时候,接线如下:
P1.1接一个拨动开关;
P3.2接正脉冲;
2软件调试出现错误及解决方案:
问题一:显示的数字有残影。

原因:每扫描完一列之后,没有清除显示。

解决方案:每扫描完一行一列之后,对行和列都进行清屏。

问题二:计数时,十进制计到9(16进制计到F),后面不自动跳到0,而是乱码显示。

原因:没有进行判断是否到达表尾。

解决方案:在每次扫描完一个数字之后,就进行判断是否到达表尾,若是到表尾,则跳转至表首,若是没有到表尾则继续接着上次的查表地址继续查表。

问题三:滚动一个字符的时候,一遍滚动完之后,不会循环滚动而是乱码。

原因:同上,没有进行是否到达表尾的判断。

解决方案:在每次扫描完一个字符之后,即16行48列扫描完并且延时显示一段时间后,判断查表地址是否到达表尾,若是到达表尾,则跳转至表首。

若是没有到达则接着上次的地址继续查表扫描。

问题四:滚动名字的时候,除了第一个字之外其余两个字上面八列和下面八
列上下颠倒。

原因:第一个字扫描显示完之后,后面的自符扫描时的查表地址直接进行递加,从而导致上下颠倒。

解决方案:把每个字的上半部分即上面8列的二进制数和下半部分即下面8 列的二进制数放在两个表中,这样没扫描完一个字符时再进行累加就滚动正确了。

七.成果
1.电源电路
2.PCB板
3.最小单片机单元电路
4.显示屏
八.心得体会
随着信息产业的高速发展,LED显示屏作为信息传播的一种重要手段成为现代信息化社会的一个闪亮标志。

近年LED显示屏已广泛应用于室内、外需要进行服务内容和服务宗旨宣传的公众场所如银行、营业部、车站、机场、港口、体育场馆等信息的发布,政府机关政策、政令,各类市场行情信息的发部和宣传等。

目前,对于那些需要显示的信息量不是很大,分辨率不是很高,又需要制造成本相对比较低的场合,使用大、小屏幕LED点阵显示器是比较经济适用的,它可以用单片机控制实现显示字符、数字、汉字和简单图形,可以根据需要使用不同字号、字型。

因此学校为我们安排了单片机应用技术的实训。

这次的实训制作一个16×48 LED点阵显示屏,融入各种基础知识和实践经验,再拓展到各种计算机知识。

这次实验共用了5个星期,在这5个星期里我们了解了元器件的特点及其运行电路,在此基础上对所需的电路进行设计与分析,将电路进行焊接,然后对电路调试分析,最后通过答辩,来验收学生对这次课程设计的了解。

通过这几周的实验,我们一组合作完成了这次实验,虽然在其中遇到了很多问题,但是通过了和其他组同学的讨论,问题也得到了一定的解决,在最开始的时候我们做的有点慢,重复画了好几张图,那是因为我们组没有很好的理解老师的要求,大概是因为这个课程设计历时较长,有点被吓住了,不过我们很快调节
好自己,来完成这次实验。

不论是硬件还是软件,资料的查阅都是非常重要,我
们要得到有用的信息,那就必须有着很好的查阅资料袋能力,不管是从网上还是从图书馆,利用已有的资源更好的去完成自己要做到事情。

我们也应该学会很好的与同学老师沟通,以获得更多的有用资料。

与焊接相比较,连接编程的工作是更大量、更费时间和精力的,也是更重要的。

在这次的实训过程中单片机的编程给我留下了深刻的印象。

上课时大家听老师讲好像很简单,可我们自己都动手去编时,大家才发现这是个大问题,我深刻体会到了单片机应用技术是一门实践性很强的课程。

既要掌握概念,又要较强的动手实践能力,因此我们尽最大的努力将所学到的知识运用到其它更多的地方进行实践和更好的掌握。

对这个项目,必须知道这个项目要实现什么功能,画出功能框图;根据项目要求分析设计出硬件系统框图,完成硬件电路;根据硬件电路图,设计软件系统框图,进而画出程序流程图;根据程序流程图设计程序;上机运行调试。

通过这次单片机课程设计,我对完整的设计一个程序有了一个深刻的理解,先画好了程序流程图,然后再写程序,写好程序之后根据所画的流程图去调试程序,就很快发现了程序中的错误并改正。

项目中除了软件程序之外,硬件也是特别重要的,我们首先要确保硬件线路的连接正确,在这个基础上才能确保程序调试的效率。

总而言之,就是我们在做一件事的时候,必须先要做的就是一个总的规划,然后是模块化分析,要有足够的耐心与细心、认真一步步的完善。

在整个课程设计的过程中,我深深地体会到细心,耐心以及一个认真的态度对做成功一件事情是多么的至关重要。

通过这次课程设计,我不仅从理论知识更是从实际操作能力上都有了很大的提高,真的是受益匪浅,为我们以后做更大的项目打下了很好的基础。

参考文献:百度问问、中国电子网
附录:
1.最小单片机单元电路
Sheet
PCB板的布线。

相关文档
最新文档