DS18B20测温C程序:数码管显示不随温度变化,且不正确,求高手解答,万分感谢!(单片机复位后仍为同数值

C51单片机,12MHZ晶振
#include<reg52.h>
#include <intrins.h>

sbit DQ=P3^7;
sbit led0=P1^3;
sbit led1=P1^2;
sbit led2=P1^1;
sbit led3=P1^0;

typedef unsigned char uchar;
typedef unsigned int uint;
#define NOP() _nop_()

uchar T_data[2]={0x00,0x00},dis[6]={0};
uchar seg[10]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
uchar seg1[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//数码管段码

void delay(uint t)//11*t+17us延时,12MHZ晶振时
{
int s;
for(s=0;s<t;s++);
}

uchar reset(void)//复位
{
uchar presence;
DQ=1;
_nop_();
DQ=0;
delay(50);//570us
DQ=1;
delay(5);//72us
presence=DQ;
delay(40);//450us
DQ=1;
return(presence);
}

uchar read_bit(void)//读位
{
uchar i,b;
DQ=0;
_nop_();
DQ=1;
for(i=0;i<3;i++);//延时11us
b=DQ;
delay(4);//60us
return(b);
}

void write_bit(char bitval)//写位
{
DQ=0;
_nop_();
DQ=bitval&0x01;
delay(4);//60us
DQ=1;
}

uchar read_byte(void)//读字节
{
uchar i;
uchar value=0;
for(i=0;i<8;i++)
{
if(read_bit()) value|=(0x01<<i);
}
return(value);
}

void write_byte(uchar val)//写字节
{
uchar i;
uchar temp;
for(i=0;i<8;i++)
{
temp=((val>>i)&0x01);
write_bit(temp);
}
}

void read_T_data()//读温度
{
while(reset());
write_byte(0xCC);
write_byte(0x44);
while(reset());
write_byte(0xCC);
write_byte(0xBE);
T_data[0]=read_byte;
T_data[1]=read_byte;
}

void work_T_data()//温度处理
{
uchar n=0;
if(T_data[1]>127)
{
T_data[1]=256-T_data[1];
T_data[0]=256-T_data[0];
n=1;
}
dis[5]=((T_data[1]&0x0F)<<4)|((T_data[0]&0xF0)>>4);//整数部分
dis[4]=dis[5]/100;//百位
dis[3]=dis[5]%100;
dis[2]=dis[3]/10;//十位
dis[1]=dis[3]%10;//个位
switch (T_data[0]&0x0f) //小数位
{
case 0x0f:dis[0]=9;break;
case 0x0e:dis[0]=9;break;
case 0x0d:dis[0]=8;break;
case 0x0c:dis[0]=8;break;
case 0x0b:dis[0]=7;break;
case 0x0a:dis[0]=6;break;
case 0x09:dis[0]=6;break;
case 0x08:dis[0]=5;break;
case 0x07:dis[0]=4;break;
case 0x06:dis[0]=4;break;
case 0x05:dis[0]=3;break;
case 0x04:dis[0]=3;break;
case 0x03:dis[0]=2;break;
case 0x02:dis[0]=1;break;
case 0x01:dis[0]=1;break;
case 0x00:dis[0]=0;break;
default:break;
}
}

void display()//温度显示
{
P2=0x39;
led0=0;
delay(40);
led0=1;
P2=seg[dis[0]];
led1=0;
delay(40);
led1=1;
P2=seg1[dis[1]];
led2=0;
delay(40);
led2=1;
P2=seg[dis[2]];
led3=0;
delay(40);
led3=1;
}

void main()
{
uchar i=0;
while(reset());
write_byte(0xCC);
write_byte(0x44);
while(1)
{
if(i==100)
{
i=0;
read_T_data();
work_T_data();
}
i++;
display();
}
}
我想知道自己这个程序问题的所在,希望高手最好能把这个程序硬件试验一下,再次感谢!(调整了好多次,唯一有的变化就是显示数值较先前一个程序发生了变化,但仍然不随温度改变,即仍为定值)

在mian函数while(reset())的下一行加上DQ=1;(拉高电平)。追问

reset()函数最后我已经拉高了电平,而且经过测试,加上之后,还是不成功

追答

又发现两处,你改了后再试试.
1:少了存在脉冲判断
void read_T_data()//读温度
{
while(reset());
delay(200); //存在脉冲
write_byte(0xCC);
write_byte(0x44);
while(reset());
delay(1); //存在脉冲
write_byte(0xCC);
write_byte(0xBE);
T_data[0]=read_byte;
T_data[1]=read_byte;
}
2:负温度时的处理
if(T_data[1]>125) //高字节为高5位为1时,温度为负。0000 0111 1111 0000 取 125
{ T_data[1]=255-T_data[1]; //低字节向高字节借了一位,256要减去1
T_data[0]=256-T_data[0];
}

看下这个网页的18B20的说明文档,可能你会有收获:
http://wenku.baidu.com/view/acf0412e453610661ed9f4d6.html 17页
http://wenku.baidu.com/view/d92d3ec75fbfc77da269b1c1.html 18页

追问

还是不行,存在脉冲其实我也已经加在reset函数中了,delay(5)+delay(40)的时间已经大于480us
至于负温度的处理,我没有多加考虑,因为温度是零上,应该不是主要问题的所在
还是说声谢谢!

温馨提示:内容为网友见解,仅供参考
第1个回答  2011-02-24
不知道你的硬件是怎么连的,如果烧过好的程序没问题的话,那还是你的程序有问题,这个显示函数应该有一个选择位的,先选中第一个数码管,然后让它显示相映位的数字,然后再选中第二个数码管,让它显示相映的数字,再选择第三个数码管,让他显示相映的数。没看明白你那led1、2、3是什么意思。追问

led是位选,seg是段选,数码管这块是不会错的

第2个回答  2011-02-24
你是在proteus中仿真还是实际硬件调试?最好将原理图贴出来看看。追问

硬件调试,而且用一个正确的测温程序试验时可以成功

DS18B20测温C程序:数码管显示不随温度变化,且不正确,求高手解答,万分感 ...
在mian函数while(reset())的下一行加上DQ=1;(拉高电平)。

...老是显示0.1“c,且不正确,求高手解答,万分感谢!
这个问题我也曾经出现过,显示的温度不变,我的是因为取了温度以后对温度×100的算法不对,比如28度,算的时候先×100变成2800,然后再通过取余什么的得到十位、个位等数。就是在计算实际温度的那个地方错了,你看看温度换算那里吧,一般取温程序不会有错。

DS18B20程序,keil c编译报错error C208: 'ReadDs': too many actual p...
Reads函数的实体中是没有参数的,而你在调用时传入了参数,所以编译报错。应该是你的实体有问题吧,一般都有参数的。

相似回答
大家正在搜