#include <AT89X51.H>
#define unchar unsigned char
#define unint unsigned int
unchar code dispcode[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x00, //熄灭
0x40, //"-"
};//数码管段码 (共阴)
unchar data disdata[5];
unint tvalue; //温度值
unchar tflag; //温度正负标志
sbit DQ=P3^5; //ds18b20与单片机连接口
unchar i,j;
//******************************************************************/
void Delay(unchar a)
{
unchar i;
while (--a!=0)
{
for (i=0;i<100;i++);
}
}
//******************************************************************/
void delay_18B20(unint i) //延时1微秒
{
while(i--);
}
//******************************************************************/
void ds1820rst() //ds1820复位
{
unchar x=0;
DQ = 1; //DQ复位
delay_18B20(4); //延时
DQ = 0; //DQ拉低
delay_18B20(100); //精确延时大于480us
DQ = 1; //拉高
delay_18B20(40);
}
//******************************************************************/
unchar ds1820rd() //读数据*/
{
unchar i=0;
unchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; //给脉冲信号
dat>>=1;
DQ = 1; //给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
//******************************************************************/
void ds1820wr(unchar wdata) //写数据
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = wdata&0x01;
delay_18B20(10);
DQ = 1;
wdata>>=1;
}
}
//******************************************************************/
read_temp() //读取温度值并转换
{
unchar a,b;
ds1820rst();
ds1820wr(0xcc); //跳过读序列号
ds1820wr(0x44); //启动温度转换
ds1820rst();
ds1820wr(0xcc); //跳过读序列号
ds1820wr(0xbe); //读取温度
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
{
tvalue=~tvalue+1;
tflag=1;
}
tvalue=tvalue*(0.625); //温度值扩大10倍,精确到1位小数
return(tvalue);
}
//******************************************************************/
void ds1820disp()//温度值显示
{
read_temp();
disdata[0]=tvalue/1000; //百位数
disdata[1]=tvalue%1000/100;//十位数
disdata[2]=tvalue%100/10; //个位数
disdata[3]=tvalue%10; //小数位
if(disdata[0]==0)
{
disdata[0]=16; //如果百位为0,不显示
if(disdata[1]==0)
{
disdata[1]=16; //如果百位为0,十位为0也不显示
}
}
P0=0x01; //选通一位
P2=dispcode[disdata[3]];//
Delay(5);
P0=0x02; //选通一位
P2=dispcode[disdata[2]]-0x80;//
Delay(5);
P0=0x04; //选通一位
P2=dispcode[disdata[1]];//
Delay(5);
P0=0x08; //选通一位
P2=dispcode[disdata[0]];//
}
//............................................................................................
void main(void)
{
EA=1;
while(1)
{
ds1820disp();
}
} |