关于DS18B20温度传感器的时序详解及代码分析
关于DS18B20温度传感器的时序详解及代码分析
简要说明测温⼯作**:**DS18B20的核⼼功能是它的直接读数字的温度传感器。温度传感器的精度为⽤户可编程的9,10,11或12位,分别以0.5℃,0.25℃,0.125℃和0.0625℃增量
递增。在上电状态下默认的精度为12位(所以最后获取的数据要乘以0.0625得到实际温度)。DS18B20启动后保持低功耗等待状态; 当需要执⾏温度测量(和AD转换)时,总线控制器必须发出[44h]命令。在那之后,
产⽣的温度数据以两个字节的形式被存储到⾼速暂存器的温度寄存器中(所以后期获取数据时,必须连续读取两次数据),下⾯介绍时序及相应代码(以12MHz的晶振为例,数据线定义为DQ)
,其中DS18B20的所有通信都是以由复位脉冲组成的初始化序列开始的,并采⽤的是单总线协议。
操作顺序:初始化——>写相应的控制指令(⽤写数据函数完成)——>读取DS18B20所采集到的数据(⽤读数据函数完成)———>把采集的数据转化成实际的温度。
延时函数: (15+15*z)us 的延时
*时序图及代码分析如下:*
⼀、初始化(见下图)
在初始化序列期间,总线控制器拉低总线并保持480us(改延时可以在480~960us之间,但需要在480us以内释放总线)以发出⼀个复位脉
冲,然后释放总线,进⼊接收状态(等待DS18B20应答)。总线释放后,单总线由上拉电阻拉到⾼电平。当DS18B20探测到I/O引脚上的
上升沿后,等待15-60us,然后其以拉低总线60-240us的⽅式发出存在脉冲。⾄此,初始化时序完毕。
初始化代码: 带返回值,有利于检验。
void delay_us(uint z)
{
for (z ;z>0 ; z--)write的返回值
{
_nop_(); _nop_();
_nop_(); _nop_();
}
_nop_(); _nop_();
}
bit DS18B20_init()
{
bit ack = 1;
DQ = 0; //主机拉低总线
delay_us(32); //延时495us
DQ = 1;//释放总线,同时IO⼝产⽣的上升沿能被DS18B20所检测到
delay_us(4); //延时⼤于60us,确保接下来DS18B20能发出60~240us的存在脉冲应答
ack = DQ;//在此60~240us之内DQ被DS18B20所占⽤,若存在,则其会发送⼀个低电平信号,DQ被DS18B20拉低,则ack为0,反之为1 delay_us(15);//延时达240us,让DS18B20释放总线
DQ = 1;
return(ack);
}
初始化代码写⾄此,其实我们便可以⽤数码管显⽰来检验初始化是否成功(即DS18B20有应答),数码管显⽰”0“,初始化失败,显⽰”1“,则初始化成功。
⼆、DS18B20的写时序(见下图):
主机在写时隙向DS18B20写⼊数据,其中分为写”0”时隙,和写”1”时隙。总线主机使⽤写“1”时间隙向DS18B20写⼊逻辑1,使⽤写“0”时间隙向DS18B20写⼊逻辑0.所有的写时隙必须有最少60us的持续时间,相邻两个写时隙必须要有最少1us的恢复时间。两种写时隙都通过主机拉低总线产⽣(见下图)为了产⽣写1时隙。
在拉低总线后主机必须在15μs内释放总线。在总线被释放后,由于上拉电阻将总线恢复为⾼电平。为了产⽣写”0”时隙,在拉低总线后主机必须继续拉低总线以满⾜时隙持续时间的要求(⾄少60μs)。
在主机产⽣写时隙后,DS18B20会在其后的15~60us的⼀个时间段内采样单总线(DQ)。在采样的时间窗⼝内,如果总线为⾼电平,主机会向DS18B20写⼊1;如果总线为低电平,主机会向DS18B20写⼊0。
综上所述,所有的写时隙必须⾄少有60us的持续时间。相邻两个写时隙必须要有最少1us的恢复时间。所有的写时隙(写0和写1)都由拉低总线产⽣。
DS18B20的写时序代码
写字节函数、由低位⾄⾼位,向DS18B20写⼊⼀个字节的数据。
⽆返回值。
形参byte是待写⼊的字节数据,读取8次,移位8次,保证每位都传输⾄DQ
void DS18B20_write_byte(uchar byte)
{
uchar i;
for(i=0 ; i<8 ; i++)
{
DQ = 0; //拉低总线,产⽣写时隙
_nop_();
_nop_(); //⼤于1us的延时
DQ = 1; //15us之内释放总线
_nop_();
_nop_(); //适当延时
DQ = byte & 0x01; //将字节低位写⼊单总线
delay_us(3); //在15~60us内等待DS18B20来采集信号
DQ = 1;//释放总线
byte >>= 1; //每次讲要读取的数据位移⾄最低位,
}
}
三、DS18B20的读时序(见下图)
主机发起读时序时,DS18B20仅被⽤来传输数据给控制器。因此,总线控制器在发出读暂存器指令[0xBE]或读电源模式指令[0xB4]后必须⽴刻开始读时序,DS18B20可以提供请求信息。除此之外,总线控制器在发出发送温度转换指令[0x44] (或召回EEPROM指令[0xB8])之后读时序,详见DS18B20 的芯⽚⼿册上的功能指令。
所有读时序必须最少60us,包括两个读周期间⾄少1us的恢复时间。当总线控制器把数据线从⾼电平拉到低电平时,读时序开始,数据线必须⾄少保持1us,然后总线被释放。DS18B20 通过拉⾼或拉低总线上来传输”1”或”0”。当传输逻辑”0”结束后,总线将被释放,通过上拉电阻回到上升沿状态。从DS18B20输出的数据在读时序的下降沿出现后15us 内有效。因此,总线控制器在读时序开始后必须停⽌把I/O⼝驱动为低电15us,以读取I/O⼝状态。
DS18B20的读时序的代码
读字节函数、由低位⾄⾼位,读取DS18B20所采集到的数据。
带返回值,可结合前⾯的写时序,对写、读数据函数进⾏检验(后⾯会提到检验过程及效果)
byte 是读取到的字节数据。其中,此函数读取8次,移位7次(实际移位8次)
uchar DS18B20_read_write()
{
uchar i;
uchar byte; //byte为要接收到的数据
for(i=0 ; i<8 ; i++)
{
DQ = 0; //产⽣读时序
_nop_();
_nop_(); //简单延时
DQ = 1;//释放总线,有从机DS18B20占⽤
byte >>= 1; //先进⾏移位
if(DQ) //让DS18B20占⽤总线,发出采集到的信号
byte |= 0x80; //若DQ=1,则让当前byte最⾼位为1,在下次循环中移位⾄次⾼位,最后达到从低位到⾼位接收的⽬的;若DQ=0,则可跳过此语句,直接 delay_us(3); //延时60us
DQ = 1;//释放总线
_nop_();
}
}
下⾯简单说说如何检验写、读时序的程序:
检验写、读的程序,本⼈采⽤DS18B20中特有的64位光刻ROM存储器(其中涉及⼀些指令,具体请见芯⽚的数据⼿册)。数据⼿册上说
明,“64位光刻ROM的排列是:开始(最低)8位是产品类型标号,对于DS18B20来说都是(28H),接着的48位是该DS18B20⾃⾝
的序列号,最后8位是前⾯56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作⽤是使每⼀个DS18B20都各不相同,这样
就可以实现⼀根总线上挂接多个DS18B20的⽬的。
因为写函数刚好是从最低位开始读,所以我们先:
调⽤函数:DS18B20_write_byte(0xcc);
接着再调⽤函数:DS18B20_read_byte();
⽤数码管,或者液晶,将读函数的返回值显⽰出来,正确的显⽰应该为:40。
这样,我们便能确定我们的写,读函数的正误了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论