DS18B20温度传感器C51驱动

代码由网上原有代码修改而来,主要是增加了传输和状态判断,在总线故障时返回0,正常返回1。
移植需要自己修改成实际的IO口,并且根据不同单片机,还需要修改ds18b20_bus.c中的延时函数。

ds18b20.c
#include "ds18b20.h"
#include "ds18b20_bus.h"


// 读取浮点类型的温度值
// 返回: 0-读取失败, 1-读取成功
unsigned char DS18B20_GetTemperature(float *temperatureBuf)
{
	unsigned char TL, TH;
	int temp;
	unsigned char ret;

	DS18B20_Reset();                  //总线复位
	ret = DS18B20_CheckOnline();	  //等待DS应答
	if(!ret)
	{
		return 0;
	}
	DS18B20_WriteByte(0xcc);            //发命令
	DS18B20_WriteByte(0x44);            //发转换命令
	DS18B20_Reset();				    //复位
	ret = DS18B20_CheckOnline();	    //等待DS应答
	if(!ret)
	{
		return 0;
	}
	DS18B20_WriteByte(0xcc);               //发命令
	DS18B20_WriteByte(0xbe);			   //发送读温度命令
	TL = DS18B20_ReadByte();               //读温度值的低字节
	TH = DS18B20_ReadByte();               //读温度值的高字节
	
	temp = TH<<8 | TL;             // 将高低字节合成温度值
	
	if(TH > 0x07)                  // 如果温度数值是负的
	{
		*temperatureBuf = (temp + 1) / 16.0;  //0.0625为12位温度采集的分辨率,乘0.0625等于除以16
	}
	else                           // 如果温度数值是正的
	{
		*temperatureBuf = temp / 16.0;
	}

	return 1;
 }

//初始化DS18B20  同时检测DS的存在
//返回0: 不存在
//返回1: 存在   
unsigned char DS18B20_Init(void)
{
	DS18B20_Reset();         //复位总线
	return DS18B20_CheckOnline();
}
ds18b20.h
#ifndef  DS18B20_H
#define  DS18B20_H

unsigned char DS18B20_Init(void);
unsigned char DS18B20_GetTemperature(float *temperatureBuf);

#endif
ds18b20_bus.c
#include "ds18b20_bus.h"
#include "debug.h"

// 这里延时需要修改成自己的
static void DS18B20_Delayus(unsigned char us)		//@24.000MHz
{
	unsigned int i;

	i = 8 * us;
	while (--i);
}


//DS18B20复位函数
void DS18B20_Reset(void)
{
    DS18B20_DQ = 1;                
    DS18B20_DQ = 0;
	// >480 us	  低电平复位信号
    DS18B20_Delayus(500);             
    DS18B20_DQ = 1;
	// >15us 的上升沿	 15-60us高电平后  是60-240us 的应答信号
    DS18B20_Delayus(16);              
}


unsigned char DS18B20_CheckOnline(void) 	   
{   
	unsigned char retry = 0;	 
	
    while ( DS18B20_DQ && (retry<50) )
	{
		retry++;
		//大概4us
		DS18B20_Delayus(4);		
	}
	
	if(retry >= 50)
	{
		Debug_UartSendStr("DS18B20: Check online fail!\r\n");
		return 0;
	}
	
	retry = 0;
	// 保持240us的延时 完成整个的复位过程
    while ( (!DS18B20_DQ) && (retry<60) )		 
	{
		retry++;
		//大概4us
		DS18B20_Delayus(4);		
	}

	if(retry >= 60)
	{
		Debug_UartSendStr("DS18B20: Check online fail!\r\n");
		return 0;	  
	}
	
	return 1;			 
}


// DS18B20写命令函数
// 向1-WIRE 总线上写1个字节
// u8 val 要写入字节
// DS18B20手册最下面有时序图
void DS18B20_WriteByte(unsigned char val)
{
	unsigned char i;
	
	for(i=0; i < 8; i++)
	{ 
		if(val&0x01)				  //写1
		{
			DS18B20_DQ = 0;
			DS18B20_Delayus(4);			  //4us
			DS18B20_DQ = 1;
			DS18B20_Delayus(60);			  //60us
		}
		else						  //写0
		{
			DS18B20_DQ = 0;
			DS18B20_Delayus(60);			  //60us
			DS18B20_DQ = 1;
			DS18B20_Delayus(4);			  //4us
		}
		val >>= 1;
	}
}

// DS18B20读1字节函数
// 从总线上取1个字节
// 返回值为读取字节值
// 说明  一次1bit的读取最少需要60us	  两次读取之间需要至少1us的恢复时间
// 单次读取1bit  总线拉低不能超过15us 然后马上拉高
unsigned char DS18B20_ReadByte(void)
{
	unsigned char i;
	unsigned char value = 0;
	
	for(i=8; i>0; i--)
	{
		DS18B20_DQ = 1;
		value >>= 1; 
		DS18B20_DQ = 0;                                  
		DS18B20_Delayus(8);			 //拉低4us 
		DS18B20_DQ = 1;              //拉高
		DS18B20_Delayus(12);		 //拉高10us	 准备接收总线当前数据
		
		if(DS18B20_DQ)
		{
			value |= 0x80;			 //将当前数据值存入临时变量
		}
			
		DS18B20_Delayus(55);         //50 us延时  完成一次读取的延时(一次读取最少60us)跳过1us的恢复时间
	}
	DS18B20_DQ = 1;
	
	return value;
}
ds18b20_bus.h
#ifndef __DS18B20_BUS_H_
#define __DS18B20_BUS_H_

#include <STC8.H>

#define DS18B20_DQ    P53        //DS18B20 端口

void DS18B20_Reset(void);
unsigned char DS18B20_CheckOnline(void);
void DS18B20_WriteByte(unsigned char val);
unsigned char DS18B20_ReadByte(void);

#endif
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值