单片机+液晶12864+ds1302+ds18b20温度显示有问题,值不变
时间:10-02
整理:3721RD
点击:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar addr[6]={0x8d,0x89,0x8b,0x85,0x83,0x81}; //年,月,日,时,分,秒 读
uchar time[6];
uchar zhuanhua[12];
int t[8];
uchar th,tl;
sbit rs=P1^2; //数据/命令选择
sbit rw=P1^1; //读写控制
sbit e=P1^0; //片选信号
sbit rst=P3^0; //ds1302
sbit sclk=P3^1;
sbit io=P3^2;
sbit dq=P1^3;//ds18b20定义数据线
#define lcd P2 //8 bit数据线
#define low 0
#define high 1
void ds18b20ini();
ds18b20writebyte(uchar byte);
uchar ds18b20readbyte();
void gettemper();
void ds18b20dis( );
void delayus(uint k)
{
while(k--);
}
void delay(uint t)
{
int i;
while(t--)
{
for(i=0;i<120;i++);
}
}
//写命令函数
void wcom(uchar com)
{
//checkbusy();
e=low;
rs=low;
rw=low;
lcd=com;
//delay(5);
e=high;
delay(10);
e=low;
}
//写数据函数
void wdata(int dat)
{
//checkbusy();
e=low;
rs=high;
rw=low;
lcd=dat;
// delay(5);
e=high;
delay(10);
e=low;
}
//初始化函数
void init()
{
lcd=0xff;
delay(100);
wcom(0x30); //写基本指令集
delay(1);
wcom(0x30);
delay(1);
wcom(0x0c); //显示开
delay(1);
wcom(0x01); //清屏指令
delay(20);
wcom(0x06); //游标右移
delay(100);
}
//显示汉字
dishanzi(uchar addr,uchar *hz)
{
int i;
//checkbusy();
wcom(addr);
for(i=0;hz[i]!='\0';i++)
{
wdata(hz[i]);
//checkbusy();
}
delay(5);
}
//ds1302模块
void ds1302write(uchar addr,uchar data1) //写地址数据函数
{
uchar i;
rst=0;
_nop_();
sclk=0;
rst=1;
for(i=0;i<8;i++)
{
if(addr&0x01==1)
io=1;
else
io=0;
sclk=1;
_nop_();
sclk=0;
_nop_();
addr>>=1;
}
for(i=0;i<8;i++)
{
if(data1&0x01==1)
io=1;
else
io=0;
sclk=1;
_nop_();
sclk=0;
_nop_();
data1>>=1;
}
}
//ds1302读函数
uchar ds1302read(uchar addr)
{
uchar i;
uchar dat=0;
rst=0;
sclk=0;
_nop_();
rst=1;
_nop_();
for(i=0;i<8;i++)
{
if(addr&0x01==1)
io=1;
else
io=0;
sclk=1;
_nop_();
sclk=0;
_nop_();
addr>>=1;
}
for(i=0;i<8;i++)
{
dat>>=1;
if(io)
dat|=0x80;
else
dat|=0x00;
sclk=1;
_nop_();
sclk=0;
_nop_();
}
rst=0;
_nop_();
io=1;
_nop_();
sclk=1;
_nop_();
return dat;
}
//获得时间
void gettime()
{
int i;
for(i=0;i<6;i++)
{
time[i]=ds1302read(addr[i]); //依次为年月日时分秒
}
}
//转化为10进制
void zh()
{
zhuanhua[0]=time[0]%16+0x30;
zhuanhua[1]=time[0]/16+0x30;
zhuanhua[2]=time[1]%16+0x30;
zhuanhua[3]=time[1]/16+0x30;
zhuanhua[4]=time[2]%16+0x30;
zhuanhua[5]=time[2]/16+0x30;
zhuanhua[6]=time[3]%16+0x30;
zhuanhua[7]=time[3]/16+0x30;
zhuanhua[8]=time[4]%16+0x30;
zhuanhua[9]=time[4]/16+0x30;
zhuanhua[10]=time[5]%16+0x30;
zhuanhua[11]=time[5]/16+0x30;
}
//写时间
void ds1302ini()
{
ds1302write(0x8e,0x00);//去除写保护
ds1302write(0x8c,0x11); // 写年
ds1302write(0x88,0x10); //写月
ds1302write(0x8a,0x04); //写日
ds1302write(0x84,0x12); //写时
ds1302write(0x82,0x00); // 写分
ds1302write(0x80,0x00); // 写秒
ds1302write(0x8e,0x80);//写保护
}
//液晶显示时间
void distime()
{
dishanzi(0x90,"20");
wdata(zhuanhua[1]);
wdata(zhuanhua[0]);
dishanzi(0x92,"年");
wdata(zhuanhua[3]);
wdata(zhuanhua[2]);
dishanzi(0x94,"月");
wdata(zhuanhua[5]);
wdata(zhuanhua[4]);
dishanzi(0x96,"日");
wcom(0x88);
wdata(zhuanhua[7]);
wdata(zhuanhua[6]);
dishanzi(0x89,"时");
wdata(zhuanhua[9]);
wdata(zhuanhua[8]);
dishanzi(0x8b,"分");
wdata(zhuanhua[11]);
wdata(zhuanhua[10]);
dishanzi(0x8d,"秒");
}
//ds18b20模块
void ds18b20ini() //ds1820初始化函数
{
dq=0;
delayus(200);
dq=1;
delayus(40);
}
//ds18b20写一字节函数
ds18b20writebyte(uchar byte)
{
int j;
uchar value;
for(j=0;j<8;j++)
{
value=byte&0x01;
byte=byte>>1;
if(value)
{
dq=0;
delayus(3);
dq=1;
delayus(30);
}
else
{
dq=0;
delayus(10);
dq=1;
delayus(7);
}
}
}
//ds18b20读一字节函数
uchar ds18b20readbyte()
{
uchar dat;
int j;
for(j=0;j<8;j++)
{
dat=dat>>1;
dq=0;
delayus(5);
dq=1;
delayus(4);
if(dq)
dat|=0x80;
delayus(10);
}
return dat;
}
//获取温度函数
void gettemper()
{
uchar a,b;
ds18b20ini();
delay(1);
ds18b20writebyte(0xcc); //跳过ROM指令
ds18b20writebyte(0x44); //写温度转换指令 ,启动ds18b20
delay(1);
ds18b20ini();
ds18b20writebyte(0xcc);
ds18b20writebyte(0xbe);
a=ds18b20readbyte();
b=ds18b20readbyte();
th=b*256+a;
th*=0.0625;
}
//温度显示函数
void ds18b20dis( )
{
t[0]=th/100+'0';
if(t[0]=='0')
t[0]=' ';
t[1]=th%100/10+0x30;
t[2]=th%100%10+0x30;
t[3]='.';
t[4]=tl/1000+'0';
t[5]=tl%1000/100+'0';
t[6]=tl%100/10+'0';
t[7]=tl%10+'0';
dishanzi(0x98,"温度");
wcom(0x9a);
wdata(':');
wdata(t[0]);
wdata(t[1]);
wdata(t[2]);
wdata(t[3]);
wdata(t[4]);
wdata(t[5]);
wdata(t[6]);
wdata(t[7]);
}
void main(void)
{
init();
delay(15);
wcom(0x01);
delay(10);
ds1302ini();
delay(10);
ds18b20ini();
delay(10);
dishanzi(0x82,"电子时钟");
while(1)
{
delay(150);
gettime();
zh();
distime();
gettemper();
ds18b20dis();
}
}
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar addr[6]={0x8d,0x89,0x8b,0x85,0x83,0x81}; //年,月,日,时,分,秒 读
uchar time[6];
uchar zhuanhua[12];
int t[8];
uchar th,tl;
sbit rs=P1^2; //数据/命令选择
sbit rw=P1^1; //读写控制
sbit e=P1^0; //片选信号
sbit rst=P3^0; //ds1302
sbit sclk=P3^1;
sbit io=P3^2;
sbit dq=P1^3;//ds18b20定义数据线
#define lcd P2 //8 bit数据线
#define low 0
#define high 1
void ds18b20ini();
ds18b20writebyte(uchar byte);
uchar ds18b20readbyte();
void gettemper();
void ds18b20dis( );
void delayus(uint k)
{
while(k--);
}
void delay(uint t)
{
int i;
while(t--)
{
for(i=0;i<120;i++);
}
}
//写命令函数
void wcom(uchar com)
{
//checkbusy();
e=low;
rs=low;
rw=low;
lcd=com;
//delay(5);
e=high;
delay(10);
e=low;
}
//写数据函数
void wdata(int dat)
{
//checkbusy();
e=low;
rs=high;
rw=low;
lcd=dat;
// delay(5);
e=high;
delay(10);
e=low;
}
//初始化函数
void init()
{
lcd=0xff;
delay(100);
wcom(0x30); //写基本指令集
delay(1);
wcom(0x30);
delay(1);
wcom(0x0c); //显示开
delay(1);
wcom(0x01); //清屏指令
delay(20);
wcom(0x06); //游标右移
delay(100);
}
//显示汉字
dishanzi(uchar addr,uchar *hz)
{
int i;
//checkbusy();
wcom(addr);
for(i=0;hz[i]!='\0';i++)
{
wdata(hz[i]);
//checkbusy();
}
delay(5);
}
//ds1302模块
void ds1302write(uchar addr,uchar data1) //写地址数据函数
{
uchar i;
rst=0;
_nop_();
sclk=0;
rst=1;
for(i=0;i<8;i++)
{
if(addr&0x01==1)
io=1;
else
io=0;
sclk=1;
_nop_();
sclk=0;
_nop_();
addr>>=1;
}
for(i=0;i<8;i++)
{
if(data1&0x01==1)
io=1;
else
io=0;
sclk=1;
_nop_();
sclk=0;
_nop_();
data1>>=1;
}
}
//ds1302读函数
uchar ds1302read(uchar addr)
{
uchar i;
uchar dat=0;
rst=0;
sclk=0;
_nop_();
rst=1;
_nop_();
for(i=0;i<8;i++)
{
if(addr&0x01==1)
io=1;
else
io=0;
sclk=1;
_nop_();
sclk=0;
_nop_();
addr>>=1;
}
for(i=0;i<8;i++)
{
dat>>=1;
if(io)
dat|=0x80;
else
dat|=0x00;
sclk=1;
_nop_();
sclk=0;
_nop_();
}
rst=0;
_nop_();
io=1;
_nop_();
sclk=1;
_nop_();
return dat;
}
//获得时间
void gettime()
{
int i;
for(i=0;i<6;i++)
{
time[i]=ds1302read(addr[i]); //依次为年月日时分秒
}
}
//转化为10进制
void zh()
{
zhuanhua[0]=time[0]%16+0x30;
zhuanhua[1]=time[0]/16+0x30;
zhuanhua[2]=time[1]%16+0x30;
zhuanhua[3]=time[1]/16+0x30;
zhuanhua[4]=time[2]%16+0x30;
zhuanhua[5]=time[2]/16+0x30;
zhuanhua[6]=time[3]%16+0x30;
zhuanhua[7]=time[3]/16+0x30;
zhuanhua[8]=time[4]%16+0x30;
zhuanhua[9]=time[4]/16+0x30;
zhuanhua[10]=time[5]%16+0x30;
zhuanhua[11]=time[5]/16+0x30;
}
//写时间
void ds1302ini()
{
ds1302write(0x8e,0x00);//去除写保护
ds1302write(0x8c,0x11); // 写年
ds1302write(0x88,0x10); //写月
ds1302write(0x8a,0x04); //写日
ds1302write(0x84,0x12); //写时
ds1302write(0x82,0x00); // 写分
ds1302write(0x80,0x00); // 写秒
ds1302write(0x8e,0x80);//写保护
}
//液晶显示时间
void distime()
{
dishanzi(0x90,"20");
wdata(zhuanhua[1]);
wdata(zhuanhua[0]);
dishanzi(0x92,"年");
wdata(zhuanhua[3]);
wdata(zhuanhua[2]);
dishanzi(0x94,"月");
wdata(zhuanhua[5]);
wdata(zhuanhua[4]);
dishanzi(0x96,"日");
wcom(0x88);
wdata(zhuanhua[7]);
wdata(zhuanhua[6]);
dishanzi(0x89,"时");
wdata(zhuanhua[9]);
wdata(zhuanhua[8]);
dishanzi(0x8b,"分");
wdata(zhuanhua[11]);
wdata(zhuanhua[10]);
dishanzi(0x8d,"秒");
}
//ds18b20模块
void ds18b20ini() //ds1820初始化函数
{
dq=0;
delayus(200);
dq=1;
delayus(40);
}
//ds18b20写一字节函数
ds18b20writebyte(uchar byte)
{
int j;
uchar value;
for(j=0;j<8;j++)
{
value=byte&0x01;
byte=byte>>1;
if(value)
{
dq=0;
delayus(3);
dq=1;
delayus(30);
}
else
{
dq=0;
delayus(10);
dq=1;
delayus(7);
}
}
}
//ds18b20读一字节函数
uchar ds18b20readbyte()
{
uchar dat;
int j;
for(j=0;j<8;j++)
{
dat=dat>>1;
dq=0;
delayus(5);
dq=1;
delayus(4);
if(dq)
dat|=0x80;
delayus(10);
}
return dat;
}
//获取温度函数
void gettemper()
{
uchar a,b;
ds18b20ini();
delay(1);
ds18b20writebyte(0xcc); //跳过ROM指令
ds18b20writebyte(0x44); //写温度转换指令 ,启动ds18b20
delay(1);
ds18b20ini();
ds18b20writebyte(0xcc);
ds18b20writebyte(0xbe);
a=ds18b20readbyte();
b=ds18b20readbyte();
th=b*256+a;
th*=0.0625;
}
//温度显示函数
void ds18b20dis( )
{
t[0]=th/100+'0';
if(t[0]=='0')
t[0]=' ';
t[1]=th%100/10+0x30;
t[2]=th%100%10+0x30;
t[3]='.';
t[4]=tl/1000+'0';
t[5]=tl%1000/100+'0';
t[6]=tl%100/10+'0';
t[7]=tl%10+'0';
dishanzi(0x98,"温度");
wcom(0x9a);
wdata(':');
wdata(t[0]);
wdata(t[1]);
wdata(t[2]);
wdata(t[3]);
wdata(t[4]);
wdata(t[5]);
wdata(t[6]);
wdata(t[7]);
}
void main(void)
{
init();
delay(15);
wcom(0x01);
delay(10);
ds1302ini();
delay(10);
ds18b20ini();
delay(10);
dishanzi(0x82,"电子时钟");
while(1)
{
delay(150);
gettime();
zh();
distime();
gettemper();
ds18b20dis();
}
}
你看看ds18b20时序正确不 ,这个芯片对时序要求很高的
顶顶!
还行啊
不错
我的也是温度值不变,正在查原因。
发现温度传感器和时钟芯片不能用同一个口。