51单片机驱动——DS18B20

51单片机驱动——DS18B20

1.描述

DS18B20是常用的环境温度测量的传感器,但其对通信时序要求较高,而51单片机资源有限,大部分人在使用时也不会严格对照数据手册的时序图操作,所以经常会有人遇到,网上下载的代码无法正常驱动DS18B20读取环境温度,有的代码在Proteus等仿真软件里是可以正常使用的(时钟频率设定等因素),但在实物中就不能实现对应功能。下面的这个代码是在实物系统中验证过的,我也简单封装了一下,大家可以直接复制使用。

2.子文件

DS18B20.c

#include "DS18B20.h"

sbit DS18B20=P1^0;  //定义数据线

void delay_ms(unsigned int x)//延时1ms
{
	unsigned int y,z;
	for(y=x;y>0;y--)
		for(z=110;z>0;z--);
}

uchar DS18B20_Init()       //初始化。成功返回1,不成功返回0.
 {
	uchar i;
	DS18B20 = 0;		     //将总线拉低480微秒~960微秒
	i = 70;	 
	while(i--);			 //延时642微秒
	DS18B20 = 1;			 //拉高总线,等待后续反馈
	i = 0;
	while(DS18B20)	    //等待DS18B20拉低总线
	{ 
		delay_ms(1);      //定义的延迟1ms的延迟函数
		i++;
		if(i>5)           //等待5ms以上
		{
			return 0;      //初始化失败
		}
	}
	return 1;             //初始化成功
}

uchar DS18B20_ReadByte() //通过读取8次状态位达到读取字节的目的
{
	uchar byte, bi;
	uint i, j;	
	for(j=8; j>0; j--)
	{
		DS18B20 = 0;		//先将总线拉低
		i++;
		DS18B20 = 1;		//然后释放总线
		i++;
		i++;				//延时6微秒等待数据稳定
		bi = DS18B20;	   //读取数据,从最低位开始读取
		byte = (byte >> 1) | (bi << 7);	//从最低位开始记录,将byte依次右移					  
		i = 4;				//读取完之后等待48微秒再接着读取下一个数
		while(i--);
	}				
	return byte;         //将读取完的字节保存
}

void DS18B20_WriteByte(uchar dat)//函数通过循环写8个位实现写一个字节
{
	uint i, j;
	for(j=0; j<8; j++)
	{
		DS18B20 = 0;	     	//每写入一位数据之前先把总线拉低
		i++;
		DS18B20 = dat & 0x01;   //然后写入一个数据,从最低位开始
		i=6; 
		while(i--);             //延时68微秒
		DS18B20 = 1; //释放总线,给总线1微秒恢复时间才能接着写入下一位			
		dat >>= 1;
	}
}

int DS18B20_ReadTemp()  //读取的温度有两个字节,分别用tml和tmh存储两个字节
{
	int temp = 0;
	uchar tmh, tml;
	DS18B20_Init();						//传感器初始化
	delay_ms(1);						//延时1微秒
	DS18B20_WriteByte(0xcc);			//跳过读取序列号操作		 
	DS18B20_WriteByte(0x44);			//温度转换指令		
	//完成温度转换功能
	DS18B20_Init();						//传感器初始化
	delay_ms(1);						
	DS18B20_WriteByte(0xcc);	 		//跳过读取序列号操作
	DS18B20_WriteByte(0xbe);			//发送读取温度指令
	//然后等待转换完后发送读取温度命令
	tml = DS18B20_ReadByte();		//读取温度值共16位,先读低字节
	tmh = DS18B20_ReadByte();		//再读高字节
	temp = tmh;			//先存高字节,后面通过移位存储低字节
	temp <<= 8;
	temp |= tml;
	return temp;
}


uint Temper_change()
{
    uint temper;
    float tp;
    //temper=read_temper();
		temper=DS18B20_ReadTemp();
    if(temper<0)    //考虑负温度的情况
    {
        temper=temper-1;
        temper=~temper;
        tp=temper*0.0625;  //16位温度转换成10进制的温度
        temper=tp*100+0.5;   //留两个小数点,并四舍五入
    }
    else
    {
        tp=temper*0.0625;  //16位温度转换成10进制的温度
        temper=tp*100+0.5;  //留两个小数点,并四舍五入
    }
    return temper;
}

DS18B20.h

#ifndef __DS18B20_H__
#define __DS18B20_H__
#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int

uint Temper_change();

void delay_ms(unsigned int x);//延时1ms
#endif

3.调用举例

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
#include "ds18b20.h"

unsigned int temper_value;//用于存储温度数据

void main(void) 
{
while (1) 
	{ 
		temper_value = Temper_change();//temper_value,后续可以用来显示、或者判断等。
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值