首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

DS18B20温度采集有关问题

2012-03-15 
DS18B20温度采集问题#includereg52.h#define uchar unsigned char#define uintunsigned int#define jump

DS18B20温度采集问题
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define jump_ROM 0xCC //写跳过读ROM指令。因为只对一个DB18B20操作。
#define start 0x44 // 写温度转换指令。
#define read_EEROM 0xBE//读暂存器,读内部RAM中9字节的温度
sbit DQ=P3^4; //DS18B02唯一与单片机连接的 数据端
uchar TMPH ,TMPL; //用于读取高低 8位数据。
uchar code table[20] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09,0x02, 0x9e, 0x24, 0x0c, 0x98, 0x48, 0x40, 0x1e, 0x00, 0x08};// 前10个(0~9
//)为不加小数点的, 后10个(0~9)为加小数点的,
uchar code table1[3]={0x01,0x02,0x04} ; //用于数码管的显示。
/****************************************************************************************

  以下为延时函数,晶振为11.0592的时候,延时一次大约为:16us。
*******************************************************************************************/
void delay(us)
{
  uint s;
  for(s=0;s<us;s++);
}

/******************************************************************************************
  一下为复位函数。resert() 并且读取它的信号。  
  注意:一个delay(1)=16us
********************************************************************************************/
uchar resert(void)
{
  uchar receive_ready;
  DQ=0;
  delay(32) ; //最好延时时间为480us。 本次为32*16=512us。
  DQ=1;
  delay(3); //延时等待。
  receive_ready=DQ; //获取信号。
  delay(25); //等待时间隙 完。 不超过480us,本次为400us。
  return receive_ready; //返回信号
}


/********************************************************************
* 名称 : read_bit()
* 功能 : 从DS18B20读一个位值
* 输入 : 无
* 输出 : 从DS18B20读出的一个位值
***********************************************************************/
uchar read_bit()
{
  uchar i;
DQ=0;
DQ=1;
for(i=0;i<3;i++); //从时间隙开始延时15us。
return DQ; //读出的一个位值返回
}
/********************************************************************
* 名称 : write_bit()
* 功能 : 向DS18B20写一位
* 输入 : bitval(要对DS18B20写入的位值)
* 输出 : 无
***********************************************************************/

void write_bit(bitval)
{
   
  DQ=0; //先把数据位置0,开始时间隙。
  //delay(1); //延时16us。
  if(bitval==1)
  DQ=1;
  delay(5); //在其余的时间隙保持值。
  DQ=1;

}
/********************************************************************
* 名称 : read_byte()
* 功能 : 从DS18B20读一个字节
* 输入 : 无
* 输出 : 从DS18B20读到的值
***********************************************************************/
uchar read_byte()
{
  uchar i;
uchar value=0;
for(i=0;i<8;i++)
{
if(read_bit()) //当read_bit()=0时,value=0; 当 read_bit()=1时,执行 value|=0x01<<i;,value=1。
{
value|=0x01<<i; //按位或|。 有一个为1则为1
 
 
}
delay(6) ; //等待剩下时间隙。

}

return value;

}

/********************************************************************
* 名称 : write_byte()
* 功能 : 向DS18B20写一个字节
* 输入 : val(要对DS18B20写入的命令值)
* 输出 : 无
***********************************************************************/
void write_byte(uchar val)
{
  uchar i,temp;
for(i=0;i<8;i++)
{
 
temp=val>>i;
temp=temp&0x01;
write_bit(temp);
}
delay(5);

}

//***********************数据显示程序**************************************
void display (uchar num ,uchar dat) //num:第几个数码管。 dat是要显示的数字  
{
  //uchar i;
P0=table[dat];
P2=table1[num];
delay(800);//i=0xff;
//i=i&(~((0x01)<<(num)) );
  // P2=i;


  //delay(50);



}

//*********************显示温度数值函数t传递的是整形的温度值**************************
void dis_temp(uint t)
{
  uchar i;
i=t/100; //除以100,得到温度的十位。
display(0,i); //在第一个数码管上面显示。
i=t%100/10; //温度数值的 个位。
display(1,i+10); //在第二个数码管上面显示。
i=t%100%10; //温度数值的 小数部位
display(2,i) ; //在第三个数码管上面显示。
}

//**************获取温度的数值************************************************
uint get_temp()
{
  float f_temp;
  uint temp; 
  P2=0x00;
  // resert(); //通过单总线的所有执行(处理 )都从一个初始化程序开始。其包括总线发出的复位脉冲和{ 从机发出的脉冲。(单机)}
  //write_byte(jump_ROM) ; //jump_ROM= 0xCC, 写跳过读ROM指令。因为只对一个DB18B20操作。
  //write_byte(start); //start 0x44 写温度转换指令。
  //resert();
  write_byte(jump_ROM); // 写跳过读ROM指令。因为只对一个DB18B20操作。
  write_byte(read_EEROM); //read_EEROM =0xBE ,读暂存器,读内部RAM中9字节的温度
  TMPL = read_byte(); //读取低字节的8位数据
  TMPH = read_byte(); //读取低字节的8位数据
  temp = TMPH; //把高位的8字节数据 付给temp。
  temp <<= 8; //两个字节为一个字
  temp = temp | TMPL;
  f_temp=temp*0.0625; //温度在寄存器里面是12位,分辨率为:0.0625。
  temp=f_temp*10+0.5; //扩大10倍为了保存以为小数点。加0.5是为了四舍五入。
  f_temp=f_temp+0.05;
  return temp;

}


//*****************温度转换函数****************************
void tempchange()
{
  resert();
  delay(50);
write_byte(jump_ROM); // 写跳过读ROM指令。因为只对一个DB18B20操作。
write_byte(start); // 写温度转换指令。
  resert();

}

//*****************主函数***********************
void main()[color=#FF0000][/color]
{
  while(1)
  {
  tempchange(); //温度转换函数。
dis_temp(get_temp()) ; // 获取温度并且显示
   
  }

}

这个采集的不准确,温度也不稳定,老是变化,主要问题可能就是数码管显示出问题了恶霸,硬件是对的。

[解决办法]
看看你硬件有没有问题,对于你的程序在检查一下 数据不稳定是很正常的 不过也不至于老是在变化,
[解决办法]
对应的DS18B20的上拉电阻 有吧

对于温度不准确,以及不稳定,很可能你对DS18B20的初始化 还有问题,
很可能你的对应时序 控制不对,比如延时不对。

建议楼主百度或GOOGLE下,找下DS18B20的C程序 参考下。
[解决办法]
好长程序,没时间看,不过ds18b20我还是用过的
[解决办法]
注意:一个delay(1)=16us

这个不对吧。每次调用delay()函数得花多少时间?
[解决办法]
楼主我觉得是时序有问题,
ds18b20对时序要求很严格的

热点排行