温度传感器DS18B20的读写一个字节的子程序

作者&投稿:张垂 (若有异议请与网页底部的电邮联系)
最近在学51单片机的温度传感器DS18B20,其中有读字节和写字节函数,我想问的是读的具体含义是什么?~

就是用DQ这条总线上读或者写入数据8次 这样就一个DQ控制口代替了8个 懂么 简单的说给DS18b20发送相应的一个字节命令(8位) 然后18b20读出2字节的数据 然后这个数据转换下 就是温度 这个懂了吧

单总线通信....对DS18B20的操作分为3个步骤:初始化,ROM命令和DS18B20功能命令。

读取的时候先 初始化,然后写ROM命令(CC 跳过ROM),然后在写(BE 这个是读取RAM命令,可以看DS18b20的资料有)..然后才在读取温度

/***********ds18b20读一个字节**************/
unsigned char ReadOneChar(void)
{
uchar i=0; //定义i用于循环
uchar dat = 0; //读取的8位数据
for (i=8;i>0;i--) //8次循环
{
DQ = 0; //拉低DQ总线开始读时序
dat>>=1; //dat左移一位
DQ = 1; //释放DQ总线
if(DQ) //如果DQ=1,执dat|=0x80;(0x80即第7位为1,如果DQ为1,即读取的数据为1,将dat的第7为置1,然后dat>>=1,循环8次结束,dat即为读取的数据)
//DQ=0,就跳过
dat|=0x80;
delay_18B20(4); // 延时以完成此次读时 序,之后再读下一数据
}
return(dat); //返回读取的dat
}

DQ = dat&0x01;这句语句是错误的。DQ为位变量,而dat为 unsigned char
如果真要这么写的话,应该是这样 :DQ = (bit)dat&0x01;

把我写的给你做个参考吧:
extern uchar8 sig; //sig判定温度符号
/*延时函数*/
void delay (int us) //DELAY-11.0592MHZ 调用程序大约为24us,每次循环为16us
{
int s;
for(s=0;s<us;s++);
}

void delayms(int z) //z为毫秒数
{
int x,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);
}

/*复位程序*/
unsigned char reset(void)
{
uchar8 presence;
DQ=0; //拉低总线。当总线停留在低电平480us-960us ,总线上所以器件都将被复位
delay(30); //保持低电平504us
DQ=1; //释放总线,让其恢复高电平
delay(3); //等待芯片应答信号
presence=DQ; //获取应答信号
delay(25); //延时以完成整个时序
return(presence); //返回应答信号。有芯片应答返回0,否则返回1。
}

/*写一位数据*/
void write_bit(char bitval)
{
DQ=0; //拉低DQ总线,开始时序
if(bitval==1) //如果写入的为1,则返回高电平
DQ=1;
delay(5); //延时104us,以完成整个时序
DQ=1;
}

/*写一字节数据*/
void write_byte(char val)
{
uchar8 i,temp;
for (i=0;i<8;i++) //写入一个字节的数据,一个时序中写一次
{
temp=val>>i; //右移i位
temp&=0x01; //复制那位数据到temp
write_bit(temp); //调用write_bit()
}
delay(5); //延时104us以完成此次时序,之后再写下一数据
}

/*读一位数据*/
uchar8 read_bit(void)
{
uchar8 i;
DQ=0; //拉低DQ,开始读时序
DQ=1; //释放DQ总线
for(i=0;i<3;i++); //从时序开始延时15us
return(DQ); //返回DQ值
}

/*读一字节数据*/
uchar8 read_byte(void)
{
uchar8 i,value=0;
for(i=0;i<8;i++)
{
if(read_bit()) //读一字节数据,一个时序中读一次,并作移位处理
value|=0x01<<i;
delay(6); //延时以完成此次读时序,之后再读下一数据
}
return(value);
}

/*温度转化*/
void tmconvert(void)
{
reset(); //复位
delay(1);
write_byte(0xcc); //仅一个DS18b20 ,跳过ROM
write_byte(0x44); //温度变换
}

/*读取温度*/
long gettm(void)
{
uchar8 LSB=0,MSB=0; //用于存储读取的温度

long temp;
reset(); //复位
write_byte(0xcc); //写指令,跳过ROM,仅一个DS18b20
write_byte(0xbe); //写指令,读暂存存储器
LSB = read_byte(); //读LSB
MSB = read_byte(); //读MSB
sig=(MSB>>4==0X0F);
if(sig) //判断符号位是否为负值,是负值了,转去处理
{
LSB=~LSB; //温度处理
MSB=~MSB;
LSB=LSB+1;
}
temp=MSB*256+LSB; //十六进制转换为10进制
temp=temp*100/16; //12位精度,最小分辨率为0.0625°C
return temp; //获得0.01°C 的精度并返回
}

/***********ds18b20读一个字节**************/
unsignedcharReadOneChar(void)
{
uchari=0;//定义i用于循环
uchardat=0;//读取的8位数据
for(i=8;i>0;i--)//8次循环
{
DQ=0;//拉低DQ总线开始读时序
dat>>=1;//dat左移一位
DQ=1;//释放DQ总线
if(DQ)//如果DQ=1,执dat|=0x80;(0x80即第7位为1,如果DQ为1,即读取的数据为1,将dat的第7为置1,然后dat>>=1,循环8次结束,dat即为读取的数据)
//DQ=0,就跳过
dat|=0x80;
delay_18B20(4);//延时以完成此次读时序,之后再读下一数据
}
return(dat);//返回读取的dat
}
DQ=dat&0x01;这句语句是错误的。DQ为位变量,而dat为unsignedchar
如果真要这么写的话,应该是这样:DQ=(bit)dat&0x01;
把我写的给你做个参考吧:
externuchar8sig;//sig判定温度符号
/*延时函数*/
voiddelay(intus)//DELAY-11.0592MHZ调用程序大约为24us,每次循环为16us
{
ints;
for(s=0;s<us;s++);
}
voiddelayms(intz)//z为毫秒数
{
intx,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);
}
/*复位程序*/
unsignedcharreset(void)
{
uchar8presence;
DQ=0;//拉低总线。当总线停留在低电平480us-960us,总线上所以器件都将被复位
delay(30);//保持低电平504us
DQ=1;//释放总线,让其恢复高电平
delay(3);//等待芯片应答信号
presence=DQ;//获取应答信号
delay(25);//延时以完成整个时序
return(presence);//返回应答信号。有芯片应答返回0,否则返回1。
}
/*写一位数据*/
voidwrite_bit(charbitval)
{
DQ=0;//拉低DQ总线,开始时序
if(bitval==1)//如果写入的为1,则返回高电平
DQ=1;
delay(5);//延时104us,以完成整个时序
DQ=1;
}
/*写一字节数据*/
voidwrite_byte(charval)
{
uchar8i,temp;
for(i=0;i<8;i++)//写入一个字节的数据,一个时序中写一次
{
temp=val>>i;//右移i位
temp&=0x01;//复制那位数据到temp
write_bit(temp);//调用write_bit()
}
delay(5);//延时104us以完成此次时序,之后再写下一数据
}
/*读一位数据*/
uchar8read_bit(void)
{
uchar8i;
DQ=0;//拉低DQ,开始读时序
DQ=1;//释放DQ总线
for(i=0;i<3;i++);//从时序开始延时15us
return(DQ);//返回DQ值
}
/*读一字节数据*/
uchar8read_byte(void)
{
uchar8i,value=0;
for(i=0;i<8;i++)
{
if(read_bit())//读一字节数据,一个时序中读一次,并作移位处理
value|=0x01<<i;
delay(6);//延时以完成此次读时序,之后再读下一数据
}
return(value);
}
/*温度转化*/
voidtmconvert(void)
{
reset();//复位
delay(1);
write_byte(0xcc);//仅一个DS18b20,跳过ROM
write_byte(0x44);//温度变换
}
/*读取温度*/
longgettm(void)
{
uchar8LSB=0,MSB=0;//用于存储读取的温度
longtemp;
reset();//复位
write_byte(0xcc);//写指令,跳过ROM,仅一个DS18b20
write_byte(0xbe);//写指令,读暂存存储器
LSB=read_byte();//读LSB
MSB=read_byte();//读MSB
sig=(MSB>>4==0X0F);
if(sig)//判断符号位是否为负值,是负值了,转去处理
{
LSB=~LSB;//温度处理
MSB=~MSB;
LSB=LSB+1;
}
temp=MSB*256+LSB;//十六进制转换为10进制
temp=temp*100/16;//12位精度,最小分辨率为0.0625°C
returntemp;//获得0.01°C的精度并返回
}

温度传感器ds18b20为什么读温度会出现0x80?也就是负零度
答:有可能是读数据的时间没选择好

做过DS18B20温度采集的请help me
答:MOV A,#44H :发出温度转换命令 LCALL WRITE— — 1820 LCALL DISPLAY LCALL INIT 一1820 :准备读温度前先复位 MOV A,#OCCH :跳过ROM匹配 LCALL WRITE l820 MOV A,#OBEH :发出读温度命令 LCALL WRITE 1820 LCALL READ 一18200 :将读出的温度数据保存到 28H/29H RET :写DS18B20的子...

这是C51单片机DS18B20读数据的一个函数,请问dat变量在这里面是什么意思...
答:在上面提供的程序中,dat是一个8位元(8bit)的临时变量。它的作用就像一个装东西的容器,不但能装东西,还能顺序排列和移动里面装的东西。下面截图展示了每次执行for循环语句dat变量里面存储的bit变化情况:显然,dat完成了装载8位DQ值的任务(每一位DQ的值不是0就是1),也就是读取了一个完整的...

DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量...
答:/***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写一个字节***/ vo...

关于DS18B20温度读取,要求用LABVIEW做数字温度传感器,我用DS18B20,请问...
答:可以用labview实现。但是后端需要采集系统,不用单片机。采集系统构成LCT2520+LCT2662M+ds18b20(最好封装过),然后就可以用labview写串口程序就可以实现温度读取了。

ds18b20测温
答:首先,如果你要使用12864液晶显示温度的话,请保证你本身的液晶显示程序没有问题,这个可以通过让他随便显示一个数据或字符得到验证。假设本省液晶显示程序没有问题,那十有八九的问题就出在ds18B20温度传感器的程序上,应该是你的ds18b20温度传感器本身就没有工作,也就是说你的f_temp一直就是默认的值0,...

STC11F32XE-51单片机读取DS18B20温度传感器,为何有时读到温度字节是FFH...
答:可能是延迟时间不合适,没有允许读造成的。

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

求AT89C51单片机和DS18B20温度程序,用四位共阳数码管显示
答://DS18B20的读写程序,数据脚P3.3 // //温度传感器18B20汇编程序,采用器件默认的12位转化 // //最大转化时间750微秒,显示温度-55到+125度,显示精度 // //为0.1度,显示采用4位LED共阳显示测温值 // //P0口为段码输入,P24~P27为位选 // /***/ include "reg51.h"include...

寻求一个用12864液晶显示DS18B20温度传感器的C程序。
答://并行连接,PSB引脚接电源正 include <reg51.h> include <intrins.h> define uint unsigned int define uchar unsigned char sbit rs=P2^0; /*数据\指令 选择*/ sbit rw=P2^1; /*读\写 选择*/ sbit e=P2^2; /*读\写使能*/ sbit ds=P3^2; //18B20脚 uint temp;float...