我这儿有使用ds1302和1602液晶加上ds18b20温度传感器结合在一起的,三个按键可以用来调节时间,和年月日,是在proteus中模拟的。
实验效果如图所示
![](https://video.ask-data.xyz/img.php?b=https://iknow-pic.cdn.bcebos.com/8601a18b87d6277f85a1fd9c29381f30e824fce7?x-bce-process=image%2Fresize%2Cm_lfit%2Cw_600%2Ch_800%2Climit_1%2Fquality%2Cq_85%2Fformat%2Cf_auto)
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();
}
}