各位帮我看下这个18B20显示温度程序有什么问题~~多谢了

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^0;
sbit p11=P1^1;
sbit p26=P2^6;
sbit p27=P2^7;
sbit p22=P2^2;
uchar buf[2],flag1,tem;
uchar code table2[]={0x18,0x7b,0x2c,
0x29,0x4b,0x89,0x88,
0x3b,0x08,0x09};
void delay1(uchar aa)
{ while(aa--);
}

void reset() //复位
{
DQ=0;
delay1(180);
DQ=1;
_nop_();

while(DQ);
p22=0;
//p11=0;
delay1(80);
//p11=1;
DQ=1;
}

void write(uchar cmd)
{
uchar i;
for(i=0;i<8;i++)
{
if(cmd&(0x80>>i))
{
DQ=0;
_nop_();
_nop_();
DQ=1;
delay1(20);
}
else
{
DQ=0;
delay1(20);
DQ=1;
_nop_();
_nop_();

}
}
}

void read()
{
uchar j,i;
for(j=0;j<2;j++)
{
buf[j]=0;
for(i=0;i<8;i++)
{

DQ=0;
_nop_();
_nop_();
DQ=1;
_nop_();
_nop_();
if(DQ)
{
buf[j]=buf[j]|(0x80>>i);
}
else

buf[j]=buf[j]&~(0x80>>i);

delay1(20);
DQ=1;
_nop_();

}

}
}

void get_tem() //获取温度
{
reset();
write(0xcc);
write(0x44);
delay1(200);
reset();
write(0xcc);
write(0xbe);
read();

}

void get_tem10() //转换成10进制数
{
uchar num0,num1,tem0,tem1;
buf[0]=(buf[0]>>4); //低8位的高4位移入低4位
tem0=(buf[0]&(0x0f)); //保留低8位的低4位
tem1=(buf[1]&(0x0f)); //保留高8位的低4位

switch(tem0) //个位
{
case 0: num0=0;
break;
case 1: num0=1;
break;
case 2: num0=2;
break;
case 3: num0=3;
break;
case 4: num0=4;
break;
case 5: num0=5;
break;
case 6: num0=6;
break;
case 7: num0=7;
break;
case 8: num0=8;
break;
case 9: num0=9;
break;
case 0x0a: num0=10;
break;
case 0x0b: num0=11;
break;
case 0x0c: num0=12;
break;
case 0x0d: num0=13;
break;
case 0x0e: num0=14;
break;
case 0x0f: num0=15;
break;

}

switch(tem1)
{
case 0: num1=0;
break;
case 1: num1=1;
break;
case 2: num1=2;
break;
case 3: num1=3;
break;
case 4: num1=4;
break;
case 5: num1=5;
break;
case 6: num1=6;
break;
case 7: num1=7;
break;
case 8: num1=8;
break;
case 9: num1=9;
break;
case 0x0a: num1=10;
break;
case 0x0b: num1=11;
break;
case 0x0c: num1=12;
break;
case 0x0d: num1=13;
break;
case 0x0e: num1=14;
break;
case 0x0f: num1=15;
break;
}
tem=((num1*16)+num0);

}

void display2()
{
uchar shi,ge;
get_tem();
get_tem10();
shi=tem/10;
ge=tem%10;

p27=0;
P0=table2[shi];
delay1(150);
p27=1;

p26=0;
P0=table2[ge];
delay1(150);
p26=1;

}

void main()
{
while(1)
{
display2();

}
}

它显示一直是79~
现在一直显示85

可能是时序不对,我做的开始也是85,那是18B20的复位状态!
你可以参照一下下面的时序:
基于51单片机的数字温度计制作(含源程序)
最近忙于电子设计竞赛,很久没有更新文章了。今天忙中偷闲,再来写点东西,希望给大家带来更多的灵感!

本制作芯片采用数字温度传感器18b20,利用51单片机控制。

DS18B20基本知识
DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
1、DS18B20产品的特点
(1)、只要求一个端口即可实现通信。
(2)、在DS18B20中的每个器件上都有独一无二的序列号。
(3)、实际应用中不需要外部任何元器件即可实现测温。
(4)、测量温度范围在-55。C到+125。C之间。
(5)、数字温度计的分辨率用户可以从9位到12位选择。
(6)、内部有温度上、下限告警设置。
2、DS18B20的引脚介绍
TO-92封装的DS18B20的引脚排列见图1,其引脚功能描述见表1。
(底视图)图1

表1 DS18B20详细引脚功能描述 序号

名称

引脚功能描述

1
GND
地信号

2
DQ
数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源。

3
VDD
可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。

3. DS18B20的使用方法
由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。
DS18B20的复位时序

DS18B20的读时序
对于DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60us才能完成。

DS18B20的写时序
对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。
对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。

源程序:

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^0;
sbit rs=P3^4;
sbit r_w=P3^5;
sbit en=P3^6 ;
sbit psb=P3^7 ;
uchar data temp[]={0x00,0x00};
//uchar code num[]={"狂奔的蜗牛!"};

/**************延时函数*************/
/*void delay(uint t)
{
for(;t>0;t--) ;
} */
/*sbit DQ=P2^6;
sbit rs=P2^1;
sbit r_w=P2^2;
sbit en=P2^3 ;
sbit psb=P2^4 ;
uchar data temp[]={0x00,0x00};*/
void delayms(uint xms)
{
uint x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}

/*********12864驱动程序**************/
void write_com(uchar com)
{
rs=0;
r_w=0;
en=0;
P0=com;
delayms(1);
en=1;
delayms(1);
en=0;
}
void write_dat(uchar dat)
{
rs=1;
r_w=0;
en=0;
P0=dat;
delayms(1);
en=1;
delayms(1);
en=0;
}

void lcd_init()
{
psb=1;
write_com(0x30);
delayms(5);
write_com(0x0c);
delayms(5);
write_com(0x01);
delayms(5);
}

/**********18b20复位函数***********/
/*reset(void)
{
char temp=1;
while(temp)
{
while(temp)
{
DQ=1;_nop_();_nop_();
DQ=0;
delay(50);//550us
DQ=1;
delay(6);//66us
temp=DQ;
}
delay(45);
temp=~DQ;
}
DQ=1;
}
void reset(void)
{
uint d;
DQ=0;
d=103;
while(d>0)d--;
DQ=1;
d=4;
while(d>0)d--;
}
/**************写一字节************/
/*void write_byte(uchar wb)
{
uchar i;
for(i=0;i<8;i++)
{
DQ=1;_nop_();_nop_();
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();
DQ=wb&0x01;
delay(6);//66us
wb>>=1;
}
DQ=1;
delay(1);
}

/************读一字节****************/
/*uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;
_nop_();_nop_();_nop_();_nop_();
DQ=1;
_nop_();_nop_();_nop_();_nop_();//4us
if(DQ)value|=0x80;
delay(6);//66us
if(DQ)
value|=0x80;//低位到高位依次移入
delay(6);
}
DQ=1;
return(value);
}

/**********读出温度******************/
/*uint read_temp(void)//读取温度
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
reset();
write_byte(0xCC); // 跳过读序号列号的操作
write_byte(0x44); // 启动温度转换
reset();
write_byte(0xCC); //跳过读序号列号的操作
write_byte(0xBE); //读取温度寄存器
a=read_byte(); //读低8位
b=read_byte(); //读高8位
/* if(b>127)
{
b=(256-b);
a=(256-a);
} */
/* t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍输出并四舍五入
return(t);
}
/************温度处理函数************/
/*work_temp()
{

unsigned int i=0;
unsigned int a=0,b=0,c=0;
i=read_temp();//读温度并送显
a=i/100;
write_dat(0x30+a); //显示温度十位
b=i%100/10;
write_dat(0x30+b); //个位
// write_dat(0x2e); //"."
c=i%10;
write_dat(0x30+c);//小位1位
// write_dat("℃");//度C

} */
void Delay(int num)//延时函数
{
while(num--) ;
}
/******************************************************************************/
void reset(void)//初始化ds1820
{
unsigned char x=0;
DQ = 1; //DQ复位
Delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
Delay(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
Delay(20);
}
/******************************************************************************/
unsigned char ReadOneChar(void)//读一个字节
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
Delay(4);
}
return(dat);
}

/******************************************************************************/
void WriteOneChar(unsigned char dat)//写一个字节
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay(5);
DQ = 1;
dat>>=1;
}
}
/******************************************************************************/
unsigned int work_temp(void)//读取温度
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
reset();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
reset();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
if(b>127)
{
b=(256-b);
a=(256-a);
}
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍输出并四舍五入
return(t);
}
void lcm_w_word(unsigned char *str){
while(*str != '\0'){
write_dat(*str++);
}
*str = 0;
}
void xianshi()
{
unsigned char a=0;
unsigned char b=0;
unsigned char c=0;
unsigned int i=0 ;
i=work_temp();//读温度并送显示
a=i/100;
write_dat(a+0x30); //显示温度十位
b=i/10-a*10;
write_dat(b+0x30); //个位
write_dat(0x2e); //"."
c=i-a*100-b*10;
write_dat(c+0x30); //小位1位
lcm_w_word("℃"); //度C

}

/************************* 孙刚*********2009年调试完成*******************************/

/**********主函数********************/
void main()
{

TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
TH0=15536/256;
TL0=15536%256;
reset();
delayms(5);
lcd_init();
delayms(5);
write_com(0x80);
lcm_w_word("现在温度:");
write_com(0x88+2);
lcm_w_word("只好去狂奔!");
write_com(0x90);
lcm_w_word("跑不快的蜗牛,");
write_com(0x98);
lcm_w_word("dztd.lingd.net");
while(1)
{
write_com(0x80+5);
xianshi();
}

}

/*void timer_0() interrupt 1
{
uchar num;
TH0=15536/256;
TL0=15536%256;
num++;
if(num==40)
{
num=0;
write_com(0x01);
xianshi();

}
} */

/************************* 孙刚*********2009年调试完成*******************************/

参考资料:http://dztd.lingd.net/article-2836052-1.html

温馨提示:内容为网友见解,仅供参考
第1个回答  2009-08-21
18B20的复位状态为85,但你一直显示85,后来又显示79,说明你的时序完全不对,,仔细查一下你的时序.程序没什么问题.
要是查不出来,可回复我,我这有源程序!本回答被提问者采纳

各位帮我看下这个18B20显示温度程序有什么问题~~多谢了
可能是时序不对,我做的开始也是85,那是18B20的复位状态!你可以参照一下下面的时序:基于51单片机的数字温度计制作(含源程序) 最近忙于电子设计竞赛,很久没有更新文章了。今天忙中偷闲,再来写点东西,希望给大家带来更多的灵感!本制作芯片采用数字温度传感器18b20,利用51单片机控制。DS18B20基本知识 DS18B20数字温度计是D...

...是按照书上写的,数码管却显示4095.希望各位大虾给看看啊
我看了一些你的程序,没看到什么问题。显示不正常可能是因为:1、硬件问题,ds18b20出现故障,可能性不大!2、软件问题。18b20对时序要求非常严格,我要求学生练习时序的时候,就拿18b20作为实例 18b20对时序要求非常严格,我想问几个问题。你选用的晶振是多少?你严格按照说明书说的时序了吗?我没有测试你...

各位帮我看下这个18B20显示温度程序有什么问题~~多谢了
其实18b20的读取操作都不是很难,主要是时序要求比较严格点,你认真看芯片使用文档,严格按照上面的读写时序来编写就没问题了

18B20 测温 (51单片机 C程序 ) 看不懂啊
main()是主函数,这个是所有C程序必须的。while(1)是一个死循环,反复执行。

有关温度报警器的程序,有关DS18B20的程序已写好,求助有关蜂鸣器报警和温...
知道答主 回答量:33 采纳率:0% 帮助的人:18.5万 我也去答题访问个人页 关注 展开全部 本设计的温度测量及加热控制系统以 AT89S52 单片机为核心部件,外加温度采集电路、键盘及显示电路、加热控制电路和越限报警等电路。采用单总线型数字式的温度传感器DS18B20,及行列式键盘和动态显示的方式,以容易控制的固...

单片机ts18b20测温程序 请大神注释程序 最好每一句都注释明白(小白一只...
DQ=1;\/\/释放温度传感器18b20的数据接口 temperature_convert();\/\/第一次调用18b20温度转换子函数消除85°C问题 lcd_int();\/\/液晶屏初始化(放在18b20温度转换子函数后边用来延时,跳过85°C)while(1){ temperature_convert();\/\/调用18b20温度转换子函数 rd_ram_command();\/\/发送命令子函数(读取18b20...

DS18B20温度传感器的使用方法
;这是关于DS18B20的读写程序,数据脚P2.2,晶振11.0592mhz ;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒 ;可以将检测到的温度直接显示到AT89C51的两个数码管上 ;显示温度00到99度,很准确无需校正!ORG 0000H ;单片机内存分配申明!TEMPER_L EQU 29H;用于保存读出温度的低8位...

...让数码管显示能出小数点后一位,谁能帮我把程序改改?
是八位共阳级的吗? 试试我的程序吧 我自己改的 可以显示小数点后一位。帮你写了很详细的备注信息,应该看的懂了把?你的悬赏分是0很杯具。。。\/ DS18B20温度采集系统程序 8 位共阳极显示,P0 送显示代码,P2作位选信号,低电平选通 分时选通,直接计算 能显示摄氏度符号 通过DD18B20读取温...

有谁知道DS18B20 温度采集程序,用C 语言编程, 用KeilC51 编译。_百度知...
我的 有谁知道DS18B20 温度采集程序,用C 语言编程, 用KeilC51 编译。 单片机控制DS18B20完成温度转换必须经过3个步骤:(1)每一次读写之前都要对DS18B20进行复位,即由单片机按照时序要求发送一个复位脉冲,DS18B20送出存在脉冲;(2)复位成功后发送1条写ROM指... 单片机控制DS18B20 完成温度转换必须经过3 个步骤: ...

...温度传感器的程序代码,用四位共阴数码管显示温度值
\/\/DS18B20的读写程序,数据脚P2.7 \/\/ \/\/温度传感器18B20汇编程序,采用器件默认的12位转化 \/\/ \/\/最大转化时间750微秒,显示温度-55到+125度,显示精度 \/\/ \/\/为0.1度,显示采用4位LED共阳显示测温值 \/\/ \/\/P0口为段码输入,P34~P37为位选 \/\/ \/***\/ include "reg51.h"include...

相似回答