ds18b20 如何读取数据?

比如说读暂存器字节0与字节1(读转换好的数据),是发送一个指令后,18b20一直不停输出那些数据,还是每次需要我给它一个信号说:我要读下一个位了。它才把下一位输出来?PS... 比如说读暂存器字节0与字节1(读转换好的数据),是发送一个指令后,18b20一直不停输出那些数据,还是每次需要我给它一个信号说:我要读下一个位了。它才把下一位输出来?

PS:资料上木有写啊,我感觉应该是给信号才会输出的,否则误差无限大啊!
展开
 我来答
生活知识小超人
高粉答主

2020-05-22 · 醉心答题,欢迎关注
知道答主
回答量:2078
采纳率:50%
帮助的人:89.6万
展开全部

1、首先双击电脑中的proteus软件,然后点击左侧的“P”按钮,如图。

2、接着找到“关键字”输入框,如图。

3、输入“DS18B20”,在列表中选择它,如图,最后点击“确定”。

4、紧接着在图纸中点击左键,此时出现一个DS18B20的虚影,如图。

5、拖动DS18B20虚影到图纸的合适位置,再次点击左键,如图,这样一个DS18b20就绘制完成了。

zhxiufan
推荐于2017-09-28 · 知道合伙人软件行家
zhxiufan
知道合伙人软件行家
采纳数:14923 获赞数:38381
国家科技进步奖

向TA提问 私信TA
展开全部

DS18B20是温度传感器,读写数据有一定的时序:

1、写操作

(1) 数据线先置低电平“0”。

(2) 延时确定的时间为15微秒。

(3) 按从低位到高位的顺序发送字节(一次只发送一位)。

(4) 延时时间为45微秒。

(5) 将数据线拉到高电平。

(6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。

(7) 最后将数据线拉高。

2、读操作

(1)将数据线拉高“1”。

(2)延时2微秒。

(3)将数据线拉低“0”。

(4)延时3微秒。

(5)将数据线拉高“1”。

(6)延时5微秒。

(7)读数据线的状态得到1个状态位,并进行数据处理。

(8)延时60微秒。

3、例程

//温度传感器:DS18B20

//显示方式:LED

#include <reg51.h>

#define uchar unsigned char

sbit keyup=P1^0;

sbit keydn=P1^1;

sbit keymd=P1^2;

sbit out=P3^7; //接控制继电器

sbit DQ = P3^4; //接温度传感器18B20

uchar t[2],number=0,*pt; //温度值

uchar  TempBuffer1[4]={0,0,0,0};

uchar Tmax=18,Tmin=8;

uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xf7};

uchar dismod=0,xiaodou1=0,xiaodou2=0,currtemp;

bit flag;

void t0isr() interrupt 1

{

TH0=(65536-5000)/256;

TL0=(65536-5000)%256;

switch(number)

{

case 0:

   P2=0x08;

     P0=distab[TempBuffer1[0]];

     break;

case 1:

   P2=0x04;

     P0=distab[TempBuffer1[1]];

     break;

case 2:

   P2=0x02;

     P0=distab[TempBuffer1[2]]&0x7f;

     break;

case 3:

   P2=0x01;

     P0=distab[TempBuffer1[3]];

     break;

default:

   break;

}

number++;

if(number>3)number=0;

}


void delay_18B20(unsigned int i)

{

while(i--);

}


/**********ds18b20初始化函数**********************/


void Init_DS18B20(void) 

{

bit x=0;

do{

DQ=1;

delay_18B20(8);

DQ = 0;          //单片机将DQ拉低

delay_18B20(90); //精确延时 大于 480us

DQ = 1;          //拉高总线

delay_18B20(14);

x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败,继续初始化

}while(x);

delay_18B20(20);

}


/***********ds18b20读一个字节**************/  


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_18B20(4);

}

  return(dat);

}


/*************ds18b20写一个字节****************/  


void WriteOneChar(unsigned char dat)

{

  unsigned char i=0;

  for (i=8; i>0; i--)

  {

  DQ = 0;

  DQ = dat&0x01;

    delay_18B20(5);

  DQ = 1;

    dat>>=1;

}

}


/**************读取ds18b20当前温度************/


unsigned char *ReadTemperature(unsigned char rs)

{

unsigned char tt[2];

  delay_18B20(80);  

Init_DS18B20();

WriteOneChar(0xCC);   //跳过读序号列号的操作

WriteOneChar(0x44); //启动温度转换

  delay_18B20(80);  

Init_DS18B20();

WriteOneChar(0xCC); //跳过读序号列号的操作

WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度

tt[0]=ReadOneChar();  //读取温度值低位

tt[1]=ReadOneChar();  //读取温度值高位

return(tt);

}


void covert1(void) //将温度转换为LED显示的数据

{

   uchar x=0x00,y=0x00;

   t[0]=*pt;

   pt++;

   t[1]=*pt;

   if(t[1]&0x080)      //判断正负温度

   {

    TempBuffer1[0]=0x0c;     //c代表负

t[1]=~t[1]; /*下面几句把负数的补码*/

t[0]=~t[0]; /*换算成绝对值*********/

x=t[0]+1;

t[0]=x;

if(x==0x00)t[1]++;

   }

  else TempBuffer1[0]=0x0a; //A代表正

  t[1]<<=4; //将高字节左移4位

  t[1]=t[1]&0xf0;

  x=t[0]; //将t[0]暂存到X,因为取小数部分还要用到它

  x>>=4; //右移4位

  x=x&0x0f; //和前面两句就是取出t[0]的高四位

  y=t[1]|x; //将高低字节的有效值的整数部分拼成一个字节

  TempBuffer1[1]=(y%100)/10;

  TempBuffer1[2]=(y%100)%10;

  t[0]=t[0]&0x0f; //小数部分

  TempBuffer1[3]=t[0]*10/16;

//以下程序段消去随机误检查造成的误判,只有连续12次检测到温度超出限制才切换加热装置

if(currtemp>Tmin)xiaodou1=0;

if(y<Tmin)

{

xiaodou1++;

currtemp=y;

xiaodou2=0;

}

if(xiaodou1>12)

{

out=0;

flag=1;

xiaodou1=0;

}

if(currtemp<Tmax)xiaodou2=0;

if(y>Tmax)

{

xiaodou2++;

currtemp=y;

xiaodou1=0;

}

if(xiaodou2>12)

{

out=1;

flag=0;

xiaodou2=0;

}

out=flag;

}

void convert(char tmp)

{

uchar a;

if(tmp<0)

{

TempBuffer1[0]=0x0c;

a=~tmp+1;

}

else 

{

TempBuffer1[0]=0x0a;

a=tmp;

}

TempBuffer1[1]=(a%100)/10;

TempBuffer1[2]=(a%100)%10;

}

void keyscan( )

{

uchar keyin;

keyin=P1&0x07;

if(keyin==0x07)return;

else if(keymd==0)

{

dismod++;

dismod%=3;

while(keymd==0);

switch(dismod)

{

case 1:

   convert(Tmax);

     TempBuffer1[3]=0x11;

     break;

case 2:

   convert(Tmin);

     TempBuffer1[3]=0x12;

     break;

default:

   break;

}

}

else if((keyup==0)&&(dismod==1))

{

Tmax++;

convert(Tmax);

while(keyup==0);

}

else if((keydn==0)&&(dismod==1))

{

Tmax--;

convert(Tmax);

while(keydn==0);

}

else if((keyup==0)&&(dismod==2))

{

Tmin++;

convert(Tmin);

while(keyup==0);

}

else if((keydn==0)&&(dismod==2))

{

Tmin--;

convert(Tmin);

while(keydn==0);

}

xiaodou1=0;

xiaodou2=0;

}

main()

{

TMOD=0x01;

TH0=(65536-5000)/256;

TL0=(65536-5000)%256;

TR0=1;

ET0=1;

EA=1;

out=1;

flag=0;

ReadTemperature(0x3f);

  delay_18B20(50000); //延时等待18B20数据稳定  

 while(1)

{

pt=ReadTemperature(0x7f); //读取温度,温度值存放在一个两个字节的数组中

if(dismod==0)covert1();

keyscan();

delay_18B20(30000);

}

}


已赞过 已踩过<
你对这个回答的评价是?
评论 收起
申滔
2012-10-21 · 超过14用户采纳过TA的回答
知道答主
回答量:96
采纳率:0%
帮助的人:43.2万
展开全部
好好研究一下数据手册。重点是它的通信协议。你只要按照数据手册上写的通信协议给18B20发送指令就可以了。使用18B20一定要根据你的晶振精确控制好延时。还有就是数据线上要加一个10K左右的上拉电阻。我觉得和使用其它芯片差不多,只是通信协议略有不同。
误差无限大我不知道你指的是什么?这个是数字芯片,得到的直接就是数字信号了。得到的数字乘以分辨率0.0625就是温度了。读18B20不要太频繁,太频繁芯片容易升温,测得的温度偏高。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式