#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs=P2^2;
sbit lcswr=P2^1;
sbit lcden=P2^0;
sbit s1=P3^3;
sbit s2=P3^2;
sbit s3=P3^1;
uchar count,s1num=0;
char miao,fen,shi,day,month,week;
uint year; //???????????
uchar code table[]=" 2018-02-28 WED";
uchar code table1[]=" 23:59:55";
void delay (uint z) //uint z 传递的是延时毫秒的数,比如延时10毫秒则为10
{
uchar x,y; //这里其实应该uint x,y;
for (x=z;x>0;x--) //这个循环是毫秒数
for (y=110;y>0;y--); //这个循环是1毫秒循环次数
}
void write_command(uchar command) //往液晶屏写命令或数据
{
lcdrs=0; //写入指令
lcswr=0;
P0=command;
delay(5);
lcden=1; //使能
delay(5);
lcden=0;
}
void write_date(uchar date)
{
lcdrs=1; //写入数据。
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init() //写入初始日期,时间(两个数组)
{
uchar num;
lcden=0;
write_command(0x38); //8位数据接口,16x2行显示,5x10点阵字符
write_command(0x0c); //显示开,光标关,闪烁关
write_command(0x06); //当读或写一个字符后,地址指针加一且光标加
write_command(0x01); //清屏
write_command(0x80); //0x80因为写入显示地址时要求最高位D7恒定为高电平1
for(num=0; num<16; num++)
{
write_date(table[num]);//写入日期
delay(5);
}
write_command(0x80+0x40); //数据第二行开头
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
shi=23;
fen=59;
miao=55;
year=2018;
month=2;
day=28;
week=3;
TMOD=0x01;//选择T0计数器工作在方式1,65535个脉冲
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void write_sfm(uchar addr,uchar data1) //写时分秒?
{
uchar shi,ge;
shi=data1/10; //shiwei
ge=data1%10; //gewei
write_command(0x80+0x40+addr);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_ymd(uchar addr,uchar date1)//写年月日函数
{
uchar shi,ge;
shi=date1/10;//分解一个2位数的十位和个位
ge=date1%10;
write_command(0x80+addr);//设置显示位置
write_date(0x30+shi);//送去液晶显示十位
write_date(0x30+ge); //送去液晶显示个位
}
void display_date(uint nian,char yue,char ri)//日期显示
{
uint y1,y2,y3,y4;
char a,b,c,d;
y1=nian/1000; //千位
y2=nian%1000/100; //百位
y3=nian%1000%100/10; //十位
y4=nian%1000%100%10; //个位
a=yue/10;
b=yue%10;
c=ri/10;
d=ri%10;
write_command(0x80+2);
write_date(0x30+y1);
write_command(0x80+3);
write_date(0x30+y2);
write_command(0x80+4);
write_date(0x30+y3);
write_command(0x80+5);
write_date(0x30+y4);
write_command(0x80+7);
write_date(0x30+a);
write_command(0x80+8);
write_date(0x30+b);
write_command(0x80+10);
write_date(0x30+c);
write_command(0x80+11);
write_date(0x30+d);
}
void write_week(char week) //写液晶星期显示函数
{
write_command(0x80+13);
switch(week)
{
case 1: write_date('M');delay(5);
write_date('O');delay(5);
write_date('N');
break;
case 2: write_date('T');delay(5);
write_date('U');delay(5);
write_date('E');
break;
case 3: write_date('W');delay(5);
write_date('E');delay(5);
write_date('D');
break;
case 4: write_date('T');delay(5);
write_date('H');delay(5);
write_date('U');
break;
case 5: write_date('F');delay(5);
write_date('R');delay(5);
write_date('I');
break;
case 6: write_date('S');delay(5);
write_date('A');delay(5);
write_date('T');
break;
case 7: write_date('S');delay(5);
write_date('U');delay(5);
write_date('N');
break;
}
}
void keyscan()
{
delay(5);
if(s1==0) //调模式
{
s1num++;
while(!s1); //如果按钮没弹起来,则死循环
if(s1num==1) //s1num标识符
{
TR0=0; //调时间的时候,T0停止工作
write_command(0x80+0x40+10);
write_command(0x0f); //闪烁开,光标开
}
if(s1num==2)
{
write_command(0x80+0x40+7);
}
if(s1num==3)
{
write_command(0x80+0x40+4);
}
if(s1num==4)//第三次按下光标闪烁定位到日位置
{
write_command(0x80+10);
}
if(s1num==5)//第二次按下光标闪烁定位到月位置
{
write_command(0x80+7);
}
if(s1num==6)//
{
write_command(0x80+2);//光标定位到年位置
write_command(0x0f); //光标开始闪烁
}
if(s1num==7)//第四次按下光标闪烁定位到星期位置
{
write_command(0x80+13);
}
if(s1num==8)
{
s1num=0;
write_command(0x0c); //和初始化函数里的一毛一样,显示开,光标关,闪烁关
TR0=1; //开定时
}
}
if(s1num!=0) //判断是否进入调整模式
{
if(s2==0)
{
while(!s2);
if(s1num==1) //判断加法对哪位
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_command(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_command(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_command(0x80+0x40+4);
}
if(s1num==4)//若功能键第三次按下
{
day++;//则调整日加1
if(year%4==0&&month==2)
{
if(day==30)//若满29后将置一
day=1;
}
if(year%4!=0&&month==2)
{
if(day==29)//若满28后将置一
day=1;
}
if(month!=2&&month!=4&&month!=6&&month!=9&&month!=11)
{
if(day==32)//若满31后将置一
day=1;
}
if(month==4||month==6||month==9||month==11)
{
if(day==31)//若满30后将置一
day=1;
}
write_ymd(10,day);//每调节一次送液晶显示一下
write_command(0x80+10);//显示位置重新回到调节处
}
if(s1num==5)//若功能键第二次按下
{
month++;//则调整月加1
if(month==13)//若满12后将置一
month=1;
write_ymd(7,month);//每调节一次送液晶显示一下
write_command(0x80+7);//显示位置重新回到调节处
}
if(s1num==6)//若功能键第一次按下
{
year++; //则调整年加1
if(year<0)//若满100后将清零
year=99;
write_ymd(4,year);//每调节一次送液晶显示一下
write_command(0x80+4);//显示位置重新回到调节处
}
if(s1num==7)//若功能键第四次按下
{
week++;//则调整星期加1
if(week==8)//若满8后将置一
week=1;
write_week(week);//每调节一次送液晶显示一下
write_command(0x80+13);//显示位置重新回到调节处
}
}
if(s3==0)
{
while(!s3);
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_command(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)