一款AT89C51单片机1602液晶显示时钟程序,功能主要有:温度、时间、日期、星期显示以及调节。有多级菜单显示。第一级菜单调节时间、日期。第二级菜单显示自定义信息。
#includereg52.h
#includeintrins.h
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P2^1;
sbit light=P2^7;
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
sbit k5=P1^4;
sbit LED1=P1^3;
sbit LED2=P1^4;
sbit DS1302_CE=P3^5;
sbit DS1302_IO=P3^6;
sbit DS1302_SCLK=P3^7;
sbit LCD1602_RS=P2^4;
sbit LCD1602_RW=P2^5;
sbit LCD1602_EN=P2^6;
extern uchar wendu[4];
extern void get_wendu();
extern void LCD1602_init();
extern void LCD1602_wcmd(uchar cmd);
extern void LCD1602_wdat(uchar dat);
extern void LCD1602_pos(uchar x,bit y); //定义显示位置,x为列,y为行,0上1下
extern void LCD1602_dischar(uchar x,bit y,uchar dat); //在指定位置显示字符
extern void LCD1602_prints(uchar x,bit y,uchar *p); //显示字符串
extern uchar dt[7];
extern void set_time();
extern void get_time();
extern void DS1302_init();
uchar dt[7];
void DS1302_write_byte(uchar dat)
{
char i;
for(i=0;i
{
DS1302_SCLK = 0;
_nop_();
_nop_();
dat >>= 1;
DS1302_IO = CY;
DS1302_SCLK=1;
_nop_();
_nop_();
}
}
uchar DS1302_read_byte()
{
uchar i;
uchar dat = 0;
for(i=0;i
{
DS1302_SCLK = 0;
_nop_();
_nop_();
dat >>= 1;
if(DS1302_IO) dat |= 0x80;
DS1302_SCLK =1;
_nop_();
_nop_();
}
return dat;
}
void DS1302_write(uchar address,uchar dat)
{
DS1302_CE=0;
_nop_();
_nop_();
DS1302_SCLK=0;
_nop_();
_nop_();
DS1302_CE=1;
_nop_();
_nop_();
DS1302_write_byte(address);
DS1302_write_byte(dat);
DS1302_SCLK=1;
DS1302_CE=0;
}
uchar DS1302_read(uchar address)
{
uchar dat;
DS1302_CE=0;
_nop_();
_nop_();
DS1302_SCLK=0;
_nop_();
_nop_();
DS1302_CE=1;
_nop_();
_nop_();
DS1302_write_byte(address);
dat =DS1302_read_byte();
DS1302_SCLK=1;
DS1302_CE=0;
dat=dat/16*10+dat;
return dat;
}
void DS1302_init()
{
DS1302_write(0x8e,0x00);
DS1302_write(0x80,0x00);
DS1302_write(0x82,0x00);
DS1302_write(0x84,0x12);
DS1302_write(0x86,0x10);
DS1302_write(0x88,0x11);
DS1302_write(0x8a,0x06);
DS1302_write(0x8c,0x12);
DS1302_write(0x8e,0x80);
}
void set_time()
{
uchar i,j=0x80;
for(i=0;i
{
dt=dt/10*16+dt;
}
DS1302_write(0x8e,0x00);
DS1302_write(0x80,0x00);
for(i=0;i
{
DS1302_write(j,dt);
j+=2;
}
DS1302_write(0x8e,0x80);
}
void get_time()
{
dt[0] =DS1302_read(0x81);
dt[1] =DS1302_read(0x83);
dt[2] =DS1302_read(0x85);
dt[3] =DS1302_read(0x87);
dt[4] =DS1302_read(0x89);
dt[5] =DS1302_read(0x8b);
dt[6] =DS1302_read(0x8d);
}
void chaongdiaon() //充电
{
DS1302_write(0x8e,0x00);
_nop_();
_nop_();
DS1302_write(0x90, 0xa6); //使能充电 用一个二极管 用4k电阻
DS1302_write(0x8e,0x80);
_nop_();
_nop_();
}
uchar code self_char[]={
0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02, //年
0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x01, //月
0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00, //日
0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00, //温度标志— —摄氏度
0x00,0x04,0x0E,0x1F,0x0E,0x04,0x00,0x00, //符号◆
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, //全开
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //
};
bit lcd_busy()
{
bit result;
LCD1602_RS=0;
LCD1602_RW=1;
LCD1602_EN=1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0&0x80);
LCD1602_EN=0;
return(result);
}
void LCD1602_wcmd(uchar cmd)
{
while(lcd_busy());
LCD1602_RS=0;
LCD1602_RW=0;
_nop_();
_nop_();
LCD1602_EN=1;
_nop_();
_nop_();
_nop_();
_nop_();
P0=cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD1602_EN=0;
}
void LCD1602_wdat(uchar dat)
{
while(lcd_busy());
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_EN=1;
_nop_();
_nop_();
_nop_();
_nop_();
P0=dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD1602_EN=0;
}
void LCD1602_pos(uchar x,bit y) //指定坐标,x为列,0~15,y为行,0为第一行,1为第二行。
{
if(y)LCD1602_wcmd(x|0xc0);
else LCD1602_wcmd(x|0x80);
}
void LCD1602_dischar(uchar x,bit y,uchar dat) //指定位置显示一个字符
{
LCD1602_pos(x,y);
LCD1602_wdat(dat);
}
void LCD1602_prints(uchar x,bit y,uchar *p) //指定位置显示字符串
{
LCD1602_pos(x,y);
while((*p) != '\0') {LCD1602_wdat(*p);p++;}
}
void LCD1602_init()
{
uchar i;
LCD1602_wcmd(0x40);
for(i=0;i
{
LCD1602_wdat(self_char);
}
LCD1602_wcmd(0x38);
LCD1602_wcmd(0x38);
LCD1602_wcmd(0x0c);
LCD1602_wcmd(0x06);
LCD1602_wcmd(0x01);
}
uchar wendu[4];
void delay_18b20(uchar i)
{
int j;
for(j=0;j
}
uchar init_18b20()
{
uchar i;
DQ=0;
delay_18b20(30);
DQ=1;
delay_18b20(3);
i=DQ;
delay_18b20(20);
return(i);
}
uchar read_18b20_bit()
{
uchar i;
DQ=0;
DQ=1;
for(i=0;i
return(DQ);
}
void write_18b20_bit(unsigned xbit)
{
DQ=0;
if(xbit==1)
DQ=1;
delay_18b20(5);
DQ=1;
}
uchar read_18b20_byte()
{
uchar i,j,value;
j=1;
value=0;
for(i=0;i
{
if(read_18b20_bit())
{
value=value+(j
}
delay_18b20(6);
}
return(value);
}
void write_18b20_byte(uchar x)
{
uchar i,j;
for(i=0;i
{
j=x>>i;
j=j&0x01;
write_18b20_bit(j);
delay_18b20(5);
}
}
void get_wendu()
{
uchar a,b;
float get_temp;
int temp1,temp2;
init_18b20();
write_18b20_byte(0xcc);
write_18b20_byte(0x44);
init_18b20();
write_18b20_byte(0xcc);
write_18b20_byte(0xbe);
a=read_18b20_byte(); //低8位
b=read_18b20_byte(); //高8位
temp1=b;
temp1=temp1
temp1=temp1|a;
if(b&0xfc)
{wendu[0]=1;temp1=~temp1+1;} //0正1负
else
wendu[0]=0;
get_temp=temp1*0.0625;
temp2=get_temp*10+0.5;
wendu[1]=temp200/100;
wendu[2]=temp2000/10;
wendu[3]=temp2000;
}
uchar mode=0,OK=0;
uchar dis1[16],dis2[16];
//uchar IRCOM[7],IRCODE=0;
uchar NUM1,NUM2;
uchar count;
bit L=0,select=0,DIS_EN=1,SHAN;
void delay(uint i)
{
uchar j;
while(i-- !=0)
{
for(j=0;j
}
}
void delay1(uchar i)
{
uchar j;
while(i--)
{for(j=0;j
}
void get_dis()
{
dis1[0]='2';
dis1[1]='0';
dis1[2]=0x30+dt[6]/10;
dis1[3]=0x30+dt[6];
dis1[4]=0;
dis1[5]=0x30+dt[4]/10;
dis1[6]=0x30+dt[4];
dis1[7]=1;
dis1[8]=0x30+dt[3]/10;
dis1[9]=0x30+dt[3];
dis1[10]=2;
dis1[11]=' ';
dis1[12]=' ';
switch(dt[5])
{
case 1: {
dis1[13]='M';
dis1[14]='o';
dis1[15]='n';
}
break;
case 2: {
dis1[13]='T';
dis1[14]='u';
dis1[15]='e';
}
break;
case 3: {
dis1[13]='W';
dis1[14]='e';
dis1[15]='d';
}
break;
case 4: {
dis1[13]='T';
dis1[14]='h';
dis1[15]='u';
}
break;
case 5: {
dis1[13]='F';
dis1[14]='r';
dis1[15]='i';
}
break;
case 6: {
dis1[13]='S';
dis1[14]='a';
dis1[15]='t';
}
break;
case 7: {
dis1[13]='S';
dis1[14]='u';
dis1[15]='n';
}
break;
}
dis2[0]=' ';
dis2[1]=0x30+dt[2]/10;
dis2[2]=0x30+dt[2];
dis2[3]=':';
dis2[4]=0x30+dt[1]/10;
dis2[5]=0x30+dt[1];
dis2[6]=':';
dis2[7]=0x30+dt[0]/10;
dis2[8]=0x30+dt[0];
dis2[9]=' ';
if(wendu[0]==1)
dis2[10]=0x2d;
else
dis2[10]=' ';
dis2[11]=0x30+wendu[1];
dis2[12]=0x30+wendu[2];
dis2[13]='.';
dis2[14]=0x30+wendu[3];
dis2[15]=3;
}
void keyscan()
{
if(k1==0)
{
delay(10);
if(k1==0)
{
while(!k1);
mode++;
if(mode==1 && OK==0)
LCD1602_wcmd(0x01);
if(mode==2 && OK==0)
{
mode=0;
select=0;
}
if(select==0 && OK==1)
{
if(mode==7)
mode=1;
}
if(select==1 && OK==1)
{
if(mode==6)
mode=1;
}
}
}
if(k2==0)
{
delay(10);
if(k2==0)
{
while(!k2);
if(mode==1 && OK==0)
{select=~select;LCD1602_wcmd(0x01);}
NUM1++;
}
}
if(k3==0)
{
delay(10);
if(k3==0)
{
while(!k3);
if(mode==1 && OK==0)
{select=~select;LCD1602_wcmd(0x01);}
NUM2++;
}
}
if(k4==0)
{
delay(10);
if(k4==0)
{
while(!k4);
if(mode==0)
light=~light;
if(mode !=0)
{
LCD1602_wcmd(0x01);
OK++;
NUM1=0;
NUM2=0;
if(OK==2)
{
LCD1602_wcmd(0x01);
set_time();
// set_alarm();
mode=0;
select=0;
OK=0;
}
}
}
}
if(k5==0)
{
delay(100);
if(k5==0)
{
while(!k5);
DS1302_init();
}
}
}
void display()
{
get_wendu();
get_dis();
if(mode==0) //正常模式
{
uchar i;
LED1=1;
get_time();
// get_alarm();
LCD1602_pos(0,0);
for(i=0;i
LCD1602_wdat(dis1);
LCD1602_pos(0,1);
for(i=0;i
LCD1602_wdat(dis2);
}
if(mode==1&&OK==0) //菜单模式
{
LCD1602_prints(1,0,1.Set Time);
LCD1602_prints(1,1,2.About...);
if(select)
LCD1602_dischar(0,1,4);
else
LCD1602_dischar(0,0,4);
}
if(OK==1&&select==0) //调日期模式
{
uchar i;
LCD1602_pos(0,0);
for(i=0;i
LCD1602_wdat(dis1);
LCD1602_pos(0,1);
for(i=0;i
LCD1602_wdat(dis2);
LCD1602_prints(10,1,Set...);
if(SHAN==1) LCD1602_prints(10,1,Set. );
if(mode==1) //调分模式,秒位清零
{
dt[0]=0;
LCD1602_dischar(7,1,0x30+dt[0]/10);
LCD1602_dischar(8,1,0x30+dt[0]);
if(NUM1!=0)
{
dt[1]++;
if(dt[1]==60)
dt[1]=0;
LCD1602_dischar(4,1,0x30+dt[1]/10);
LCD1602_dischar(5,1,0x30+dt[1]);
NUM1=0;
}
if(NUM2!=0)
{
dt[1]--;
if(dt[1]==-1)
dt[1]=59;
LCD1602_dischar(4,1,0x30+dt[1]/10);
LCD1602_dischar(5,1,0x30+dt[1]);
NUM2=0;
}
if(SHAN==1) LCD1602_dischar(5,1,5);
}
else
if(mode==2) //调时模式
{
if(NUM1!=0)
{
dt[2]++;
if(dt[2]==24)
dt[2]=0;
LCD1602_dischar(1,1,0x30+dt[2]/10);
LCD1602_dischar(2,1,0x30+dt[2]);
NUM1=0;
}
if(NUM2!=0)
{
dt[2]--;
if(dt[2]==-1)
dt[2]=23;
LCD1602_dischar(1,1,0x30+dt[2]/10);
LCD1602_dischar(2,1,0x30+dt[2]);
NUM2=0;
}
if(SHAN==1) LCD1602_dischar(2,1,5);
}
if(mode==3) //调星期状态
{
if(NUM1!=0)
{
dt[5]++;
if(dt[5]==8)
dt[5]=1;
switch(dt[5])
{
case 1: LCD1602_prints(13,0,Mon);break;
case 2: LCD1602_prints(13,0,Tue);break;
case 3: LCD1602_prints(13,0,Wed);break;
case 4: LCD1602_prints(13,0,Thu);break;
case 5: LCD1602_prints(13,0,Fri);break;
case 6: LCD1602_prints(13,0,Sat);break;
case 7: LCD1602_prints(13,0,Sun);break;
}
NUM1=0;
}
if(NUM2!=0)
{
dt[5]--;
if(dt[5]==0)
dt[5]=7;
switch(dt[5])
{
case 1: LCD1602_prints(13,0,Mon);break;
case 2: LCD1602_prints(13,0,Tue);break;
case 3: LCD1602_prints(13,0,Wed);break;
case 4: LCD1602_prints(13,0,Thu);break;
case 5: LCD1602_prints(13,0,Fri);break;
case 6: LCD1602_prints(13,0,Sat);break;
case 7: LCD1602_prints(13,0,Sun);break;
}
NUM2=0;
}
if(SHAN==1) LCD1602_dischar(15,0,5);
}
if(mode==4) //调日模式
{
if(NUM1!=0)
{
dt[3]++;
if(dt[3]==32)
dt[3]=1;
LCD1602_dischar(8,0,0x30+dt[3]/10);
LCD1602_dischar(9,0,0x30+dt[3]);
NUM1=0;
}
if(NUM2!=0)
{
dt[3]--;
if(dt[3]==0)
dt[3]=31;
LCD1602_dischar(8,0,0x30+dt[3]/10);
LCD1602_dischar(9,0,0x30+dt[3]);
NUM2=0;
}
if(SHAN==1) LCD1602_dischar(9,0,5);
}
if(mode==5) //调月模式
{
if(NUM1!=0)
{
dt[4]++;
if(dt[4]==13)
dt[4]=1;
LCD1602_dischar(5,0,0x30+dt[4]/10);
LCD1602_dischar(6,0,0x30+dt[4]);
NUM1=0;
}
if(NUM2!=0)
{
dt[4]--;
if(dt[4]==0)
dt[4]=12;
LCD1602_dischar(5,0,0x30+dt[4]/10);
LCD1602_dischar(6,0,0x30+dt[4]);
NUM2=0;
}
if(SHAN==1) LCD1602_dischar(6,0,5);
}
if(mode==6) //调年模式
{
if(NUM1!=0)
{
dt[6]++;
if(dt[6]==100)
dt[6]=0;
LCD1602_dischar(2,0,0x30+dt[6]/10);
LCD1602_dischar(3,0,0x30+dt[6]);
NUM1=0;
}
if(NUM2!=0)
{
dt[6]--;
if(dt[6]==-1)
dt[6]=99;
LCD1602_dischar(2,0,0x30+dt[6]/10);
LCD1602_dischar(3,0,0x30+dt[6]);
NUM2=0;
}
if(SHAN==1) LCD1602_dischar(3,0,5);
}
}
if(OK==1&&select==1) //调闹铃模式
{
LCD1602_prints(0,0, Birthday gift );
LCD1602_prints(0,1, --by HJL);
delay(2000);
LCD1602_wcmd(0x01);
LCD1602_prints(0,0,2013-12-04 Is );
LCD1602_prints(0,1,LiYunL birthday!);
delay(2000);
LCD1602_wcmd(0x01);
LCD1602_prints(0,0,Friends together);
LCD1602_prints(0,1,for life... );
delay(2000);
LCD1602_wcmd(0x01);
mode=1 ;
OK=0;
}
}
void diy()
{
LCD1602_init();
delay(1);
LCD1602_prints(0,0, Digital Clock );
LCD1602_prints(0,1,v1.1.0 --by HJL);
delay(1000);
LCD1602_wcmd(0x01);
}
void main()
{
IT0=1; //外部中断0为下降沿触发
EX0=1; //
TMOD=0x01;
TH0=0x3C; //50ms
TL0=0xB0;
EA=1;
ET0=1;
TR0=1;
get_wendu();
diy();
chaongdiaon();
while(1)
{
P1=0xff;
keyscan();
display();
}
}
void timer0() interrupt 1
{
TH0=0x3C;
TL0=0xB0;
count++;
if(count==10)
{
count=0;
SHAN=~SHAN;
}
}