DS18B20温度传感器

1.DS18B20介绍
DS18B20温度传感器是单总线器件,一根线上可以挂接多个DS18B20,在生活中运用很多。
2.DS18B20特点
(1)单线通信
(2)每个DS18B20都有唯一的64位序列码存在板载ROM中。(多机挂接时找对应DS18B20)
(3)温度范围:-55-125度
(4)温度传感器可以设置9-12位,12位为0.0625度(就是只有变化0.0625数值才会变化加一)
同理9位 0.5度,10位 0.25度,11位 0.125度
3.器件原理图
1与3口为接地与电源,2口为数据转输线
请添加图片描述
4.单总线转输
(1)单总线信号类型:
复位,存在脉冲,读0,读1,写0,写1
这些信号只有存在脉冲是DS18B20发出的,其余是总线控制器发出的
数据从最低位开始存。
5.发送方法
(1)初始化时序
主机与DS18B20的任何通信都需要进行初始化程序
初始化时序包括复位DS18B20和接收DS18B20的返回的存在信号。
复位:总线拉低480us以上,总线上的器件都被复位。然后拉高,等待15-60us
存在:DS18B20返回60-240us的低点平存在信号。
请添加图片描述
(2)写0与写1
就是将总线控制拉低,然后由拉低的时间取确认写0还是写1,如果拉低60到120us为写0,15us后为写1,然后拉高间隔1us。
请添加图片描述
(3)读时序
同样是总线控制拉低,然后15us内读取到数据,读一位数据要保存60us+。请添加图片描述
6.温度寄存器内容
请添加图片描述
请添加图片描述
(1)0-1个字节
用于存储温度数据,LSB为高位,MSB为低位。
(2)2-3个字节
TH为最高上限报警位
TL为最低下限报警位
(3)4字节
主要配置DS18B20工作在多少位
如下就R1与R0可以改变配置
请添加图片描述
(4)5-8字节
暂时无用
(5)EEPROM为寄存器,断电数据也不会断,故我们可以设置EEPROM后传给BS18B20。
7.步骤
(1)初始化时序
(2)发送ROM指命(寻找单总线上的BS18B20的地址)
(3)DS18B20的功能指命
8.特殊指命
(1)0xcc,忽略ROM指命
当一条总线上只有一个BS18B20时就可以使用,因为不需要找地址了。
当是有多个显然不行,上面的所以BS18B20都会被开启使用。
(2)0x44,温度转换
启动一次温度转换,传感器收集到的温度数据直接以2个字节的形式被放在高速寄存器的第0-1位中。
(3)0xbe,读暂存器的内容
读取将从0开始,然后一直读下去,直到发送复位电路停止读取。
(4)0x4e,写暂存器TH,TL,模式的内容
写直接从TH位置开始写,直到写完配置暂存器后停止。
(5)0x48,拷贝暂存器
将TH,TL,配置暂存器的内容写到EEPROM,而与之对应的就是0xB8,将EEPROM数据传回。

#include <reg52.h> 
#include <intrins.h>
sbit LA=P2^2;
sbit LB=P2^3;
sbit LC=P2^4;
sbit DS = P3^7;
unsigned char miao; //全局变量位,控制显示
unsigned char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(unsigned char us) //进入11.95us,执行一次6.5us
{
	while(us--);
}
void delay2(unsigned int z)     //延时函数2,delay(1000)=1s
{
	unsigned int x,y;
	for(x=z;x>0;x--)
	   for(y=120;y>0;y--);
}
void timefrist()   //中断初始化
{
	EA = 1;
	ET0 = 1;
	TR0 = 1;
	TMOD |= 0x01;
	TH0 = 0xED;
	TL0 = 0xFF;
}
void DigDisplay(unsigned char h)  //显示函数
{
	unsigned char a=h%10;
	unsigned char b=h/10%10;
	unsigned char c=h/100;
	static unsigned char wei=0;
	switch(wei)
	{
		case 0: LA=1;LB=1;LC=1;P0 = smgduan[c];break;
		case 1:	LA=0;LB=1;LC=1;P0 = smgduan[b];break;
		case 2: LA=1;LB=0;LC=1;P0 = smgduan[a];break;
	}
	wei++;
	if(wei==3)
	{
		wei = 0;
	}
}
void timer0() interrupt 1    //中断函数150ms不断显示
{
	 TH0 = 0xED;
	 TL0 = 0xFF;
	 DigDisplay(miao);
}
bit dsdirst()          //初始化时序
{
	bit i;
	DS = 1;
	_nop_();       //DS=1的时间要有
	DS = 0;          
	delay(75);     //拉低480us以上
	DS = 1;       //释放总线
	delay(4);     //等待15-60us
	i = DS;       //接收BS18B20的存在信号
	delay(20);   //60到240的us的存在信号
	DS =1;       //释放总线
	_nop_();
	return (i);   //返回存在信号
}
void writeone(unsigned char dat)   //写一个字节
{
	unsigned char i;   //初始化前已经拉高了DS
	for(i=0;i<8;i++)
	{
		DS = 0;
		_nop_();     //拉低1us
		DS = dat & 0x01;   //从最低有效位开始
		delay(10);   //同时满足写0与写1要求
		DS = 1;      //释放总线,准备下一次输入数据
		_nop_();     
		dat >>= 1;   //不断右移,把下一位对应的最低位
	}
}
unsigned char readone()  //读一个字节
{
	unsigned char i,j,dat;
	for(i=0;i<8;i++)
	{
		DS = 0;
		_nop_();
		DS = 1;  //拉低后释放总线交给DS18B20控制
		_nop_();
		j = DS;  //读数据一位
		delay(10); //读一位数据至少要60us以上
		DS = 1;    //重新交给控制器  
		_nop_();   
		dat = (j<<7) | (dat>>1);  //j写到最高位给dat后然后dat右移到最低位
	}
	return(dat);
}
void main()
{	
	unsigned int i;
	unsigned char L,H;
	timefrist();     //定时器0初始
	while(1)
	{
        dsdirst();         //每次通信都要初始化
		writeone(0xcc);    //跳跃ROM(寻址)指命,因为51上只有一个DS18B20
		writeone(0x44);    //发送温度转换指命,存储在寄存器内
		
        dsdirst();         //重新初始化
		writeone(0xcc);    //跳跃ROM(寻址)指命,因为51上只有一个DS18B20
		writeone(0xbe);    //读暂存器的内容,从第0个字节开始
		L = readone();     //读第一个字节(温度高位)
		H = readone();     //读第2个字节(温度低位)
		i = H;                     
		i <<= 8;          //这里为把高8位与低8位合起来
		i |= L;   
		i = i * 0.0625 *10 + 0.5;      //0.0625为12位分辨率,*10是为了显示小数后一位
		delay2(1000);   //延时1s,再检测一次温度
		miao = i;       //i赋予全局miao显示
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值