搜索
您的当前位置:首页正文

基于51单片机的LCD简单电子钟的设计

2020-02-22 来源:星星旅游
- . -

. 编号:

设计实验报告

题:电子钟 业:自动化 黄紫扬 号:1200810222

. -可修编-

单片机原理及应用课专学生姓名:学 - . -

2015 年 5 月 27 日

目 录

0 前言…………………………………………………………………2

1 总体方案设计………………………………………………………3

2硬件电路设计………………………………………………………3

3软件设计……………………………………………………………5

4调试分析及说明……………………………………………………7

5结论…………………………………………………………………8

参考文献……………………………………………………………错误!未定义书签。

课设体会……………………………………………………………错误!未定义书签。

. . -可修编-

- . -

附录1 电路原理………………………………………………………8

附录2 程序清单……………………………………………………8

摘要:传统的数字电子时钟采用了较多的分立元器件,不仅占用了很大的空间而且利用率也比很低,随着系统设计复杂度的不断提高,用传统时钟系统设计方法很难满足设计需求。

单片机是集CPU、RAM、ROM、定时器/计数器和多种接口于一体的微控制器。它体积小、本钱低、功能强,广泛应用于智能产品和工业自动化上。而51系列的单片机是各单片机中最为典型和最有代表性的一种。,本次设计提出了系统总体设计方案,并设计了各局部硬件模块和软件流程,在用C语言设计了具体软件程序后,将各个模块完全编译通过过后,结果证明了该设计系统的可行性。该设计给出了以AT89C2051为核心,利用单片机的运算和控制功能,并采用系统化LED显示模块实时显示数字的设计方案,适当地解决了实际生产和日常生活中对计时高准确度的要求,因此该设计在现代社会中具有广泛的应用性。 关键字:AT89C2051,C语言程序,电子钟。

0 前言

利用51单片机开发电子时钟,实现时间显示、调整功能。具体要求如下: (1) (2)

根据给定题目设计的Proteus仿真原理图,并简单阐述设计原理; 根据给定题目设计有关的51汇编语言〔或C语言〕源程序,及主要

的流程框图;

. . -可修编-

- . -

(3) (4)

在Proteus仿真界面下运行程序实现给定的功能;

下载到ZKSYS单片机实验板上验证有关程序实现给定的功能。

1 总体方案设计

该电子时钟由89C51,按键,1602 LCD液晶屏等构成,采用晶振电路作为驱动电路,利用单片机部定时计数器0通过软件扩展产生的一秒定时,到达时分秒的计时,六十秒为一分钟,六十分钟为一小时,满二十四小时为一天。时钟的年月日时分秒的切换是由一个按键控制,而另外两个个按键控制加减调节。

图1 系统构造框图

该电子时钟由STC89C51,按键,1602 LCD液晶屏等构成,采用晶振电路作为驱动电路,晶振电路的晶振频率为12MHZ,使用的定时器/计数器工作方式1,通过软件扩展产生的一秒定时,到达时分秒的计时,60秒为一分钟,60分钟为一小时,24小时为一天,又重00:00:00开场计时

2硬件电路设计

(1)时钟电路设计

单片机利用外部12MHZ晶振构成振荡电路作为时钟源,时钟电路的原理如下列图。

. . -可修编-

- . -

图2 时钟电路图

(2)独立按键输入电路

按键处理设置为:当有没键按下时,时钟正常运行;当按K1时分别切换到年月日时分秒;按K2为加。按K3为减。电路图如下列图

图3 独立按键电路

(3)单片机系统

AT89C51是一种带4K字节闪烁可编程可擦除只读存储器〔FPEROM—Falsh Programmable and Erasable Read Only Memory〕的低电压,高性能CMOS8位微处理器,俗称单片机。外形及引脚排列如下列图

. . -可修编-

- . -

图4 单片机系统图

(4)LCD液晶显示

LCD1602采用标准的16脚接口,第1脚:VSS为电源地;第2脚:VDD接5V电源正极;第3脚:V0为液晶显示器比照度调整端,接正电源时比照度最弱,接地电源时比照度最高;第4脚:RS为存放器选择,高电平1时选择数据存放器、低电平0时选择指令存放器;第5脚:RW为读写信号线,高电平(1)时进展读操作,低电平(0)时进展写操作;第6脚:E(或EN)端为使能(enable)端。第7~14脚:D0~D7为8位双向数据端;第15~16脚:空脚或背灯电源。电路如下列图

图5LCD液晶显示图

3软件设计

本系统的软件系统主要可分为主程序、定时计数中断程序、时间调整程序、延时程序四大模块。系统的流程图如下列图

开场

. . -可修编-

- . -

是 否

完毕 显示时间 读取时间 按键是否按下? 调整时间 液晶初始化 时间初始化 . . -可修编-

- . -

设计思路:

本系统主要可分为主程序、定时计数中断程序、时间调整程序、延时程序和LCD液晶驱动程序。定时中断程序是利用单片机部定时器0实现1秒的定时,然后利用软件延时实现分小时,时间调整程序是利用单片机的部存贮器,把调整好的时间写到显示时间的存贮单元,然后启动定时器开场计时并显示,延时程序是利用软件实现延时到达去抖的目的。液晶启动程序是为了把单片机的数据送到显示器的同时让显示器的第6脚使能断的电平实现由1到0的跳变,使显示器执行显示的命令。主程序就是利用这些子程序中断程序实现显示、定时等功能。

4调试分析及说明

(1) 时钟正常运行调试仿真图

图6 正常运行仿真图

(2) 时间调整仿真

. . -可修编-

- . -

图10 对时分秒的调整

5 结论

本次电子时钟的设计根本完成:当没有键按下时,时钟正常运行;时钟的年月日时分秒的切换是由一个按键控制,而另外两个个按键控制加减调节

附录1 电路原理

附录2 程序清单

#include

#define uchar unsigned char #define uint unsigned int

uchar code table[]=\" 2015-05-27 WED \"; uchar code table1[]=\" 12:30:55\"; uchar code table2[]=\" 1200810222 \";

. . -可修编-

- . - uchar code table3[]=\"Made by HUANG\";

uchar code table4[]=\"MONTUEWEDTHUFRISATSUN\"; uchar count,s1num; char miao,fen,shi,ri,yue; uint nian;

sbit lcd_rs = P2^0; sbit lcd_rw = P2^1; sbit lcd_en = P2^2; sbit s1=P1^0; sbit s2=P1^1; sbit s3=P1^2;

sbit Output_squ=P3^6;

void delay(uint z)//延时子函数 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); }

void write_(uchar )//写命令函数 { lcd_rs = 0; P0= ; delay(5); lcd_en=1; delay(5); lcd_en=0; }

void write_date(uchar date)//写数据函数 { lcd_rs = 1; P0= date; delay(5); lcd_en=1; delay(5); lcd_en=0; }

void init()//初始化函数 { int num; shi=12; fen=30; miao=55;

ri=27;

. . -可修编-

- . - yue=5; nian=2015; lcd_en=0; lcd_rw=0; write_(0x38);//显示设置模式 write_(0x0c);//00001100开显示,不显示光标,光标不闪烁 write_(0x06);//00000110地址指针加一,整屏不移动 write_(0x01);//清屏 write_(0x80); for(num=0;num<16;num++)//显示数字1200810222 { write_date(table2[num]); delay(300); } write_(0x80+0x40); for(num=0;num<16;num++)//显示made by HUANG { write_date(table3[num]); delay(300); } delay(5000); write_(0x01); write_(0x80); for(num=0;num<16;num++)//显示日期 { write_date(table[num]); delay(5); } write_(0x80+0x40); for(num=0;num<12;num++)//显示时间 { write_date(table1[num]); delay(5); } TMOD=0x51;//启动定时器中断 TH0=0X3C; //50ms TL0=0XB0; TH1=0X00; TL1=0X00; EA=1; ET0=1; TR0=1;//翻开定时器0 TR1=1; //翻开定时器0

}

. . -可修编-

- . - {

void write_sfm(uchar add,uchar date)//写时分秒函数 { uchar shi,ge; shi=date/10; ge=date%10; write_(0x80+0x40+add); write_date(0x30+shi); write_date(0x30+ge); }

void write_nyr(uint add,uint date)//写年月日函数,此处假设用uchar围只有0-255 { //不够,改用uint(0-65535) uint qian,bai,shi,ge; qian=date/1000; bai=date%1000/100; shi=date%100/10; ge=date%10; write_(0x80+add); write_date(0x30+qian); write_date(0x30+bai); write_date(0x30+shi); write_date(0x30+ge); }

void write_yr(uchar add,uchar date)//写月日函数 { uchar shi,ge; shi=date/10; ge=date%10; write_(0x80+add); write_date(0x30+shi); write_date(0x30+ge); }

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

int m,n; if(s1==0) { delay(5); if(s1==0)//按键1光标移位扫描 { s1num++; if(s1num==1) { while(!s1);//等待按键松手 write_(0x80+0x40+10); TR0=0;//关闭定时器

. . -可修编-

- . - write_(0x0f); //开显示,显示光标,光标闪烁 } if(s1num==2) { while(!s1); write_(0x80+0x40+7); } if(s1num==3) { while(!s1); write_(0x80+0x40+4); } if(s1num==4) { while(!s1); write_(0x80+3); } if(s1num==5) { while(!s1); write_(0x80+6); } if(s1num==6) { while(!s1); write_(0x80+9); } if(s1num==7) { while(!s1) write_(0x80+13); } if(s1num==8) { while(!s1); s1num=0; write_(0x0c); TR0=1;//开定时器 } } }

if(s1num!=0) {

if(s2==0)//按键2加功能

. . -可修编-

- . - {

. delay(5); if(s2==0) { while(!s2); if(s1num==1)//秒加 { miao++; if(miao==60) { miao=0; } write_sfm(10,miao); write_(0x80+0x40+10); } if(s1num==2)//分加 { fen++; if(fen==60) { fen=0; } write_sfm(7,fen); write_(0x80+0x40+7); } if(s1num==3)//时加 { shi++; if(shi==24) { shi=0; } write_sfm(4,shi); write_(0x80+0x40+4); } if(s1num==4)//年加 { nian++; if(nian==10000) { nian=2000; } write_nyr(1,nian); write_(0x80+3);

. -可修编-

- . -

} if(s1num==5)//月份加 { yue++; if(yue==13) { yue=1; } write_yr(6,yue); write_(0x80+6); } if(s1num==6)//日期加 { ri++;

if(ri==29&&yue==2&&!((nian%4==0&&nian%100!=0)||nian%400==0)) { ri=1;//平年 }

if(ri==30&&yue==2&&((nian%4==0&&nian%100!=0||nian%400==0))) { ri=1;//闰年 } if(ri==31&&(yue==4||yue==6||yue==9||yue==11)) { ri=1; } if(ri==32) { ri=1; } write_yr(9,ri); write_(0x80+9); } if(s1num==7)//星期加 { m=m+3; if(m==21) m=0; write_(0x80+12); for(n=m;n. . -可修编-

- . - delay(5); } write_(0x80+13); } } }

if(s3==0)//按键3减功能 {

. delay(5); if(s3==0) { while(!s3); if(s1num==1)//秒减 { miao--; if(miao==-1) { miao=59; } write_sfm(10,miao); write_(0x80+0x40+10); } if(s1num==2)//分减 { fen--; if(fen==-1) fen=59; write_sfm(7,fen); write_(0x80+0x40+7); } if(s1num==3)//时减 { shi--; if(shi==-1) shi=23; write_sfm(4,shi); write_(0x80+0x40+4); } if(s1num==4)//年减 { nian--; if(nian==1999) nian=2000; write_nyr(1,nian);

. -可修编-

- . -

. write_(0x80+3); }

if(s1num==5)//月份减 { yue--; if(yue==0) yue=12; write_yr(6,yue); write_(0x80+6); }

if(s1num==6)//日减 { ri--; if(ri==0) { if(yue==2&&!((nian%4==0&&nian%100!=0)||nian%400==0)) { ri=28;//平年 } if(yue==2&&((nian%4==0&&nian%100!=0||nian%400==0))) { ri=29;//闰年 } if(yue==4||yue==6||yue==9||yue==11) { ri=30; } if(yue==1||yue==3||yue==5||yue==7||yue==9||yue==11) ri=31; } write_yr(9,ri); write_(0x80+9); }

if(s1num==7)//星期减 { m=m-3; if(m==0) m=21; write_(0x80+12); for(n=m;n-3}

. -可修编-

- . -

write_(0x80+13); } } } } }

void main() { int i,j; init(); while(1) { keyscan(); if(TL1==8) { TH1=0X00; TL1=0X00; miao++; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; ri++; j=j+3; if(j==21) j=0; write_(0x80+12); for(i=j;iif(ri==29&&yue==2&&!((nian%4==0&&nian%100!=0)||nian%400==0)) { ri=1;yue++;//平年 }

. . -可修编-

- . - if(ri==30&&yue==2&&((nian%4==0&&nian%100!=0||nian%400==0))) { ri=1;yue++;//闰年 } if(ri==31&&(yue==4||yue==6||yue==9||yue==11)) { ri=1;yue++; } if(ri==32) { ri=1;yue++; } if(yue==13) { yue=1; nian++; if(nian==10000) { nian=2000; } write_nyr(1,nian); } write_yr(6,yue); } write_yr(9,ri); write_sfm(4,shi); } write_sfm(7,fen); } write_sfm(10,miao); } } }

void timer() interrupt 1 { TH0=0X3C; TL0=0XB0; Output_squ=~Output_squ; }

. . -可修编-

因篇幅问题不能全部显示,请点此查看更多更全内容

Top