C51单片机LCD电子时钟课程设计Word格式文档下载.docx
《C51单片机LCD电子时钟课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《C51单片机LCD电子时钟课程设计Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
闹钟部分主要由蜂鸣器,三极管,电阻组成。
其电路图如图所示:
闹钟电路
当单片机得P1^5接口输出为高电平时,蜂鸣器响,当输出为低电平时,蜂鸣器停止。
2、5显示电路设计
2、5、1LCD1602简介
LCD1602液晶也叫1602字符型液晶,它就是一种专门用来显示字母、数字、符号等得点阵型液晶模块,它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。
每位之间有一个点距得间隔,每行之间也有也有间隔,起到了字符间距与行间距得作用,正因为如此,所以她不能显示图形(用自定义CGRAM,显示效果也不好)。
1602LCD就是指显示得内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符与数字)。
目前市面上字符液晶绝大多数就是基于HD44780液晶芯片得,控制原理就是完全相同得,因此基于HD44780写得控制程序可以很方便地应用于市面上大部分得字符型液晶。
(1)LCD1602得主要技术参数
显示容量:
16×
2个字符;
芯片工作电压:
4、5—5、5V;
工作电流:
2、0mA(5、0V);
模块最佳工作电压:
5、0V;
字符尺寸:
2、95×
4、35(W×
H)mm。
(2)LCD1602引脚功能说明
1602LCD采用标准得14脚(无背光)或16脚(带背光)接口,各引脚接口说明如下:
第1脚:
VSS为地电源;
第2脚:
VDD接5V正电源;
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K得电位器调整对比度;
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器;
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS与R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据;
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令;
第7~14脚:
D0~D7,为8位双向数据线;
第15脚:
背光源正极;
第16脚:
背光源负极。
1602液晶模块得读写操作,屏幕与光标得操作都就是通过指令编程来实现得。
本显示电路将单片机得P0口作为液晶得数据口,由于P0口没有上拉电阻,所以需额外加一个排阻作为上拉电阻,利用P1口作为其读写控制端,具体电路如图。
显示电路
三、软件设计
软件设计就是本次设计中不可缺少得环节,就是本次设计能够完成得最重要得环节之一。
在完成了硬件电路得设计之后,依据系统设计要求与硬件电路开始系统软件部分得设计。
本系统软件设计包括:
主程序、系统初始化子程序、延时中断子程序、时间设置子程序。
首先进行模块设计,最后进行各模块得整合以完成整个软件系统。
3、1程序主流程图
主流程图
3、2初始化流程图
系统初始化模块得主要功能就是完成系统得初始化以及设定系统得工作状态,初始化部分包括以下方面得内容:
(1)单片机定时器0初始化以及各种I/O口定义;
(2)1602液晶初始化清屏及设定工作方式;
(3)系统进入正常工作状态。
初始化流程图
3、3延时中断子程序
延时中断子程序
3、4时间设置子程序
这里仅画出了秒设置流程图,其她时间及日期设置类似。
秒设置流程图
四、系统测试
4、1测试方法
系统单片机代码采用C语言编写,proteus进行原理图得设计,keil软件进行代码得编译,通过keil与proteus软件得充分利用,将编译好得执行代码加载到原理图中得单片机里面进行原理图仿真,通过仿真对系统得代码程序与原理图进行测试,瞧就是否达到系统得设计要求。
4、2测试结果
(1)通过按调时健、加减键得调节,我们可以设定出具体得时间1:
00:
00,观察LCD液晶屏如图所示精确显示出我们所设定得时间时间。
(2)通过按键调节调闹钟健,我们可以五秒听到清晰得蜂鸣声。
4、3 结果分析
通过对系统原理图与程序得仿真与调试基本实现了系统得功能要求。
可以通过按键(mode)来设定具体时间、闹钟。
LCD液晶显示屏能够准确而且清晰地显示出时间。
五、源程序
ﻩﻩ#include<
reg51、h>
#include<
intrins、h>
#defineucharunsignedchar
#defineuintunsigned int
sbit beep=P1^5;
//定义蜂鸣器得io口
sbitrw=P2^1;
//定义读写得io口
sbit rs=P2^0;
ﻩﻩﻩ//定义接收与发送指令得io口
sbitlcden=P2^2;
ﻩ//定义使能端得io口
sbit k1=P3^0;
//定义调时键得io口
sbitk2=P3^1;
//定义加数键得io口
sbitk3=P3^2;
//定义减数键得io口
sbitk4=P3^3;
//定义调闹钟键得io口
ucharcount,count1,num,num1,num2;
charh,min,sec,h1,min1,sec1;
uchar table[]={"
23:
59:
57"
};
uchartable1[]={"
00:
00:
00"
};
voiddelay(uint ms)ﻩﻩ//延时程序
{
inti;
while(ms--)
{
for(i= 0;
i<
250;
i++)
{
ﻩ_nop_();
_nop_();
ﻩ _nop_();
_nop_();
}
}
}
delay1(ucharz) //延时程序
{
uintx,y;
for(x=z;
x>
0;
x--)
for(y=110;
y>0;
y--);
return0;
}
bitwrite_busy() //判断就是否为繁忙状态
{
ﻩ bitresult;
rs = 0;
ﻩrw=1;
ﻩ lcden =1;
_nop_();
_nop_();
_nop_();
_nop_();
result=(bit)(P0&
0x80);
ﻩ lcden= 0;
ﻩ returnresult;
}
voidwrite_(uchar) //写指令函数
{
ﻩ while(write_busy());
ﻩrs=0;
ﻩrw=0;
lcden=0;
P0=;
_nop_();
ﻩ _nop_();
ﻩ_nop_();
_nop_();
ﻩlcden=1;
ﻩ _nop_();
ﻩ _nop_();
_nop_();
ﻩlcden=0;
voidwrite_data(uchardate) //写数据函数
{
while(write_busy());
rs=1;
ﻩrw=0;
ﻩlcden=0;
ﻩP0=date;
ﻩ_nop_();
_nop_();
lcden=1;
ﻩ_nop_();
_nop_();
ﻩ _nop_();
ﻩ _nop_();
ﻩlcden=0;
voidwrite_pos(ucharpos) //设定地址
{ﻩﻩﻩﻩﻩ
ﻩwrite_(pos|0x80);
//数据指针=80+地址变量
voidwrite_sfm(ucharadd,uchardate) //设定时分秒及其显示与地址
uintshi,ge;
shi=date/10;
ge=date%10;
ﻩwrite_(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);
void write_sfm1(ucharadd,uchardate)//设置闹钟时分秒及其显示与地址
ﻩuintshi,ge;
shi=date/10;
ﻩge=date%10;
write_(0x80+add);
write_data(0x30+shi);
write_data(0x30+ge);
voidkeyscan() //键盘扫描
{
if(k1==0)
{
delay1(5);
if(k1==0)
{
while(!
k1);
num++;
if(num==1)
{
ﻩﻩTR0=0;
write_(0x80+0x40+11);
write_(0x0f);
}
if(num==2)
{
write_(0x80+0x40+8);
ﻩ}
if(num==3)
ﻩ{
ﻩwrite_(0x80+0x40+5);
}
if(num==4)
ﻩ{
ﻩﻩnum=0;
ﻩwrite_(0x0c);
TR0=1;
ﻩ}
}
if(num!
=0)
{
if(k2==0)
{
delay1(5);
if(k2==0)
ﻩ{
ﻩwhile(!
k2)
if(num==1)
ﻩ{
sec++;
ﻩﻩif(sec==60)ﻩ
ﻩﻩsec=0;
ﻩﻩ write_sfm(10,sec);
ﻩﻩ write_(0x80+0x40+0x10);
ﻩ
ﻩ}
if(num==2)
ﻩﻩﻩ{
ﻩﻩﻩﻩmin++;
ﻩﻩﻩif(min==60)
ﻩﻩﻩﻩmin=0;
write_sfm(7,min);
ﻩﻩﻩwrite_(0x80+0x40+8);
ﻩﻩﻩ}
ﻩ if(num==3)
ﻩﻩ{
ﻩﻩﻩh++;
ﻩﻩﻩif(h==24)
ﻩﻩh=0;
ﻩﻩwrite_sfm(4,h);
ﻩﻩwrite_(0x80+0x40+5);
ﻩﻩ}
}
}
if(k3==0)
delay1(5);
if(k3==0)
ﻩ while(!
k3);
ﻩﻩif(num==1)
ﻩﻩ sec--;
if(sec==-1)
sec=59;
write_sfm(10,sec);
ﻩﻩ write_(0x80+0x40+0x10);
ﻩ}
ﻩif(num==2)
ﻩﻩ{
ﻩmin--;
ﻩﻩ if(min==-1)
ﻩﻩmin=59;
ﻩwrite_sfm(7,min);
ﻩﻩﻩ write_(0x80+0x40+8);
}
ﻩif(num==3)
ﻩ{
ﻩﻩ h--;
ﻩﻩﻩif(h==-1)
ﻩﻩﻩh=23;
ﻩwrite_sfm(4,h);
ﻩ write_(0x80+0x40+5);
ﻩﻩ}
ﻩ}
ﻩ}ﻩ
if(k4==0)
{
delay1(5);
ﻩ if(k4==0)
ﻩ while(!
k4);
num1++;
ﻩﻩif(num1==1)
write_sfm1(10,sec1);
ﻩwrite_sfm1(7,min1);
ﻩwrite_sfm1(4,h1);
ﻩ}
ﻩif(num1==2)
{
ﻩﻩwrite_(0x80+11);
ﻩ write_(0x0f);
ﻩ }
ﻩif(num1==3)
ﻩwrite_(0x80+8);
ﻩﻩ}
if(num1==4)
ﻩ{
ﻩﻩwrite_(0x80+5);
}
if(num1==5)
{
ﻩ num1=0;
write_(0x0c);
ﻩ write_sfm(10,sec);
ﻩﻩ write_sfm(7,min);
ﻩﻩ write_sfm(4,h);
}
ﻩ}
}
ﻩ if(num1!
{
ﻩ if(k2==0)
delay1(5);
if(k2==0)
ﻩ{
ﻩﻩ while(!
k2)
if(num1==2)
ﻩﻩﻩ{
ﻩ sec1++;
ﻩﻩﻩ if(sec1==60)ﻩ
ﻩﻩﻩ sec1=0;
ﻩ write_sfm1(10,sec1);
ﻩ ﻩﻩwrite_(0x80+0x10);
}
ﻩ if(num1==3)
ﻩﻩﻩﻩ{
ﻩﻩﻩmin1++;
ﻩﻩﻩﻩif(min1==60)
ﻩﻩﻩﻩmin1=0;
ﻩﻩwrite_sfm1(7,min1);
ﻩﻩﻩﻩwrite_(0x80+8);
ﻩ}
ﻩﻩif(num1==4)
ﻩﻩ{
ﻩﻩﻩﻩﻩh1++;
ﻩﻩﻩﻩif(h1==24)
ﻩﻩﻩﻩh1=0;
ﻩﻩwrite_sfm1(4,h1);
ﻩﻩﻩﻩﻩwrite_(0x80+5);
ﻩﻩﻩ}
ﻩﻩ }
ﻩﻩ}
ﻩ if(k3==0)
delay1(5);
if(k3==0)
ﻩ {
ﻩ while(!
k3);
ﻩif(num1==2)
ﻩ {
ﻩsec1--;
ﻩ if(sec1==-1)
ﻩ sec1=59;
ﻩ write_sfm1(10,sec1);
ﻩﻩ write_(0x80+0x10);
ﻩﻩ}
ﻩﻩif(num1==3)
ﻩ{
ﻩmin1--;
ﻩ if(min1==-1)
ﻩﻩmin=59;
ﻩ write_sfm1(7,min1);
ﻩﻩwrite_(0x80+8);
ﻩ }
ﻩif(num1==4)
ﻩﻩh1--;
ﻩif(h1==-1)
ﻩﻩﻩh1=23;
ﻩﻩﻩ write_sfm1(4,h1);
ﻩﻩﻩ write_(0x80+5);
ﻩﻩﻩ}
ﻩﻩ}ﻩ
ﻩ}
void init() //程序初始化函数
uinti;
ﻩ h=23;
min=59;
sec=57;
ﻩh1=00;
min1=00;
sec1=00;
num=0;
ﻩ lcden=0;
write_(0x38);
delay
(1);
ﻩ write_(0x0c);
//显示开,关光标
delay(1);
write_(0x06);
//移动光标
delay
(1);
ﻩwrite_(0x01);
//清除LCD得显示内容
ﻩ delay
(1);
ﻩ
i=0;
while(table1[i]!
='
\0') //显示闹钟(静态)
ﻩ write_data(table1[i]);
ﻩ i++;
ﻩ }
i=0;
ﻩwrite_pos(0x40);
ﻩwhile(table[i]!
\0'
) //显示时间(静态)
ﻩ {
write_data(table[i]);
ﻩ i++;
}
ﻩTMOD=0x01;
//定时器
TH0=(65536-50000)/256;
ﻩTL0=(65536-50000)%256;
EA=1;
//开启定时器
ﻩET0=1;
TR0=1;
voidmain()
init();
while
(1)
{
keyscan();
ﻩﻩif(min==min1&&
h==h1) ﻩ//闹钟启动条件
while(sec<
=5) //响五秒
ﻩﻩ{
ﻩ ﻩbeep=1;
ﻩﻩdelay1
(2);
ﻩﻩﻩbeep=0;
ﻩ }
ﻩﻩ}
ﻩelse
beep=0;
}
voidtimer0()interrupt1 //定时器时间设定
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
ﻩif(count==20)
{
count=0;
sec++;
if(sec==60)
{
sec=0;
ﻩ min++;
ﻩ if(min==60)
ﻩ{
min=0;
ﻩﻩh++;
if(h==24)
{
ﻩﻩh=0;
ﻩﻩ
ﻩﻩﻩ }
ﻩ write_sfm(4,h);
ﻩwrite_sfm(7,min);
ﻩ write_sfm(10,sec);
ﻩ }}