打印

菜鸟的ds18b20总结

[复制链接]
2857|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qqiummo|  楼主 | 2010-12-23 17:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
沙发
qqiummo|  楼主 | 2010-12-23 18:54 | 只看该作者
一、初始化,如图一

数据线拉低至少480us后再将其拉高,大约等待15~60us,就会收到60~240us的低电平的存在脉冲,其后数据线会恢复被拉高状态,在数据线被拉高到初始化结束经过的时间至少为480us,以下是我根据对初始化时序写的子程序,用的是51
#include <reg52.h>
#define uchar unsigned char

#define uint unsigned int
void delay1(uint z)//延时子程序
{ uint x,y;

for(x=10;x>0;x--)
/*z=1
时,延时子程序用时约为61.5US*/

{


for(y=z;y>0;y--);


}


}
void reset()
{ uint i;

DQ=1;


i++;


DQ=0;


delay1(120);//
软件仿真测试为495us

DQ=1;


for(i=65;i>0;i--)


{ //i
这个数值可以改,for语句只是作为收到存在脉冲时的延时只要满足>60us就可以

if(!DQ)break;
//
当收到存在脉冲时跳出循环

}


delay1(120);
//
大于480us
}
其实这个子程序并没考虑到干扰,因为假设在初始化过程有低电平脉冲的干扰,那么即使ds18b20没有发送低电平,也会认为初始化成功。
一、二、写时隙

1)写1时隙,如上右图:主控器将数据线拉低至少1us,并在拉低后的15us内再将其拉高,整个过程大于60us,子程序如下
uchar bit1_write18b20()
{uint i=0;

DQ=1;


i++;


DQ=0;


for(i=0;i<1;i++);

//for(i=0;i<1;i++)
约为12.94us

DQ=1;


for(i=0;i<4;i++);
//
约为51us,整个过程大于60us

return(DQ);

}


2)写0时隙,如上左图,主控器将数据线拉低至少60us后将其拉高,子程序如下:
uchar bit0_write18b20()
{uint i=0;

DQ=1;


i++;


DQ=0;


for(i=0;i<5;i++);//
大于60us

return(DQ);

}
一、三、读时隙

我发    很多人被时序图的阴影部分吓到了,其实这表示数据线的在这个时间段状态不确定,整个时序图的意思是主控制器将数据线拉高至少1us后,再将其拉低,在拉低后15us内的数据有效,整个时隙时间要大于60us.
虽然pdf中,用两个时序图分别表示读0时隙和读1时隙,实际上读一位数的子程序只要一个,数据线拉低后1us,将数据线拉高,在15us内储存数据,再延时,使其满足总时间大于60us,下面给个例子:
uchar bit_read18b20(void)
{ uint i;


uint k;



DQ=1;

k++;


DQ=0;



for(i=0;i<1;i++);
/*for(i=0;i<1;i++)
约为12.94us*/


DQ=1;

/*60us*/




return(DQ);

}
一、四、写、读一个字节数子程序:
/*写一字节数*/
void byte_write18b20(uint w)
{ uint i=0;



bit b;



for(;i<8;i++)



{
b=w&0x01;




if(b)bit1_write18b20();



else bit0_write18b20();



w=w>>1;



}

}
/*读一字节*/
uchar byte_read18b20(void)
{


uchar i;



uint k;



uchar
value=0;



for(i=0;i<8;i++)



{



if(bit_read18b20())value|=(0x01<<i);



for(k=0;k<6;k++);
//
延时使其满足读时隙时间


}



return(value);

}
五、温度转换和显示那些子程序有很多,在这里就不重复了,接下来再写几个其他的子程序(单个ds18b20):
1/*电源模式读取*/
unsigned int Readpower( )
{

unsigned int t=0;


reset();


byte_write18b20(0xCC);//skip rom


byte_write18b20(0xB4);


t=bit_read18b20();


return(t);

}
2/*将快速暂存寄存器的TH,TL和配置寄存器复制到EEPROM*/
void copyRam()

{

reset();

byte_write18b20(0xCC);

byte_write18b20(0x48);

}

说明:这个指令与WRITE SCRATCHPAD(4Eh)指令结合可以将所要设置的温度上下限值写入ds18b20中的eeprom中,实现断电后所设置的数值仍然保存,可已通过这种方式做一个可报警的温度计,下面给个例子:
void send(uchar TH,ucharTL)//将要写的温度上下限值存入EEPROM
{
reset();


byte_write18b20(0xCC);



byte_write18b20(0x4E);



byte_write18b20(TH);



byte_write18b20(TL);



byte_write18b20(0x00);



reset();



byte_write18b20(0xCC);



byte_write18b20(0x48);



reset();

}
3)读单个ds18b20的序列号子程序
uint a[7];
uint b[7];
void num_read()
{

reset();



byte_write18b20(0x33);



for(i=0;i<8;i++)



{



g=byte_read18b20();



a=g/16;
//16
进制存入,这个是为了方便我用来显示的,只作参考


b=g%16;



}

}
对于ds18b20,有一点遗憾的是alarm searchECh)指令并没有试出来,据说是当ds18b20的温度超过所设置的温度范围时,会返回唯一的ID即序列号,但无论我怎么弄,读取的数值各个位都是一,也有可能是我只用一个ds18b20的原因,希望有用过ds18b20的大侠指教一下alarm search的用法






使用特权

评论回复
板凳
letlet| | 2011-4-13 14:43 | 只看该作者
总结的不错,菜鸟学习了。呵呵

使用特权

评论回复
地板
gongmaomao| | 2011-4-15 12:50 | 只看该作者
菜鸟学习ing···

使用特权

评论回复
5
wangjun403| | 2011-4-15 21:53 | 只看该作者
mark

使用特权

评论回复
6
afei9527| | 2011-4-16 17:56 | 只看该作者
菜鸟学习ing···

使用特权

评论回复
7
hyunbin| | 2011-4-23 16:22 | 只看该作者
弄懂18b20还是需要这些总结啊 谢谢分享

使用特权

评论回复
8
老鱼探戈| | 2011-4-23 17:19 | 只看该作者
技术不在乎有当前多么的利害
而在于在不断的学习过程中的积累和思考
LZ好样的。

使用特权

评论回复
9
xin71| | 2011-5-2 15:07 | 只看该作者
学习了

使用特权

评论回复
10
caohua6| | 2011-5-23 16:46 | 只看该作者
顶LZ啊

使用特权

评论回复
11
lixupengarm| | 2011-5-24 19:32 | 只看该作者
mark!!

使用特权

评论回复
12
hukepig| | 2011-8-26 06:36 | 只看该作者
顶,感谢分享你的经验

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

67

帖子

1

粉丝