我试了好多遍,还是有问题,我猜测是时序问题,请各位前辈指点一下。晶振是11.0592的
#include"reg52.h"
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P3^7;
sbit a=P2^1;
sbit b=P2^2;
sbit c=P2^3;
uchar duan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f},duan2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
void dy(uint x)
{
while(x--);
}
void dy30(void) //误差 -0.703125us
{
unsigned char a;
for(a=11;a>0;a--);
}
void dy15(void) //误差 -0.894097222222us
{
unsigned char a;
for(a=4;a>0;a--);
}
void dy45(void) //误差 -0.512152777778us
{
unsigned char a;
for(a=18;a>0;a--);
}
void dy500(void) //误差 -0.868055555556us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=227;a>0;a--);
}
uchar init()
{
uchar i=0;
DQ=0;
dy500(); //至少480us
DQ=1;
while(DQ) //等待拉低总线 15~60us内拉低
{
i++;
if(i>50000)
return 0;
}
return 1;
}
void write(uchar dat) //发送一个字节数据
{
uchar i;
for(i=0;i<8;i++)
{
dy(1); //写时序时先将总线拉低最少1us,写0时序总线必须保持低电平60~120us然后释放总线(即拉高电平),
//写1时序时要在总线产生写时序后15us内把总线拉高,2次写周期之间至少间隔1us
DQ=0;
dy15();
DQ=dat&0X01; //向最低位看齐
dy45();
//dy80();
DQ=1;//施放总线至少1us
dat>>=1;
}
}
uchar read() //读取一个字节数据 数据的传输时从最低位开始的
{//产生读时序时必须将总线拉低至少1us然后释放总线,在读信号开始15us内开始采集数据,
//读一位数据至少保持在60us以上,俩次读周期之间至少间隔1us
uchar i,a=0X00,b=0;
for(i=0;i<8;i++)
{
DQ=1;
dy(2);
DQ=0;
dy(6);
DQ=1;
dy(4);
a|=DQ;
dy30(); //便于检测
b=b>>1|a<<7;
}
return b;
}
void changetemp() //转化温度
{
init();
dy(100);
write(0Xcc); //忽略64位ROM地址,直接向18B20发送温度变换命令,适用于一个从机工作
write(0X44); //启动18B20进行温度转换,结果存入内部9字节的RAM中
}
int gettemp() //读取温度 ,作为返回值返回
{
char templ,temph;
float ft;
int temp;
init();
dy(100);
write(0Xcc);
write(0Xbe); //读取命令,温度以2字节补码的形式存放在RAM的第0和第1个字节,负数的补码是原码取反然后加一,读出来后要进行转换
templ=read(); //读取低八位
temph=read(); //读取高八位
temp|=temph;
temp=temp<<8|templ;
ft=temp*0.0625*100+0.5; //转换为温度数据
temp=ft; //先试着只看整数部分
return temp;
}
void xs(int temp) //数码管显示温度
{
uint i;
for(i=0;i<6;i++)
{
switch(i)
{
case 0:a=0;b=0;c=0;break;
case 1:a=1;b=0;c=0;;break;
case 2:a=0;b=1;c=0;P0=duan[temp/1000%10];break;
case 3:a=1;b=1;c=0;P0=duan2[temp/100%10];break;
case 4:a=0;b=0;c=1;P0=duan[temp/10%10];break;
case 5:a=1;b=0;c=1;P0=duan[temp%10];break; //最低位
}
dy(100);
P0=0X00;
}
}
void main()
{
while(1)
{
changetemp();
xs(gettemp());
// xs(1232);
}
}