LCD12864液晶显示电子钟设计

更新时间:2024-06-28 06:10:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《单片机原理及应用》

课程设计说明书

题目 LCD12864 液晶显示电子钟设

系(部)

专业(班级) 姓学指起

名 号

导止

教日

师 期

课程设计任务书

系(部): 专业:

LCD12864 液晶显示电子钟设计 设计一种基于 AT89S52 单片机的液晶显示电子时钟,要求如下: (1) 、 能正确显示时间、 日期和星期显示格式为: 时间: XX 小时:XX 分: XX 秒;日期:XX 年:XX 月:XX 日;星期:X。 (2) 、时间能够由按键调整,误差小于 1S。 (3) 、 闹钟功能: 时间运行到与闹钟设定时间时, 闹钟响 (持续响 3 秒)。 设计(4) 、 报时功能: 时间运行到正点时间时, 闹钟响, 几点钟就响几要求 声 (每 声持续响 2 秒,每两声之间时间间隔 1 秒)。 液晶显示器第一行显示“数字电子钟” ;第二行显示“当前时间” ;第三 行显示日期和星期;第四行显示最近一个闹钟的设定时间。 2、要求: 完成该系统的硬件和软件的设计,在 Proteus 软件上仿真通过, 并提交 一篇课程设计说明书。 课题名称 设计工作量 1、汇编或 C51 语言程序设计; 2、程序调试; 3、在 Proteus 上进行仿真成功,进行实验板下载调试; 4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序 分析、仿真分析、调试过程,参考文献、设计总结等。 起止日期 第一天 工作第二天 计划 第三天~第六天 第六天~第八天 第九天~第十天 工作内容 课题绍,答疑,收集材料,C51介绍 设计方案论证,练习编写 C51 程序 程序设计 程序调试、仿真 系统测试并编写设计说明书 系(部)教研室 年 月 日 主管领导 年 月 日 意见 意见

目录

一、12864液晶的工作原理 .....................................................................................................................4 二、方案设计 ............................................................................................................................................4 2.1 实物硬件设计 ..................................................................................................................................4 2.2 系统硬件设计 ..................................................................................................................................5 2.2.1 主芯片模块 ..................................................................................................................................5 2.2.2 晶振和复位模块 ..........................................................................................................................5 2.2.3 按钮模块 ......................................................................................................................................6 2.3 系统软件设计 ..................................................................................................................................6 2.3.1 主程序设计 ..................................................................................................................................6 三、仿真和分析 ........................................................................................................................................7 四、总结体会 ............................................................................................................................................7 参考文献 ..................................................................................................................................................33

一、12864液晶的工作原理

液晶显示屏中的业态光电显示材料,利用液晶的电光效应把电信号转换成数字符、图像等可见信号。

如图1-1,液晶正常情况下,其分子排列很有秩序,显得清澈透明,一旦加上直流电场后,分子的排列被打乱,一部分液晶变的不透明,颜色加深因而能显示数字和图像。管脚一共1个CS1左半屏片选端,CS2右半屏片选端;V0液晶显示驱动电压,通过一个电位器接到VCC;RS数据指令选择信号,H为数据,L为指令,也叫D/I;R/W读写选择信号,H为读,L为写,。E为LCD使能端,R/W为L时,E信号下降沿锁存 DB7-DB0;R/W为H时,E为H,DDRAM数据读到DB7-DB0。DB0-DB7数据传输端口。RST复位信号。-VOUT 和V0为液晶显示驱动电压。 12864是一种图形点阵液晶显示器,它主要由行驱动器/列驱动器及128×64 全点阵液晶显示器组成。可完成图形显示,也可以显示8×4个(16×16点阵)汉字。 

图1-1 12864LCD液晶显示屏

二、方案设计

2.1 实物硬件设计

单片机控制液晶显示屏系统总共可分为六个环节,分别是单片机控制系统、12864字符显示模块、控制开关模块、晶振控制模块、复位电路模块和DS1302时钟控制模块。通过这六个模块的协调工作就可以完成相应的液晶屏控制和显示功能。这六个模块的相互连接如图2-1:

图2-1 硬件组成框图

2.2 系统硬件设计

本硬件电路主要由四大模块组成:主芯片模块;晶振和复位电路模块;控制接钮模块;显示电路

模块。

2.2.1 主芯片模块

主芯片模块即单片机模块,XTAL1:接外部晶振和微调电容的一端。在片内,它是振荡电路反相放大器的输入端。XTAL2:接外部晶振和微调是容的一端。RST:AT89C51的复位信号输入引脚,高电平有效。当此输入端保持两个机器周期的高电平时,就可以完成复位操作。ALE:允许地址锁存信号端。EA:该引脚为低电平时,则读取外部的程序代码来执行程序。P0、P1、P2、P3:8位并行输入输出口。每个端口都是8位准双向口,共占32只引脚。每一条都能独立地用作输入或输出。每个端口都包括一个锁存器、一个输出驱器和输入缓冲器。作输出时,数据可以锁存;作输入时,数据可以缓冲。图如图3—1。

图3-1 单片机引脚图 2.2.2 晶振和复位模块

89C51芯片内部有一个高增益反相放大器,用于构成振荡器。如图3—2,反相放大器的输入端为XTAL1,输出端XTAL2,两个跨接石英晶体及两个电容就可以构成稳定的自激振荡器。XTAL1 是片内振荡器的反相放大器输入端,XTAL2 则是输出端,使用外部振荡器时,外部振荡信号应直接加到XTAL1,而XTAL2 悬空。一个晶体振荡器,接在单片机内部的振荡电路上,两个电容是起振电容,频率越高,应该越小。

图4-1 晶振模块

在振荡器运行时,有两个机器周期(24 个振荡周期)以上的高电平出现在此引脚时,将使单片机复位,只要这个脚保持高电平,51 芯片便循环复位。复位后P0-P3 口均置1 引脚表现为高电平,程序计数器和特殊功能寄存器SFR 全部清零。当复位脚由高电平变为低电平时,芯片为ROM 的00H 处开始运行程序。如上图5-1所示复位电路,由于复位时高电平有效,当刚接上电源的瞬间,电容C1两端相当于短路,即相当于给RESET引脚一个高电平,等充电结束时(这个时间很短暂),电容相当于断开,这时已经完成了复位动作。

图5-1 复位模块 2.2.3 按钮模块

本模块采用四个按钮进行控制,通过串行口输入输出连接,当K1按键波动一次后,方可进行年、月、日、星期、时、分的改变,当循环满时,按下K0可实现对闹钟的改变。按键K2、K3分别实现加一减一的操作。

图6-1 按钮模块

2.3 系统软件设计 2.3.1 主程序设计

图7-1 主程序流程图

图8-1 LCD显示程序和初始化子程序流程图

三、仿真和分析

将程序下载到单片机开发板上,LCD12864显示如下图,第一行为汉字“数字电子钟”,第二行为时分秒,第三行为年月日以及星期,第四行为闹钟,通过按键可实现时间的调整,也可实现整点报时和闹钟。符合设计要求。

图9-1 实物仿真图

程序:

#include

#include #include

#define uchar unsigned char #define uint unsigned int

sbit rs=P1^0;//12864引脚定义 sbit rw=P1^1; sbit en=P1^2; sbit PSB=P1^3;

sbit beep=P3^4;//蜂鸣器引脚定义 sbit k1=P3^5;//按键定义 sbit k2=P3^6; sbit k3=P3^7; sbit k0=P0^0;

uint t,k,kk;

uchar shi,fen,miao,nian=13,yue,ri,zhou,shi0,fen0,miao0; uchar code dis1[]={0xca,0xfd,\字电子钟\显示字组 uchar code dis2[]={\时00分00秒%uchar code dis3[]={\年00月00日 1%uchar code dis4[]={\闹钟00时00分00秒\

void delayms(uint xms)//延时xms函数

{ }

void warn(uchar xn)//“嘟”xn次函数 {

uint nn;

for(nn=0;nn

uint n;

for(n=2000;n>0;n--) { }

for(n=1000;n>0;n--) {

beep=1; delayms(3);

beep=1; delayms(1); beep=0; delayms(2);

uchar i,j; for(i=xms;i>0;i--)

for(j=110;j>0;j--);

}

}

void warn3s()//3s报警函数 { }

void write_com(uchar com)//12864写指令函数 { }

rs=0; rw=0; en=0; P2=com; delayms(5); en=1; delayms(5); en=0; uint n;

for(n=3000;n>0;n--) { }

beep=0; delayms(2); beep=1; delayms(1);

void write_data(uchar date)//12864数据指令函数 { }

void lcd_pos(uchar X,uchar Y)//12864显示位置函数 {

uchar pos; if(X==0) { } if(X==1) { } if(X==2)

X=0x90; X=0x80; rs=1; rw=0; en=0; P2=date; delayms(5); en=1; delayms(5); en=0;

}

{ } if(X==3) { } pos=X+Y; write_com(pos);

X=0x98; X=0x88;

void write_sfm(int add,uint date)//时钟数值函数 { }

void write_sfm1(int add1,uint date1)//年月日数值函数 {

uchar shi,ge; shi=date1/10; uchar shi,ge; shi=date/10; ge=date; lcd_pos(1,0+add); write_data(0x30+shi); write_data(0x30+ge);

}

ge=date1; lcd_pos(2,0+add1); write_data(0x30+shi); write_data(0x30+ge);

void write_sfm2(int add2,uint date2)//闹钟数值函数 { }

void keyscan()//按键扫描函数 {

if(k0==0)//闹钟按键操作 {

delayms(5); if(k0==0) {

while(!k0); kk++; if(kk==1)

uchar shi,ge; shi=date2/10; ge=date2; lcd_pos(3,0+add2); write_data(0x30+shi); write_data(0x30+ge);

}

}

{ }

TR0=0;

write_com(0x0f); lcd_pos(3,2);

if(kk==2) { } if(kk==3) { } if(kk==4) { }

kk=0; TR0=1;

write_com(0x0c);

lcd_pos(3,6); lcd_pos(3,4);

if(k1==0)//调试按键操作 {

delayms(5); if(k1==0)

{ } if(k==2) { } if(k==3) { } if(k==4) { } if(k==5) {

lcd_pos(2,2); lcd_pos(2,4); lcd_pos(1,0); lcd_pos(1,2); k++; while(!k1); if(k==1) { }

TR0=0;

write_com(0x0f); lcd_pos(1,4);

}

} if(k==6) { } if(k==7) { } if(k==8) {

k=0;

write_com(0x0c); TR0=1;

lcd_pos(2,7); lcd_pos(2,0);

}

if(k!=0) {

if(k2==0)//“+1”按键操作 {

delayms(5); if(k2==0) {

while(!k2); if(k==1)

//

//

//

{ miao++; if(miao==60)

miao=0;

write_sfm(4,miao); lcd_pos(1,4); write_sfm(4,miao);

} if(k==2) { fen++; if(fen==60)

fen=0; write_sfm(2,fen); lcd_pos(1,2); write_sfm(2,fen);

} if(k==3) { shi++; if(shi==24)

shi=0; write_sfm(0,shi); lcd_pos(1,0);

write_sfm(0,shi);

//

//

} if(k==4) { ri++; if(ri==32)

ri=1;

write_sfm1(4,ri); lcd_pos(2,4); write_sfm1(4,ri);

} if(k==5) { yue++; if(yue==13)

yue=1; write_sfm1(2,yue); lcd_pos(2,2); write_sfm1(2,yue);

} if(k==6) { nian++; if(nian==50)

nian=0;

write_sfm1(0,nian);

}

}

}

lcd_pos(2,0); write_sfm1(0,nian);

//

if(k==7) { }

zhou++; if(zhou==8)

zhou=0;

write_sfm1(7,zhou); lcd_pos(2,7); write_sfm1(7,zhou);

//

if(k3==0)//“-1按键操作” {

delayms(5); if(k3==0) {

while(!k3); if(k==1) {

miao--; if(miao==-1)

miao=59;

//

//

//

write_sfm(4,miao); lcd_pos(1,4); write_sfm(4,miao);

}

if(k==2) { fen--; if(fen==-1)

fen=59;

write_sfm(2,fen); lcd_pos(1,2); write_sfm(2,fen);

} if(k==3) { shi--; if(shi==-1)

shi=23; write_sfm(0,shi); lcd_pos(1,0); write_sfm(0,shi);

} if(k==4) {

ri--;

//

//

//

if(ri==-1)

ri=31;

write_sfm1(4,ri); lcd_pos(2,4); write_sfm1(4,ri);

}

if(k==5) { yue--; if(yue==-1)

yue=12;

write_sfm1(2,yue); lcd_pos(2,2); write_sfm1(2,yue);

} if(k==6) { nian--; if(nian==-1)

nian=50; write_sfm1(0,nian); lcd_pos(2,0); write_sfm1(0,nian);

} if(k==7)

}

}

{ }

zhou--; if(zhou==-1)

zhou=7;

write_sfm1(7,zhou); lcd_pos(2,7); write_sfm1(7,zhou);

//

}

if(k==0) {

if(k2==0) {

delayms(5); if(k2==0) {

while(!k2); if(kk==3) {

miao0++; if(miao0==60)

miao0=0;

write_sfm2(6,miao0);

}

}

}

lcd_pos(3,6); write_sfm2(6,miao0);

//

if(kk==2) { } if(kk==1) { }

shi0++; if(shi0==24)

shi0=0; fen0++; if(fen0==60)

fen0=0;

write_sfm2(4,fen0); lcd_pos(3,4); write_sfm2(4,fen0);

//

write_sfm2(2,shi0); lcd_pos(3,2); write_sfm2(2,shi0);

//

if(k3==0) {

//

//

delayms(5); if(k3==0) { while(!k3); if(kk==3) { miao0--; if(miao0==-1)

miao0=59;

write_sfm2(6,miao0); lcd_pos(3,6); write_sfm2(6,miao0);

} if(kk==2) { fen0--; if(fen0==-1)

fen0=59; write_sfm2(4,fen0); lcd_pos(3,4); write_sfm2(4,fen0);

} if(kk==1) {

shi0--;

}

}

}

if(shi0==-1)

shi0=23;

write_sfm2(2,shi0); lcd_pos(3,2); write_sfm2(2,shi0);

// }

}

void init()//初始化函数(12864初始化,定时器初始化) {

PSB=1;

write_com(0x30); delayms(5); write_com(0x0c); delayms(5); write_com(0x01); delayms(5);

TH0=(65535-50000)/256; TL0=(65535-50000)%6; TMOD=0x01; ET0=1; EA=1;

}

TR0=1;

void main()//主函数 {

uchar i; delayms(10); init();

lcd_pos(0,2);//第一排显示 i=0;

while(dis1[i]!='\\0') { }

lcd_pos(1,0);//第二排显示 i=0;

while(dis2[i]!='\\0') { }

lcd_pos(2,0);//第三行显示 i=0;

while(dis3[i]!='\\0')

write_data(dis2[i]); i++;

write_data(dis1[i]); i++;

{ }

lcd_pos(3,0);//第四行显示 i=0;

while(dis4[i]!='\\0') { }

write_data(dis4[i]); i++;

write_data(dis3[i]); i++;

while(1) {

keyscan();

if(miao==0&&fen==0&&TR0==1)//整点报时判断 { }

if(miao==miao0&&fen==fen0&&shi==shi0&&TR0==1)//闹钟判断 { }

if(miao==0&&fen==0&&miao==miao0&&fen==fen0&&shi==shi0&&TR0==1)//整点报时、闹钟时冲突

warn3s(); warn(shi);

操作

}

}

{ }

warn3s();

while(1);

void timer() interrupt 1//定时器函数 {

TH0=15535/256; TL0=15535%6;

t++; //50ms计数一次 if(t==20) {

t=0; miao++; if(miao==60) {

miao=0; fen++; if(fen==60) {

fen=0; shi++; if(shi==24)

{

shi=0; zhou++; if(zhou==8) { } ri++;

if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) { }

if(yue==4||yue==6||yue==9||yue==11) {

if(ri==31) {

if(ri==32) { }

ri=1; yue++; if(yue==13) { }

yue=1; nian++;

zhou=1;

}

}

ri=1; yue++; if(yue==13) { }

yue=1; nian++;

if(yue==2) {

if((nian%4)==0) { }

if((nian%4)!=0)

if(ri==30) {

ri=1; yue++; if(yue==13) { }

yue=1; nian++;

}

}

}

}

}

}

}

{ }

write_sfm1(2,yue);

if(ri==29) { }

write_sfm1(0,nian);

ri=1; yue++; if(yue==13) { }

yue=1; nian++;

write_sfm1(7,zhou); write_sfm1(4,ri);

write_sfm(0,shi);

write_sfm(2,fen);

write_sfm(4,miao);

四、总结体会

通过这为期两个星期的课程设计,我从中认识到了自己很多方面的不足。在第一个星期的课程设计中,是通过proteus仿真来实现要求中的各种功能。由于自己课余时间没有对单片机相关的知识进行深入了解,所以在开始做设计时,无从下手,不知道该怎么布置仿真图,更不知道怎么通过写程序来实现课题要求。不过有的课题可以参考课本上的程序,例如彩灯中断,就是在课本上流水灯的基础上加入一个中断程序,不过中断程序加在何处自己还是有一点疑惑,通过翻阅课本上有关中断方面的知识后,了解了中断系统的结构及工作原理,再加入了中断程序后,程序还是有一点小问题,在请教了同学之后,找到了问题所在,修改程序以后实现了要求。而串转并,在以前的实验中做过类似的,所以整体比较顺利。利用彩灯计数一开始不太明白这个要求的意思,请教了同学才明白要求的意思。根据二进制的计算转化成彩灯的亮灭,虽然程序很短,但我心里还是有很大的成就感。在做方波的输出时,在写程序之前参考了一下同学的程序,搞懂了原理,才完成了设计。在这之后,有关于LCD的设计,在这之前,还没有接触过LCD,所以上网查了一下有关资料,了解了其结构和工作原理,对它们有了大致的了解。但在写程序时,还是遇到了很大的困难,因为自己在写程序方面并不熟练,只掌握了一些基本的函数语句,在具体的定义和结构上还是不精通,所以在写之前参考了同学的程序,搞懂了程序的原理之后,完成了仿真设计。而让我觉得最难的莫过于LCD12864和LED点阵的设计了。因为仿真软件中的12864没有字库,所以要用仿真来完成12864的设计,程序中要现实的汉字和数字就要用点阵的形式,不过幸好有取模软件的帮助,减少了额外的工作量,不过最终还是用的实物来完成的设计。在设计LED点阵时,因为对这方面知识不太了解,在网上查阅了资料,参考了网上的仿真图,无一意外的是我在写程序时,又遇到了困难,后来还是在同学的帮助下完成了设计,纵观第一个星期的设计,遭遇了太多的困难,归根结底还是自己的能力不够,大多数都是在同学的帮助下完成的,以后要多对自己的薄弱环节进行加固,多看书,多动手挺高自己的水平。在完成第一个星期的设计后,我们又抽签抽到了自己的设计,即12864显示多功能时钟,在前一个星期中,我们也做了关于12864的设计,所以对12864的结构和工作原理比较了解。而时钟实现我利用的是单片机内部的计时器,修改时间通过四个独立按键来实现,即对四个按键进行定义。整个系统是利用实习时所完成的单片机开发板来实现仿真的。所以要比仿真更方便快捷一些。通过开发板来定义每个系统的各个引脚,因为自己写程序的能力有限,再写出大概的程序框图后,剩下的程序写的时候比较困难,所以就请教了同学,最终完成了设计。在结束课程设计之后,松一口气之余还有很多无力感,自己各方面的不足在设计过程中暴露出来,以后课余的时间还是要多查缺补漏,多看书,多动手,把基础知识夯实,充分理解每个知识点的含义,才能举一反三,使自己的能力得到提高。

参考文献

[1] 曾屹 . 单片机原理与应用[M]. 湖南:中南大学出版社 2009

[2] 彭伟 . 单片机C语言程序设计实训100例[M]. 北京:北京航空航天大学出版社 [3] 郭天祥. 51单片机C语言教程[M]. 北京:电子工业出版社 [4] 姜志海. 单片机原理及应用[M]. 北京:电子工业出版社

本文来源:https://www.bwwdw.com/article/tqp3.html

Top