用定时器设计时钟并在1602液晶上显示
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit wela=P2^7;
sbit dula=P2^6;
/****分解出的独立按键****/
sbit s1=P3^0; //进入调时间状态
sbit s2=P3^1; //数值增大
sbit s3=P3^2; //数值减少
sbit s4=P3^3; //进入设置闹钟状态
sbit rd=P3^7;
uint a,shi,fen,miao,ri,yue,nian,num,i,j,q,shi1,fen1,miao1,num1;
uchar temp;
uchar code table[]="2012";
/*****显示星期*****/
uchar code table1[][4]={"Mon ","Tues","Wed ","Thur","Fri ","Sat ","Sun "}; /*****延时1ms*****/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/**********
1602初始化
**********/
void write_com(uchar com) //写命令
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) //写数据
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init_1602() //初始化
{
// lcdwr=0;
dula=0; //关断选、位选
wela=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80+0x04);
write_data(':');
write_com(0x80+0x07);
write_data(':');
write_com(0x80+0x40);
for(i=0;i<4;i++)
write_data(table[i]);
write_com(0x80+0x44);
write_data('.');
write_com(0x80+0x47);
write_data('.');
}
/************
1602显示时间
************/
void write_sfm() //显示时分秒
{
write_com(0x80+0x02);
write_data(0x30+shi/10);
write_com(0x80+0x03);
write_data(0x30+shi%10);
write_com(0x80+0x05);
write_data(0x30+fen/10);
write_com(0x80+0x06);
write_data(0x30+fen%10);
write_com(0x80+0x08);
write_data(0x30+miao/10);
write_com(0x80+0x09);
write_data(0x30+miao%10);
/*****当显示小时的数小于13,显示AM*****/ if(shi<13)
{
write_com(0x80+0x0c);
write_data('A');
write_com(0x80+0x0d);
write_data('M');
}
/*****显示PM*****/
if(shi>12)
{
write_com(0x80+0x0c);
write_data('P');
write_com(0x80+0x0d);
write_data('M');
}
/*显示月日*/
write_com(0x80+0x45);
write_data(0x30+yue/10);
write_com(0x80+0x46);
write_data(0x30+yue%10);
write_com(0x80+0x48);
write_data(0x30+ri/10);
write_com(0x80+0x49);
write_data(0x30+ri%10);
/*显示星期*/
write_com(0x80+0x4c);
write_data(table1[q][0]);
write_com(0x80+0x4d);
write_data(table1[q][1]);
write_com(0x80+0x4e);
write_data(table1[q][2]);
write_com(0x80+0x4f);
write_data(table1[q][3]);
}
void write_sfm1()
{
write_com(0x80+0x02);
write_data(0x30+shi1/10);
write_com(0x80+0x03);
write_data(0x30+shi1%10);
write_com(0x80+0x05);
write_data(0x30+fen1/10);
write_com(0x80+0x06);
write_data(0x30+fen1%10);
write_com(0x80+0x08);
write_data(0x30+miao1/10);
write_com(0x80+0x09);
write_data(0x30+miao1%10);
}
/*************
定时器计时
*************/
void init_time0()
{
TMOD=0x02; //定时器0的工作方式2,避免了软件重装初值所带来的时间误差TH0=6;
TR0=6;
EA=1;
ET0=1;
TR0=1;
}
/***************
分解独立键盘扫描
***************/
void keyscanf()
{
if(s1==0) //当按键1按下,开始进入设置时间状态,
{
delay(5);
if(s1==0)
{
num++;
if(num==1) //按下的次数决定光标的位置,即为要修改的地方
{
TR0=0; //关闭定时器(当设置下面的闹钟时不用关定时器)
write_com(0x80+0x09);
write_com(0x0f); //光标显示并闪烁
}
if(num==2)
write_com(0x80+0x08);
if(num==3)
write_com(0x80+0x06);
if(num==4)
write_com(0x80+0x05);
if(num==5)
write_com(0x80+0x03);
if(num==6)
write_com(0x80+0x02);
if(num==7)
write_com(0x80+0x49);
if(num==8)
write_com(0x80+0x48);
if(num==9)
write_com(0x80+0x46);
if(num==10)
write_com(0x80+0x45);
if(num==11)
write_com(0x80+0x4c);
if(num==12)
{
num=0; //按下第12次跳出调时间状态
TR0=1; //打开定时器
write_com(0x0c);
}
while(!s1); //等待按键释放
}
}
/*****按下s2和s3分别增大和减小数值*****/
if(num!=0) //这里不能写成“if(s1==0)”,否则当s2按下后数字不会自加{
if(s2==0)
{
delay(5);
if(s2==0)
{
switch(num)
{
case 1: miao++;
if(miao==60)
miao=0;
write_sfm();
break;
case 3: fen++;
if(fen==60)
fen=0;
write_sfm();
break;
case 5: shi++;
if(shi==24)
shi=0;
write_sfm();
break;
case 7: ri++;
q++;
ri=1;
if(q==7)
q=0;
write_sfm();
case 9: yue++;
if(yue==12)
yue=1;
write_sfm();
case 11: q++;
if(q==7)
q=0;
write_sfm();
}
}
while(!s2);
}
}
if(num!=0)
{
if(s3==0) //减小数值
{
delay(5);
if(s3==0)
{
switch(num)
{
case 1: miao--;
if(miao==0)
miao=60;
write_sfm();
break;
case 3: fen--;
if(fen==0)
fen=60;
write_sfm();
break;
case 5: shi--;
if(shi==0)
shi=24;
write_sfm();
break;
case 7: ri--;
if(ri==1)
write_sfm();
case 9: yue--;
if(yue==1)
yue=12;
write_sfm();
case 11: q--; //表示星期,q的值用于选择数组的值
if(q==0)
q=7;
write_sfm();
}
}
while(!s3);
}
}
/*闹钟功能*/
if(s4==0) //进入调闹钟功能,调闹钟功能时不用关定时器
{
delay(5);
if(s4==0)
{
temp=1;
num1++;
if(num1==1) //用于选择调的位置
{
write_com(0x80+0x09);
write_com(0x0f);
}
if(num1==2)
write_com(0x80+0x08);
if(num1==3)
write_com(0x80+0x06);
if(num1==4)
write_com(0x80+0x05);
if(num1==5)
write_com(0x80+0x03);
if(num1==6)
write_com(0x80+0x02);
if(num1==7)
{
num1=0;
temp=0;
write_com(0x0c);
}
}
while(!s4);
}
if(num1!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
switch(num1)
{
case 1: miao1++;
if(miao1==60)
miao1=0;
write_sfm1();
break;
case 3: fen1++;
if(fen1==60)
fen1=0;
write_sfm1();
break;
case 5: shi1++;
if(shi1==24)
shi1=0;
write_sfm1();
break;
}
}
while(!s2);
}
}
if(num1!=0)
{
if(s3==0)
{
delay(5);
if(s3==0)
{
switch(num1)
{
case 1: miao1--;
if(miao1==0)
miao1=60;
write_sfm1();
break;
case 3: fen1--;
if(fen1==0)
fen1=60;
write_sfm1();
break;
case 5: shi1--;
if(shi1==0)
shi1=24;
write_sfm1();
break;
}
}
while(!s2);
}
}
}
/*******
主函数
*******/
void main()
{
rd=0;
init_1602();
init_time0();
while(1)
{
keyscanf();
if(temp==0) //temp为标志,为0时显示调时间的状态,为1时显示调闹钟状态write_sfm();
else
write_sfm1();
if(shi==shi1&&fen==fen1&&miao==miao1) //当设置的闹钟时间和当前显示的时间吻合,led做出反应
{
for(i=0;i<10;i++)
{
for(j=0;j<50;j++)
{
P1=0xfd;
delay(5);
P1=0xff;
}
}
write_sfm();
}
}
}
/***********
中断函数
***********/
void t0() interrupt 1
{
a++;
if(a==4000) //当a=4000,1秒
{
a=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
ri++;
q++;
if(q==7)
q=0;
if(ri==30)
{
ri=1;
yue++;
if(yue==12)
yue=1;
}
}
}
}
} }。