关于51单片机读取DS18B20温度采集系统,并将读取到的数据传输到数码管上;我们书写的程序总是读取到-000.06的状况,给出以下解决办法。

Posted weixin_49302432

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于51单片机读取DS18B20温度采集系统,并将读取到的数据传输到数码管上;我们书写的程序总是读取到-000.06的状况,给出以下解决办法。相关的知识,希望对你有一定的参考价值。

关于51单片机读取DS18B20温度采集系统,并将读取到的数据传输到数码管上;我们书写的程序总是读取到-000.06的状况,给出以下解决办法。

问题所在


错误源代码为

/*******************************************************************************
* 函 数 名         : Ds18b20Init
* 函数功能		   : 初始化
* 输    入         : 无
* 输    出         : 初始化成功返回1,失败返回0
*******************************************************************************/
u8 Ds18b20Init()

	u8 i=0;
	DSPORT = 1;	
	delay6us();
	DSPORT = 0;			 //将总线拉低480us~960us
	delay500us();
	DSPORT = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	i = 0;
	while(DSPORT)	//等待DS18B20拉低总线
	
		delay80us();
		i++;
		if(i>5)//等待>5MS
		
			return 0;//初始化失败
			
	
	return 1;//初始化成功

通过我的对比、观察,最后得到的是DS18B20程序的初始化程序有问题,
问题是:上文程序DS18B20在将 DSPORT 数据位拉低后, 未将 DSPORT 数据位拉高;
因此我将初始化程序进行了修改,修改后的程序就是下文的程序

正确源代码

/*******************************************************************************
* 函 数 名         : Ds18b20Init
* 函数功能		   : 初始化
* 输    入         : 无
* 输    出         : 初始化成功返回1,失败返回0
*******************************************************************************/
u8 Ds18b20Init()

	u8 i=0;
	DSPORT = 1;	
	delay6us();
	DSPORT = 0;			 //将总线拉低480us~960us
	delay500us();
	DSPORT = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	i = 0;
	while(DSPORT)	//等待DS18B20拉低总线
	
		delay80us();
		i++;
		if(i>5)//等待>5MS
		
			return 0;//初始化失败
			
	
	DSPORT = 1;	
	return 1;//初始化成功

程序源码

下面我就将程序的源码展示给大家,以便大家阅读和解决问题;本程序分为两个模块,一个是DS18B20的读取模块,另一个是8位数码管的显示模块;

temp.c文件的程序

#include<temp.h>
#include <intrins.h>
/*******************************************************************************
* 函 数 名         : Delay1ms
* 函数功能		   : 延时函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Delay1ms(u16 y)

	u16 x;
	for( ; y>0; y--)
	
		for(x=110; x>0; x--);
	

void delay500us(void)   //误差 0us

    unsigned char a,b;
    for(b=71;b>0;b--)
        for(a=2;a>0;a--);

void delay80us(void)   //误差 0us

    unsigned char a,b;
    for(b=11;b>0;b--)
        for(a=2;a>0;a--);

void delay48us(void)   //误差 0us

    unsigned char a,b;
    for(b=9;b>0;b--)
        for(a=1;a>0;a--);

void delay6us(void)   //误差 0us

    unsigned char a;
    for(a=1;a>0;a--);
    _nop_();  

/*******************************************************************************
* 函 数 名         : Ds18b20Init
* 函数功能		   : 初始化
* 输    入         : 无
* 输    出         : 初始化成功返回1,失败返回0
*******************************************************************************/
u8 Ds18b20Init()

	u8 i=0;
	DSPORT = 1;	
	delay6us();
	DSPORT = 0;			 //将总线拉低480us~960us
	delay500us();
	DSPORT = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	i = 0;
	while(DSPORT)	//等待DS18B20拉低总线
	
		delay80us();
		i++;
		if(i>5)//等待>5MS
		
			return 0;//初始化失败
			
	
	DSPORT = 1;	
	return 1;//初始化成功

/*******************************************************************************
* 函 数 名         : Ds18b20WriteByte
* 函数功能		   : 向18B20写入一个字节
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Ds18b20WriteByte(u8 dat)

	u16 i, j;
	for(j=0; j<8; j++)
	
		DSPORT = 0;	     	  //每写入一位数据之前先把总线拉低1us
		i++;                 //表示延迟1us
		DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始
		delay80us();
		DSPORT = 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		dat >>= 1;
	

/*******************************************************************************
* 函 数 名         : Ds18b20ReadByte
* 函数功能		   : 读取一个字节
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
u8 Ds18b20ReadByte()

	u8 byte, bi;
	u16 i, j;	
	for(j=8; j>0; j--)
	
		DSPORT = 0;//先将总线拉低1us
		i++;
		DSPORT = 1;//然后释放总线
		delay6us();
		bi = DSPORT;	 //读取数据,从最低位开始读取
		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
		byte = (byte >> 1) | (bi << 7);						  
		delay48us();
		DSPORT = 1;
					
	return byte;

/*******************************************************************************
* 函 数 名         : Ds18b20ChangTemp
* 函数功能		   : 让18b20开始转换温度
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void  Ds18b20ChangTemp()

	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
	Ds18b20WriteByte(0x44);	    //温度转换命令 

/*******************************************************************************
 1. 函 数 名         : Ds18b20ReadTempCom
 2. 函数功能		   : 发送读取温度命令
 3. 输    入         : 无
 4. 输    出         : 无
*******************************************************************************/
void  Ds18b20ReadTempCom()
	

	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
	Ds18b20WriteByte(0xbe);	 //发送读取温度命令

/*******************************************************************************
 5. 函 数 名         : Ds18b20ReadTemp
 6. 函数功能		   : 读取温度
 7. 输    入         : 无
 8. 输    出         : 无
*******************************************************************************/
int Ds18b20ReadTemp()

	int temp = 0;
	u8 tmh, tml;
	Ds18b20ChangTemp();			 	//先写入转换命令
	Ds18b20ReadTempCom();			//然后等待转换完后发送读取温度命令
	tml = Ds18b20ReadByte();		//读取温度值共16位,先读低字节
	tmh = Ds18b20ReadByte();		//再读高字节
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;

temp.h文件的数据

#include"reg51.h"

#define u16 unsigned int
#define u8 unsigned char	
	
sbit DSPORT=P3^7;

void Delay1ms(u16 y);
void delay500us(void);
void delay80us(void);
void delay48us(void);
void delay6us(void);

u8 Ds18b20Init();
void Ds18b20WriteByte(u8 dat);
u8 Ds18b20ReadByte();
void  Ds18b20ChangTemp();
void  Ds18b20ReadTempCom();
int Ds18b20ReadTemp();

main.c文件的数据

/****************************************
*本程序是由8位数码管,读取DS18B20温度采集的程序
*
*本程序采用keil5编写,采用proteus8.9进行仿真
*
*此温度显示范围-50~+120,精度达到了0.05
*
*程序编写人 “莫拉”
*******************************************/
#include<reg51.h>
#include<temp.h>

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u8 displaydata[8];

u8 code smgduan[10]=0x3f,0x06,0x5b,0x4f,0x66,
					0x6d,0x7d,0x07,0x7f,0x6f;
/****************************************
*函数名:delay
*函数功能:延时函数
*输入:当输入1时,大约延迟1us
*输出:无
*******************************************/										
void delay(u16 i)

 while(i--); 
											
/****************************************
*函数名  :datapros
*函数功能:显示真实温度数据
*输入:DS18B20反馈的数据
*输出:无
*******************************************/
void datapros(int temp)

	float tp;
	if(temp<0)
		displaydata[0]=0x40;
		temp=temp-1;		
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;
	
	else
	
		displaydata[0]=0x00;	
		tp=temp;
		temp=tp*0.0625*100+0.5;
	
	displaydata[1] = smgduan[temp/10000];
	displaydata[2] = smgduan[temp % 10000 / 1000];
	displaydata[3] = smgduan[temp % 1000 / 100] | 0x80;
	displaydata[4] = smgduan[temp % 100 / 10];
	displaydata[5] = smgduan[temp % 10];

/****************************************
*函数名  :display
*函数功能:数码管显示
*输入:无
*输出:无
*******************************************/
void display( )

	u8 i;
	for(i=0;i<6;i++)
	
		switch(i)
		
			case(0):LSA=0;LSB=0;LSC=0;break;  //显示第0位
			case(1):LSA=1;LSB=0;LSC=0;break;   //显示1位
			case(2):LSA=0;LSB=1;LSC=0;break; 
			case(3):LSA=1;LSB=1;LSC=0;break; 
			case(4):LSA=0;LSB=0;LSC=1;break; 
			case(5):LSA=1;LSB=0;LSC=1;break; 
			case(6):LSA=0;LSB=1;LSC=1;break; 
			case(7):LSA=1;LSB=1;LSC=1;break;   //显示7位
		
		P0=displaydata[i];
		delay(100);
	


void main()

	while(1)
	
		datapros(Ds18b20ReadTemp());
		display();
		Delay1ms(10);
	

下面是proteus的仿真图


以上就是DS18B20的全部程序,希望在阅读完毕后,觉得有用的小伙伴给我点个赞,支持一下!!!
您的支持将会是我创作的动力!!!

以上是关于关于51单片机读取DS18B20温度采集系统,并将读取到的数据传输到数码管上;我们书写的程序总是读取到-000.06的状况,给出以下解决办法。的主要内容,如果未能解决你的问题,请参考以下文章

Proteus51单片机+双DS18B20浮点数温度显示

51单片机课程设计:基于DS18B20的温度报警器

DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号

DS18B20温度传感器的使用方法有哪些?

51单片机温度传感器ds18b20、lcd1602液晶C程序

16.STC15W408AS单片机获取DS18B20温度