C51单总线操作,读取温度DS18B20

本人不是电子出生,所以电路图大家就将就着看吧

ds18b20的驱动

#ifndef DS18B20_H
#define DS18B20_H


#include <reg51.h>
#include "delay.c"

//主机 11.0592Mhz
//
//


sbit DQ = P3^7;

#define SKIP_ROM 0xcc	   //跳过rom
#define CONVERT 0x44	   //开始转换
#define READ 0xbe		   //读取数据
#define _12 0x7f
#define _11 0x5f
#define WRITE_RAM 0x4e






//探测是否有器件
static void has()
{
	while(DQ);
	while(~DQ);
	delay_us(120);
	DQ = 1;
}


//重置
static void reset()
{
	DQ = 0;
	delay_us(480/2);
	DQ = 1;
	delay_15us();
    has();
} 

//写零
static void write_0()
{
	DQ = 0;
	NOP();
	delay_us(30);
	DQ = 1;
}

//写1
static void write_1()
{
    DQ = 0;
	NOP();
	NOP();
    DQ = 1;
    delay_us(30);	
}

//写一个字节
static void write_byte(char v)
{
	unsigned char i;
	unsigned char t;
	for(i = 0;i < 8;++i)
	{
		t = v & 0x01;
		v = v >> 1;
		if(t)
		{
			write_1();
		}
		else
		{
			write_0();
		}
	}
}

//读一个比特
static unsigned char read_bit()
{
	unsigned char re;
	DQ = 0;
	NOP();
	DQ = 1;
	NOP();
	NOP();
	re = DQ;
	delay_us(25);
	DQ = 1;
	return re;
}

//读一个字节
static unsigned char read_byte()
{
	unsigned char re;
    unsigned char t;
	unsigned char i;
	re = 0x00;	
	for(i = 0;i < 8;++i) {
		t = read_bit();	
	    re = (t << 7)|(re >> 1);//低位在前,高位在后
	}
	return re;
}

//16位二进制转化为温度
static float help(unsigned char low, unsigned char high)
{
    float re;
	unsigned char a, b;
	if (high & 0x80) 
	{
	//-
    	a = ~high;
		b = ~low;
		re = (a * 256 + b + 1) * 0.0625 * -1;

	}
	else
	{
	//+
	    a = high;
		b = low;
		re = (a * 256 + b) * 0.0625;
	}
	return re;
}

static void temperature_start()
{
    delay_ms(1);
	reset();
	write_byte(SKIP_ROM);
	write_byte(CONVERT);
	delay_ms(500);
}

static float temperature_read()
{
    unsigned char high = 0x00, low = 0x00;
	float re;
	delay_ms(1);
	reset();
	write_byte(SKIP_ROM);
	write_byte(READ);

	low = read_byte();
	high = read_byte();


	re = help(low,high);
    
	return re; 

}


static void ds18b20_init()
{
	delay_ms(1);
	reset();
	write_byte(SKIP_ROM);
	write_byte(WRITE_RAM);
	write_byte(0x00);
	write_byte(0x00);
	write_byte(_12); //精度12位
	
}

static int get_temperature()
{
    temperature_start();
	return temperature_read();
}


#endif						    

使用IO引脚模拟总线,重要的是时序对于单总线来说,时序很好模拟,就是一根线电平的高低,关键是时序的把握,高多长时间,什么时候拉低。

完整的例子代码http://www.kuaipan.cn/file/id_45404676266394625.htm

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值