DS18B20,驱动编写及说明手册

DS18B20


1. 64 位的 ROM 存储其独一无二的序列号(一般用不到)
2.暂存寄存器包含2 个字节宽度的温度寄存器,一个字节的过温和低温,温度报警寄存器(断电不丢失)和一个字节的配置寄存器(决定精度)
3. 1-Wire 总线上所有的命令或者数据的发送都是
遵循低位先发送的原则。读发都是低位开始
4. DS18B20 中输出的数据在初始化读时序后仅有 15us 的有效时间(这表示随及就要读写处理)
5.每个读时段最小必须有 60us 的持续时间且独立的写时段间至少有 1us 的恢复时间,要1S的释放时间DQ=1;

 
6,符号标置位(S)正数S=0,负数S=1,
 
这里要注意的是温度有12位,10位,9位等数据位减少方向为低位到高位(减小的是小数位),寄存器第8位到第11位,用到时是数据位,用不到时是符号位。
 
*上电复位时温度寄存器中的值为+85℃
温度报警
1. 当 DS18B20 完成一次温度转换后自动与用户定义的温度报警 TH 和 TL 寄存
器中的值进行比较(而且掉电数据依旧存在属于非易失寄存器)
 
当当前温度大于或小于设置温度时,被标志位被置一。
主设备可以通过报警查询命令[Che]查询该总线上的 DS18B20 设备的报警标志位


DS18B20 的供电


1.用电源供电,数据口需要加上拉电阻,用于唤醒温度转换期间可以正常工作。(主要)
2.可以不加电源(由寄生电容供电,但响应功能缺失)
由寄生电容供电还需要在加一个上拉MOSFET来为ds18b20提供足够的电流。而且上拉期间不可以产生其他动作。
 
64 位光刻 ROM 编码
 
存储器

 

 


一般来说前8位为符号位,后8位为数据位,,后8位中高4位为整数位,后4位为小数位
这里要注意的是温度有12位,10位,9位等数据位减少方向为低位到高位,寄存器第8位到第11位,用到时是数据位,用不到时是符号位。
在12位时,总共12位为数据位,其中8位为整数位(实际只用到7位,第8位没有用到,所以其整数最大只有127),后4位为小数位,一般不用。

循环冗余校验CRC计算


1-Wire 总线系统


1-Wire 总线上所有的命令或者数据的发送都是遵循低位先发送的原则。读发都是低位开始
硬件配置
1-Wire 总线需要一个 5kΩ左右的外部上拉电阻因此1-Wire 总线在闲置情况下是高电平。

所以释放就是回归高电平,一般设DQ=1就是释放过程。

事件序列
访问 DS18B20 的事件序列如下所示
第一步初始化(主设备的复位脉冲+从设备回应存在脉冲,采用回应存在脉冲明从设备准备好。)
第二步ROM 命令  (搜索 ROM[F0h] 获得总线上的所有从设备64位ROM编码从而确定类型及数量,
读取 ROM[33h] 读取唯一从设备的64位ROM编码。
匹配 ROM[55h] 主设备发送特定的64位ROM编码对特定从设备操作,其他的设备不相应。
跳过 ROM[CCh]指令,不在对 64位ROM编码这一步操作,所有设备直接执行功能命令,从机只有一个才行,多个会导致数据冲突,)
第三步DS18B20功能命令 (温度转换[44h],发送后将温度转换储存到0. 1字节,
写入暂存寄存器[4Eh],将数据(上下限,分辨率)写入,采取低位优先的原则位置为2-4字节。
读取暂存寄存器[BEh],将数据从暂存寄存器读取出来,0到9个字节全部读出。
拷贝暂存寄存器[48h】,将写入的数据拷贝到EEPOM中,
召回 EEPROM[B8h], 将存入的数据读取出来,
使用这个指令大前提是你不知道供电模式)读取供电模式[B4h],  确定供电模式,(由寄生电容供电的,主设备可以在发送一个跳过 ROM 命令[CCh]之后再发送一个读取供电方式命令[B4h]再紧跟一个“读取数据时序”。在读取数据时序中“寄生电源”供电方式的 DS18B20将会将总线拉低但是由外部供电方式的 DS18B20 将会让该总线继续保持高。


每次对 DS18B20 的访问都必须遵循这样的步骤来进行如果这些步骤中的任何一个丢失或者没有执行则 DS18B20将不会响应。除了 ROM 搜索命令[F0h]和报警搜索命令[ECh]之外。当执行完这些 ROM 命令之后主设备必须回到上述步骤中的第一步。
1-Wire 总线信号
初始化程序—复位和存在脉冲
主机产生大于等于480us的低脉冲,等待上升沿产生延迟15us到60us从机当检测到上升沿,产生大约180us的低脉冲,然后产生高电平480us说明初始化成功。
 
读/写时段
写时段
独立的写时段间至少有 1us 的恢复时间
写1时段,是由15us的低电平(对于51一次指令大约就可以满足)和45us以上的高电平组成
写0时段,是由60us的低电平组成,     注意的是命令切换必须要有1us以上的总线释放。

每个写时段最小必须有 60us 的持续时间,
读时段
每个读时段最小必须有 60us 的持续时间,
读时段通过主设备将总线拉低超过 1us 再释放总线来实现初始化。当主设备初始化完读时段后DS18B20 将会向总线发送 0 或者 1, 每次读初始化后发送1位从 DS18B20 中输出的数据在初始化读时序后仅有 15us 的有效时间,(这里初始完就可以读取了)
发送读暂存寄存器值,然后开始读,

使用是注意晶振

晶振不同可能无发正常使用

11.0592MHZ

#include <REG51.H>
#include <INTRINS.H>

#ifndef __DS18B20_H__
#define __DS18B20_H__


void delay_100us(unsigned int us_100);
void delay_10us(unsigned int us_10);
void Delay1(unsigned int num);
unsigned int reset();
void send_1byte( unsigned int byte_1);
void read_init();//读初始化
unsigned int  read_1byte();
unsigned int Ds18b20_Data();//获取温度

#endif // 
 
#include <DS18B20.H>


sbit DQ=P2^0;//总线控制口 

//延迟函数100us级
void delay_100us(unsigned int us_100)
{
 unsigned int i,a;
 for(i=0;i<us_100;i++)
 for(a=0;a<100;a++)
	_nop_ ();//为单周期指令 
}


//延迟函数10us级
void delay_10us(unsigned int us_10)
{
 unsigned int i,a;
 for(i=0;i<us_10;i++)
 for(a=0;a<10;a++)
	 _nop_();//为单周期指令
}

void Delay1(unsigned int num)            
{
    while(num--) ;//一次大15us
}
//复位函数
unsigned int reset()
{
 unsigned int DQ_flag;
 DQ=0;  
 delay_100us(5);
 DQ=1; //上升沿为从机触发信号
 delay_10us(2);//微妙级上升沿产生需要适当延迟
 DQ_flag=DQ;//采集从机应答信号为0代表应答成功,一般默认应答成功
 delay_100us(5);//延迟度过从机应当信号
 return  DQ_flag;
}


//写1个字节
void send_1byte( unsigned int byte_1)
{	
unsigned int i,b;	
 i=byte_1;//储存发送值
 for(b=0;b<8;b++)
	{
  if(i&0x01)
	{
    DQ=0;      //从赋0到输出就有15us左右了
    DQ=1;			//写一位1部分
	}
	else DQ=0;
	 Delay1(5);//一次大约15us//时间结束发送完毕
	 DQ=1;	  //释放总线为下次做准备
   i>>=1;
  }
 return; 
}

//读时段初始化
 void read_init()
 {
 DQ=0; 
 DQ=1;//读时段初始化
 }

 //读一个字节
unsigned int  read_1byte()
{
 unsigned int Data_T,i;
 for(i=0;i<8;i++)//但是数据要赋8次,但第一个位只能移动7次
{
  read_init();	
	Data_T>>=1;//移位必须放置在赋值前,放后会缺失一个数据
  if(DQ==1)
	{
  Data_T|=0X80;//数据从低位开始发送,那接受方应该从高开始接收	 		
	}

	Delay1(4);//读时间最小有60us才能有下一步 

}
return Data_T;
}
 
//读取温度值
unsigned int Ds18b20_Data()
{
  int TMPL,TMPH,falg;//符号判断
	unsigned int temp;
 reset();//写指令前必须要复位
 send_1byte(0xCC);//不对64位编码操作
 send_1byte(0x44);//发送温度转换指令
 reset();//写指令前必须要复位
 send_1byte(0xCC);//不对64位编码操作
 send_1byte(0xBE);//发送温度读取指令
 TMPL=read_1byte();//开启接受低位
 TMPH=read_1byte();//开启接受高位
 falg=TMPH&0x80;//获取符号
 if(falg==0x80)//负数高位为1
 {
  temp=TMPH<<8;//将低8位数据移到高8位
	temp=temp| TMPL;//将高低温数据合并
  temp=~temp+1;//取反加1得原码,符号位不参与运算。
	temp=temp*0.98;//12位精度位0.98
  return temp;
 }
 else //正数高位为零
 {
 temp=TMPH<<8;//将低8位数据移到高8位
 temp=temp| TMPL;//将高低温数据合并
 temp=(temp>>4) & 0x00FF;//温度数据中低4位没有用
 temp=temp*0.98;//12位精度位0.98//
 return temp;
 }

}

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码飞升,先练内功

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值