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对时序要求很严格的