求使用单片机74LS273 设计LED电脑时钟 课程设计报告

如题所述

第1个回答  2013-06-13

我这儿有使用ds1302和1602液晶加上ds18b20温度传感器结合在一起的,三个按键可以用来调节时间,和年月日,是在proteus中模拟的。

实验效果如图所示

c语言代码如下

  #include<reg52.h>
  #include<intrins.h>
  #define uchar unsigned char
  uchar miao,fen,xiaoshi,ri,yue,nian,tem,lsb,msb,pushtime;
  uchar code  x[]=" 20  /  /  ";
  uchar code x1[]="     :  :  " ;
  sbit RS=P1^0;
sbit EN=P1^1;
sbit clk=P3^2;
sbit IO=P3^7;
sbit reset=P3^0;
sbit key1=P1^4;
sbit key2=P1^5;
sbit key3=P1^6;
sbit DQ=P1^7;

void key();


void delay(uchar z) //延时4ms
{
uchar x,y;
for(x=0;x<z;x++)
for(y=0;y<110;y++);
}
void delayus(uchar z)//10us
{
uchar i;
for(i=0;i<z;i++)
{
_nop_();
}
}

void date(uchar dat)
{
 RS=1;
 P2=dat;
 EN=1;
 delay(1);
 EN=0;
 delay(1); 
}
void write_com(uchar com)
{
 RS=0;
 P2=com;
 EN=1;
 delay(1);
 EN=0;
 delay(1);
}
void init()
{
uchar i;
 EN=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
  write_com(0x01);
write_com(0x80);
for(i=0;i<11;i++)
{
date(x[i]);
}
write_com(0x80+0x40);
for(i=0;i<11;i++)
{
date(x1[i]);
}
clk=0;
IO=0;
reset=0;
}
void write1(uchar x)  //写一位
{
IO=x;
clk=0;
clk=1;
}
uchar read1() //读一位
{
uchar x;
clk=1;
clk=0;
_nop_();
x=IO;
return x;
}
void writebyte(uchar date) //写一个字节
{
uchar i,x;
for(i=0;i<8;i++)
{
x=date%2;
date=date>>1;
write1(x);
}

}
uchar readbyte()  //读一个字节
{
uchar i,x,date;
date=0;
for(i=0;i<8;i++)
{
x=read1();
x=x<<i;
date=date+x;
}
return date;

}
uchar read(uchar addr)
{
uchar date;
reset=1;
writebyte(addr);
date=readbyte();
reset=0;
return date;
}


 
void write(uchar addr,uchar date)
{
reset=1;
writebyte(addr);
writebyte(date);
reset=0;
}
void key()
{
uchar gewei,shiwei,x;
if(key1==0)
{
delay(3);//延时12ms软件消抖
if(key1==0)
{
pushtime++;
while(key1==0);
}
}
switch(pushtime)
{
case 0:
break;
case 1:    //修改分
write(0x80,0x80);
write_com(0x80+0x40+7);
write_com(0x0f);
if(key2==0)
{
delay(3);
if(key2==0)
{
gewei=fen&0x0f;   //取出分的个位
shiwei=(fen&0x70)>>4; //取出分的十位
x=gewei+10*shiwei;
x++;
if(x==60)
{
x=0;
}
gewei=x%10;
shiwei=x/10;
fen=(shiwei<<4)+gewei;    //重新得到分
write(0x82,fen);  //修改3102中的分
write_com(0x80+0x40+6);//修改屏幕上的分
date(shiwei+0x30);  
write_com(0x80+0x40+7);
date(gewei+0x30);
while(key2==0);
}
}
if(key3==0)
{
delay(3);
if(key3==0)
{
gewei=fen&0x0f;   //取出分的个位
shiwei=(fen&0x70)>>4; //取出分的十位
x=gewei+10*shiwei;
x--;
if(x==255)
{
x=59;
}
gewei=x%10;
shiwei=x/10;
fen=(shiwei<<4)+gewei;    //重新得到分
write(0x82,fen);  //修改3102中的分
write_com(0x80+0x40+6);//修改分地址
date(shiwei+0x30);  //修改分数
write_com(0x80+0x40+7);//修改分地址
date(gewei+0x30); //修改分数
while(key3==0);
}
}
break;
case 2:   //修改小时
write_com(0x80+0x40+4);
if(key2==0)
{
delay(3);
if(key2==0)
{
gewei=xiaoshi&0x0f;   //取出小时的个位
shiwei=(xiaoshi&0x30)>>4; //取出小时的十位
x=gewei+10*shiwei;
x++;
if(x==24)
{
x=0;
}
gewei=x%10;
shiwei=x/10;
xiaoshi=(shiwei<<4)+gewei;    //重新得到小时
write(0x84,xiaoshi);  //修改3102中的小时
write_com(0x80+0x40+3);//修改屏幕上的小时
date(shiwei+0x30);  
write_com(0x80+0x40+4);
date(gewei+0x30);
while(key2==0);
}
}
if(key3==0)
{
delay(3);
if(key3==0)
{
gewei=xiaoshi&0x0f;   //取出小时的个位
shiwei=(xiaoshi&0x30)>>4; //取出小时的十位
x=gewei+10*shiwei;
x--;
if(x==255)
{
x=23;
}
gewei=x%10;
shiwei=x/10;
xiaoshi=(shiwei<<4)+gewei;    //重新得到小时
write(0x84,xiaoshi);  //修改3102中的小时
write_com(0x80+0x40+3);//修改小时地址
date(shiwei+0x30);  //修改分数
write_com(0x80+0x40+4);//修改小时地址
date(gewei+0x30); //修改分数
while(key3==0);
}
}
break;
case 3:
write_com(0x80+10);//修改日
if(key2==0)
{
delay(3);
if(key2==0)
{
gewei=ri&0x0f;   //取出日的个位
shiwei=(ri&0x30)>>4; //取出日的十位
x=gewei+10*shiwei;
x++;
if(x==32)
{
x=0;
}
gewei=x%10;
shiwei=x/10;
ri=(shiwei<<4)+gewei;    //重新得到日
write(0x86,ri);  //修改3102中的日
write_com(0x80+9);//修改屏幕上的日
date(shiwei+0x30);  
write_com(0x80+10);
date(gewei+0x30);
while(key2==0);
}
}
if(key3==0)
{
delay(3);
if(key3==0)
{
gewei=ri&0x0f;   //取出日的个位
shiwei=(ri&0x70)>>4; //取出日的十位
x=gewei+10*shiwei;
x--;
if(x==255)
{
x=31;
}
gewei=x%10;
shiwei=x/10;
ri=(shiwei<<4)+gewei;    //重新得到日
write(0x86,ri);  //修改3102中的日
write_com(0x80+9);//修改日地址
date(shiwei+0x30);  //修改分、日数
write_com(0x80+10);//修改日地址
date(gewei+0x30); //修改日数
while(key3==0);
}
}
break;
case 4:
write_com(0x80+7);//修改月
if(key2==0)
{
delay(3);
if(key2==0)
{
gewei=yue&0x0f;   //取出月的个位
shiwei=(yue&0x10)>>4; //取月的十位
x=gewei+10*shiwei;
x++;
if(x==13)
{
x=0;
}
gewei=x%10;
shiwei=x/10;
yue=(shiwei<<4)+gewei;    //重新得到月
write(0x88,yue);  //修改3102中的月
write_com(0x80+6);//修改屏幕上的月
date(shiwei+0x30);  
write_com(0x80+7);
date(gewei+0x30);
while(key2==0);
}
}
if(key3==0)
{
delay(3);
if(key3==0)
{
gewei=yue&0x0f;   //取出月的个位
shiwei=(yue&0x10)>>4; //取出月的十位
x=gewei+10*shiwei;
x--;
if(x==0)
{
x=12;
}
gewei=x%10;
shiwei=x/10;
yue=(shiwei<<4)+gewei;    //重新得到月
write(0x88,yue);  //修改3102中的月
write_com(0x80+6);//修改月地址
date(shiwei+0x30);  //修改月数
write_com(0x80+7);//修改月地址
date(gewei+0x30); //修改月数
while(key3==0);
}
}
break;
case 5:
write_com(0x80+4);//修改年
if(key2==0)
{
delay(3);
if(key2==0)
{
gewei=nian&0x0f;   //取出年的个位
shiwei=(nian&0x70)>>4; //取出年的十位
x=gewei+10*shiwei;
x++;
if(x==100)
{
x=0;
}
gewei=x%10;
shiwei=x/10;
nian=(shiwei<<4)+gewei;    //重新得到年
write(0x8c,nian);  //修改3102中的年
write_com(0x80+3);//修改屏幕上的分
date(shiwei+0x30);  
write_com(0x80+4);
date(gewei+0x30);
while(key2==0);
}
}
if(key3==0)
{
delay(3);
if(key3==0)
{
gewei=nian&0x0f;   //取出年的个位
shiwei=(nian&0x70)>>4; //取出年的十位
x=gewei+10*shiwei;
x--;
if(x==255)
{
x=99;
}
gewei=x%10;
shiwei=x/10;
nian=(shiwei<<4)+gewei;    //重新得到年
write(0x8c,nian);  //修改3102中的年
write_com(0x80+3);//修改年地址
date(shiwei+0x30);  //修改年数
write_com(0x80+4);//修改年地址
date(gewei+0x30); //修改年数
while(key3==0);
}
}
break;
case 6:
pushtime=0;
write_com(0x0c);
write(0x80,0x00);
break;
}


}
void resettem()
{
DQ=1;//温度reset
_nop_();
_nop_();
DQ=0;
delayus(60); //延时480-960us 600us
DQ=1;
delayus(6);//15-60us
delay(20);//最多80ms的响应时间
DQ=1;
_nop_();
_nop_();
}

void temwrite1(uchar x)
{
DQ=0;
_nop_();
_nop_();//2us
DQ=x;
delayus(7);//70us
DQ=1;
_nop_();
_nop_();

}

void temwritebyte(uchar date)
{
uchar i,x;
for(i=0;i<8;i++)
{
x=date%2;
date=date>>1;
temwrite1(x);
}
}

uchar temread1()
{
uchar x;
DQ=0;
_nop_();
_nop_();//2us
DQ=1;
_nop_();
_nop_();
_nop_();//3us
x=DQ;
delayus(6);//60us
DQ=1;
_nop_();
_nop_();//2us
return x;
}

uchar temreadbyte()
{
uchar i,date,x;
date=0;
for(i=0;i<8;i++)
{
x=temread1();
x=x<<i;
date=date+x;
}
return date;
}

void main()
{
uchar gewei,shiwei;
    init();
write_com(0x80+15);
date(0xdf);
write(0x84,0x10);
while(1)
{
if(pushtime==0)
{
/*测量时间*/
miao=read(0x81);  //读秒
gewei=miao&0x0f;
shiwei=miao&0x70;
shiwei=shiwei>>4;
write_com(0x80+0x40+9);//修改秒地址
date(shiwei+0x30); //修改秒数
write_com(0x80+0x40+10);//修改秒地址
date(gewei+0x30); //修改秒数

fen=read(0x83);    //读分
gewei=fen&0x0f;
shiwei=fen&0x70;
shiwei=shiwei>>4;
write_com(0x80+0x40+6);//修改分地址
date(shiwei+0x30); //修改分数
write_com(0x80+0x40+7);//修改分地址
date(gewei+0x30); //修改分数

xiaoshi=read(0x85);    //读小时
gewei=xiaoshi&0x0f;
shiwei=xiaoshi&0x30;
shiwei=shiwei>>4;
write_com(0x80+0x40+3);//修改小时地址
date(shiwei+0x30); //修改小时数
write_com(0x80+0x40+4);//修改小时地址
date(gewei+0x30); //修改小时数

nian=read(0x8d);    //读年
gewei=nian&0x0f;
shiwei=nian&0xf0;
shiwei=shiwei>>4;
write_com(0x80+3);//修改年地址
date(shiwei+0x30); //修改年数
write_com(0x80+4);//修改年地址
date(gewei+0x30); //修改年数

yue=read(0x89);    //读月
gewei=yue&0x0f;
shiwei=yue&0xf0;
shiwei=shiwei>>4;
write_com(0x80+6);//修改月地址
date(shiwei+0x30); //修改月数
write_com(0x80+7);//修改月地址
date(gewei+0x30); //修改月数

yue=read(0x87);    //读日
gewei=yue&0x0f;
shiwei=yue&0xf0;
shiwei=shiwei>>4;
write_com(0x80+9);//修改日地址
date(shiwei+0x30); //修改日数
write_com(0x80+10);//修改日地址
date(gewei+0x30); //修改日数

/*测量温度*/
resettem();
temwritebyte(0xcc);
temwritebyte(0x44);
while(DQ==0);

resettem();
temwritebyte(0xcc);
temwritebyte(0xbe);
lsb=temreadbyte();
msb=temreadbyte();
tem=(lsb>>4)+(msb<<4);
gewei=tem%10;
shiwei=tem/10;
write_com(0x80+14);
date(gewei+0x30);
write_com(0x80+13);
date(shiwei+0x30);
}


key();    
}
}