最近写了一个用at89s52和18b20的测温程序,但为何在数码管上的显示一直是8.5呢?
网上有许多解释,有的说温度读取后需要一定的转换时间,出现85的问题很大可能是转换时间不够 ;85是电源供电的问题,如果是寄生供电要保证1S以上的充电时间,转换开始后要尽快转到高电平,并保持1S以上,可以把上拉电阻减小到1K5试试 ;
有的说是忘了跳过ROM匹配,因此造成温度转换不成功,读到的是18B20暂存器中的温度上电缺省值85度,还有的说是电源端接触不良,偶尔出85度,焊好后,就正常了 ……
但我还是不太明白,小弟是一名初学者,请大家帮忙分析哈,不能感激!
附代码如下:
//18B20单线温度检测的应用样例程序
#include<REG52.H>
#include<math.h>
#include<INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
uchar temp;
uchar code tab[]={0x39,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ;
sbit DQ=P1^7;//ds18b20 端口
void delay15us(uchar n )
{
do
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();
n--;
}while(n);
}
//18b20初始化函数
unsigned Init_DS18B20(void)
{
uint answer_flag;
DQ = 0;
delay15us(35); //延时480~960us
DQ = 1;
delay15us(2); //延时15~60us等待响应
answer_flag=DQ; //采样应答脉冲信号
//delay15us(6);//延时60~240us
//delay15us(25);
return(answer_flag);
}
//读取一位
uchar Readbit(void)
{
bit s;
DQ=1; //拉高数据线,延时1s,准备启动读时隙
_nop_();
DQ=0; //保持低电平1us,但不能高于15us
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
DQ=1; //在15us之内,停止低电平
s=DQ; //读取一位数据
delay15us(4);//读时序不低于60us
return(s);
}
uchar Readbyte(void) //读取数据的一个字节
{
uchar i,j,by;
by=0;
for(i=0;i<8;i++)
{
j=Readbit();
by=(j<<7)|(by>>1);
}
return(by);
}
//写一个字节
void WriteOneChar(unsigned char byte)
{
unsigned int i=0;
bit n;
for (i=8; i>0; i--)
{
DQ = 1;
_nop_();
n=byte&0x01;
byte=byte>>1;
if(n) //写1
{
DQ=0;
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
DQ=1;
delay15us(4);
}
else
{
DQ=0;
delay15us(6);
DQ=1;
_nop_(); _nop_();
_nop_(); _nop_();
}
}
}
void convert(void)//启动温度转换
{
Init_DS18B20();//初始化,复位
if(Init_DS18B20()) //接受到应答脉冲
{
delay15us(7); //延时1ms
WriteOneChar(0xcc);//skip rom
WriteOneChar(0x44);//convert T
}
}
//读取温度
uchar ReadTemperature(void)
{
uchar a,b,t;
convert();
delay15us(7000);//1s
Init_DS18B20();
if( Init_DS18B20())
{
delay15us(7); //1ms
WriteOneChar(0xcc);
WriteOneChar(0xbe);
a=Readbyte(); //读取温度低位字节
b=Readbyte(); //高位
b<<=4;
b+=(a&0xf0)>>4;
t=b;
return(t);
}
}
void dispaly()
{
P2=0;
P0=tab[temp/10];
delay15us(200);
P2=1;
P0=tab[temp%10];
delay15us(200);
P2=2;
P0=tab[0];
delay15us(200);
}
void main()
{
while(1)
{
dispaly();
temp=ReadTemperature();
}
}
书上说如果测的温度>0,将结果乘以0.0625,<0,将测得的温度取反加1再乘0.0625,这个怎么处理呢? |