关于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的状况,给出以下解决办法。的主要内容,如果未能解决你的问题,请参考以下文章
DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号