原创 同步快速读取8支DS18B20温度的方法

2008-11-12 20:36 2770 7 8 分类: MCU/ 嵌入式

同步快速读取8DS18B20温度的方法


------李杰<?XML:NAMESPACE PREFIX = O />


DS18B20在测温领域,应用非常广泛。当系统要测量多支DS18B20的温度时,如何快速测量,成为程序设计的关键。


DS18B20内部均有一个独立的序列号(ROMCODE),单片机通过ROMCODE可以对一条总线上的多支DS18B20进行控制,读取它们的温度。但要完成这个操作,软件设计异常复杂,同时存在一个致命的缺点:速度太慢!对于一些实时性要求高的测稳场合,根本无法使用。现在介绍一种采用单片机的并口,同步快速读取8DS18B20的方法。


一、设计原理


电路见图一,8DS18B20全部与单片机(Lpc932A1)P0口连接。由排阻RB12K)提供上拉,采用1mm的导线,控制距离可达200米。减小RB1的阻值,还可进一步提高控制距离。


 


对于一支DS18B20,我们要输出或输入各类命令数据时,采用“位寻址”


如:


MOV  D0C  


MOV  CD0 


SETB C                            


而对于8DS18B20,如果还采用“位寻址”的方法,程序就非常复杂!但我们只需将“位寻址”扩展成“字节寻址”如:


MOV     P0#0FFH


MOV  A,    P0


即可一次输出或输入8个位数据,从而达到同步读取的目的。详细的程序见下(只给出 读、写子程序)。


八支DS18B20的控制程序


以下程序全部在KEIL C51下编译!


//---------------------------------------------------------------------------------------------------------


//12MHz 下,_NOP_1uS_()执行时间0.1667us   LPC932


//---------------------------------------------------------------------------------------------------------


#define NOP_1uS  _nop_();_nop_();_nop_();_nop_();_nop_();_nop_()


//**************************************


#define Skip                  0xcc              //跳过命令


#define Convert             0x44       //转化命令


#define RdDs18b20       0xbe              //读温度命令


//********************************************************************


#define  DQ         P0           //P0口用8DS18B20


//-------------------------------------------------------------------------------------------------------


//功能:10us 级别延时


//-------------------------------------------------------------------------------------------------------


void Delay10us(unsigned char n){


       while(n--)  {


              NOP_1uS;NOP_1uS;NOP_1uS;


              NOP_1uS;NOP_1uS;NOP_1uS;


              NOP_1uS;


       }


}


//----------------------------------


//功能:总线初始化


//-----------------------------------


bit Init_18B20(void)


{


       DQ=0;


       Delay10us(50);//延时500us


       DQ=0xff;


       Delay10us(9);//延时90us


       if((DQ & 0x1f) ==0x1f)                     //0001 1111b=1f


       {


              return 0;  //失败0


       }else


       {


              Delay10us(40);//延时400us


              DQ=0xff;              //成功!


       }


       return 1;


}


//-------------------------------------------


//功能:读取18B20 (8DS18B20)


//入口 *p接收数据的地址指针


//------------------------------------


void Read_18B20(unsigned char *p){


       unsigned char i;


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


              DQ=0;


              NOP_1uS;                                         //延时1us


              DQ=0xff;


              NOP_1uS;NOP_1uS;NOP_1uS;


              NOP_1uS;NOP_1uS;NOP_1uS;          //延时5us


              //----------------------------------


              *p++=DQ;                                         //并口读入8个位


              //----------------------------------


              Delay10us(5);                                    //延时40us


              DQ=0xff;


       }


}


 


//-----------------------------------


//功能:写18B20


//-----------------------------------


void Write_18B20(unsigned char n)


{


       unsigned char i;


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


       {


              DQ=0;


              Delay10us(1);                                    //延时13us 左右


              DQ= (n&0x01)*0xff;


              n=n>>1;


              Delay10us(5);                                    //延时50us 以上


              DQ=0xff;


       }


}


二、   温度合成处理


采用上述方法1次性读取了8DS18B20的温度数据占用时间不到1秒,但它们在RAM中排列是交叉的,必须用软件合成,才能得到8个的温度值。温度值在Buf中的存放次序(见表一)


表一



Buf[0]


D70


D60


D50


D40


D30


D20


D10


D00


Buf[1]


D71


D61


D51


D41


D31


D21


D11


D01


Buf[2]


D72


D62


D52


D42


D32


D22


D12


D02


Buf[3]


D73


D63


D53


D43


D33


D23


D13


D03


Buf[4]


D74


D64


D54


D44


D34


D24


D14


D04


Buf[5]


D75


D65


D55


D45


D35


D25


D15


D05


Buf[6]


D76


D66


D56


D46


D36


D26


D16


D06


Buf[7]


D77


D67


D57


D47


D37


D27


D17


D07


探头:


8


7


6


5


4


3


2


1


 


 


8个字节的缓存区中(Buf[0]-Buf[7])中,从D07位开始,纵向依次排列的是8DS18B20的温度值,此时要设计一个将纵向8位数据转换成横向的数据程序,便可得到温度的数据字节,连续执行2次,便可将DS18B20的高、低字节全部合成标准的温度数据(程序见下)。


 


#define Ds18b20k                8            //定义8DS18B20


//------------------------------------------


//数据合并 Buf[0].0,Buf[1].0...=>Dat[0]


//8 DS18B20合并8个温度


//------------------------------------------


void FormatTemp(unsigned char *pSurce,unsigned char *pTag)


{


       code unsigned char CodeMask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};    //对应8DS18B20的位


       unsigned char i,j;


      


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


       {


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


              {


                     pTag >>=1;


                     pTag |=(( pSurce[j] & CodeMask)>0? 1:0)*0x80;


            }


       }


}


三、结束语


上述的方法,程序设计非常简单,8DS18B20的读取时间与1DS18B20的读取时间基本相等,使系统测温非常快速。上述希望使用DS18B20的朋友借鉴!

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1584993 2010-12-21 11:58

多多的加油吧

用户1021297 2010-12-21 09:01

我才471E币,这个。。。

用户944075 2010-12-20 17:49

这么多好东西啊 可惜e币不多了

用户1433065 2010-12-20 12:05

今天收到了你的读卡器,谢谢

用户518141 2008-11-14 20:47

谢谢楼主分享,好资料,参考参考。
相关推荐阅读
用户1612104 2008-11-16 13:33
Keil C51程序设计中几种精确延时方法
 摘要 实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。本文从实际应用出发,讨论...
用户1612104 2008-11-08 19:56
湿度传感器HS1101在智能家居控制系统中的应用
 引言      随着时代的发展,数字化家居控制系统的出现使得人们可以通过手机或者互联网在任何时候、任意地点对家中的任意电器进行远程控制,同时也可以对室内的空气温度、湿度、质量进行监测和调节。    ...
用户1612104 2008-11-08 19:39
C语言指针
C语言指针(转)c语言指针的用处 C里面函数都只能返回一个值,如果你的函数要返回两个值,那就要用指针了,把变量地址传进函数,然后把希望通过函数操作后想要的值存进传进来的变量地址里面。当然函数可以返回数...
用户1612104 2008-11-05 13:24
让指针不再困扰你(转载原作者moonwalker)
指针对一部分初学者来说一直是一个无法逾越的障碍,没有指针的C语言就好像没有左腿的短跑运动员。今天我来试试换一种方法来理解指针,希望能帮还在为指针挣扎的朋友们理清思路,高手略过即可。     我们先认为...
用户1612104 2008-07-26 12:43
今天开博了,庆祝一下
今天开博了,庆祝一下...
EE直播间
更多
我要评论
1
7
关闭 站长推荐上一条 /3 下一条