请教一个关于DS18B20如何正确读数的问题?
小弟用DS18B20进行温度采集。在室内测量,显示零下四十多度,虽然最近天气比较冷,可也没有这么低呀!当把DS18B20用手握住(或用空调吹一会儿),过一会儿,如果测量到的温度显示》16时时就没问题,这是怎么回事? 从零下40多突然到16,变化也太大了 我估计是你读出的数据没有正确解码。符号位你是怎么处理的?再看一下datasheet里的那张表吧 呵呵,LZ对自己的程序太有自信了,这么相信你的读数啊? 本帖最后由 bmfw 于 2009-11-25 21:35 编辑
附上有关程序,帮我看一下!
//////无符号整数转换为BCD码//////////////////////
uchar IntToBcd(unsigned char Int)
{
uchar i,j;
j=100;
i=0;
while((Int >= j) && (j>9))
{
Int-=j;
i++;
}
j/=10;
i=0;
while((Int >= j) && (j>9))
{
Int-= j;
i++;
}
return((i<<4)|(Int));
}
/////////////////////////////////////////////////
voidGetTemperature(void)
{
uchar TempH = 0;
uchar TempL = 0;
uchar TempSigned= 0;
uchar TempHigh= 0;
uchar TempLow = 0;
DS18B20_IO = 1;
if(DS18B20_Init()) //接收到应答脉冲
{
DS18B20_WriteByte(SkipRom);//0xcc发出SKIP ROM命令
DS18B20_WriteByte(ConvertTemperature);//0x0x44发送温度转换命令
Delay15us(50); //等待AD转换结束
DS18B20_Init();
DS18B20_WriteByte(SkipRom); //0xcc发出SKIP ROM命令
DS18B20_WriteByte(ReadScratchpad);//0xbe发送读命令
TempL = DS18B20_ReadByte(); //读取温度值低位字节(其中低4 位为二进制的"小数"部分)
TempH = DS18B20_ReadByte(); //读取温度值高位字节(其中高5位为符号位)
if (TempH^3==0) { TempSigned = 0;}//温度的符号位,0为正温度,1为负温度
else //负温度
{
TempSigned = 1; //温度的符号位,0为正温度,1为负温度
TempL=256-TempL; //负温度用补码表示,即反码加1
TempH=255-TempH; //也就是255-Temp+1
}
}
//TempH的低四位和TempL的高四位是整数部分,TempL的低四位是小数部分
TempHigh= IntToBcd((TempH<<4)|(TempL>>4));
TempLow = IntToBcd((TempL&0x0f)*625/100);//小数部分*625/100转换成整数
} 温度正负判断好像错了. 昨晚测试了一下,读出的十六进制是正确的,可能是IntToBcd出了问题 本帖最后由 bmfw 于 2009-11-25 21:33 编辑
再次请问一下,为什么我的程序在16度以下不能正确解码16度以上却没有问题?有关程序如下
uchar TAB_IntToBcd[]={
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,};
TempL = DS18B20_ReadByte();//读取温度值低位字节(其中低4 位为二进制的"小数"部分)
TempH = DS18B20_ReadByte();//读取温度值高位字节(其中高5位为符号位)
if (TempH^3==0) //正温度
{
TemSigned = 0x00; //温度的符号位,0为正温度,1为负温度
}
else //负温度
{
TemSigned = 0x01;
TempL=256-TempL; //负温度用补码表示,即反码加1
TempH=255-TempH; //也就是255-Temp+1
}
//TempH的低四位和TempL的高四位是整数部分,TempL的低四位是小数部分
TemHigh= TAB_IntToBcd[(TempH<<4)|(TempL>>4)];
TemLow = TAB_IntToBcd[(TempL&0x0f)*625/100];//小数部分*625/100转换成整数 我写了个在0到16度能正常测温,16度以上就跳到0了,我知道是高温数据没读到,但程序还没找到问题 能把有关程序附上吗? 汇编的源程序要嘛 回去仔细读手册
DS1820很成熟
绝对没有问题
你自己完全可以搞定,你行的 DS18b20.c
#include "DS18b20.h"
#include "myfun.h"
/*******************************************************
+-------------------------------------+
|振南电子 驱动程序模块 DS18B20 部分 |
+-------------------------------------+
此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
严禁随意用于商业目的,违者必究,后果自负
振南电子
->产品网站 http://www.znmcu.cn/
->产品网店 http://shop.znmcu.cn/
->产品咨询 QQ:987582714
MSN:yzn07@126.com
WW:yzn07
********************************************************/
/******************************************************************
- 功能描述:DS18B20初始化
- 隶属模块:DS18B20模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:返回值为0说明初始化成功,否则失败
- 注:初始化是正确操作DS18B20是重要一步,必须初始化成功
******************************************************************/
unsigned char DS18B20_Init()
{
unsigned char x=0;
DQ=1; //DQ复位
delay(96);//稍做延时
DQ=0; //单片机将DQ拉低
delay(960); //精确延时 大于 480us
DQ=1; //拉高总线
delay(168);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(240);
return x;
}
/******************************************************************
- 功能描述:从DS18B20读取一个字节
- 隶属模块:DS18B20模块
- 函数属性:内部
- 参数说明:无
- 返回说明:从DS18B20读到的字节
- 注:无
******************************************************************/
unsigned char DS18B20_ReadByte()
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
DQ=0; //给脉冲信号
dat>>=1;
DQ = 1;//给脉冲信号
if(DQ) dat|=0x80;
delay(48);
}
return(dat);
}
/******************************************************************
- 功能描述:向DS18B20写入一个字节
- 隶属模块:DS18B20模块
- 函数属性:内部
- 参数说明:dat:将要向DS18B20写入字节
- 返回说明:无
- 注:无
******************************************************************/
void DS18B20_WriteByte(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0x01;
delay(60);
DQ=1;
dat>>=1;
}
}
/******************************************************************
- 功能描述:从DS18B20中读取温度
- 隶属模块:DS18B20模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:由于返回的温度是浮点数(即小数),为了方便返回的值将为原
值的100倍,即精确到小数点后2位,用户需要对返回值除以100
得到实际的温度值
- 注:这里读取温度是以DS18B20的最高精度来读取的,即12位
******************************************************************/
unsigned int DS18B20_ReadTemperature()
{
unsigned int t=0;
DS18B20_Init();
DS18B20_WriteByte(0xcc); // 跳过读序号列号的操作
DS18B20_WriteByte(0x44); // 启动温度转换
DS18B20_Init();
DS18B20_WriteByte(0xcc); //跳过读序号列号的操作
DS18B20_WriteByte(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
((unsigned char *)&t)=DS18B20_ReadByte();
((unsigned char *)&t)=DS18B20_ReadByte();
return (t!=1360)?(t*6.25):0; //DS18B20有一个常见的问题,即所谓的85问题
//刚上电时可能读回的温度值是85,这是错误的值,应舍弃
}
DS18b20.h
#ifndef_DS18B20_H_
#define_DS18B20_H_
#include "reg51.h"
/*******************************************************
+-------------------------------------+
|振南电子 驱动程序模块 DS18B20 部分 |
+-------------------------------------+
此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
严禁随意用于商业目的,违者必究,后果自负
振南电子
->产品网站 http://www.znmcu.cn/
->产品网店 http://shop.znmcu.cn/
->产品咨询 QQ:987582714
MSN:yzn07@126.com
WW:yzn07
********************************************************/
sbit DQ=P1^4; //DS18B20的数据端
unsigned char DS18B20_Init();
unsigned char DS18B20_ReadByte();
void DS18B20_WriteByte(unsigned char dat);
unsigned int DS18B20_ReadTemperature();
#endif
可选用成品,我们专门研发了一线总线采集模块LCT2662M,还有仪表LCT2201C,可以采集常用的一线总线器件ds18b20,还有模拟量ds2438等。支持64个ds18b20同时采集。输出rs485总线,便于和电脑等终端通讯,常用于粮库粮仓测温,煤筒仓测温,水蓄冷测温等等。
https://bbs.21ic.com/data/attachment/forum/201909/27/224119qh33pe2hzyzm0meh.jpg.thumb.jpg https://bbs.21ic.com/data/attachment/forum/201909/27/224418kc1qznvvuvnc619r.jpg.thumb.jpg
https://bbs.21ic.com/data/attachment/forum/201909/27/224505i0i55yd0zh99ipq6.jpg.thumb.jpg
页:
[1]