基于单总线的实时温度监控系统文档格式.docx
《基于单总线的实时温度监控系统文档格式.docx》由会员分享,可在线阅读,更多相关《基于单总线的实时温度监控系统文档格式.docx(34页珍藏版)》请在冰豆网上搜索。
1)DS18B20的内部结构
DS18B20内部结构如图5所示,主要由4部分组成:
64位ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
DS18B20的管脚排列如图7-1-2所示,DQ为数字信号输入/输出端;
GND为电源地;
VDD为外接供电电源输入端,在寄生电源接线方式时接地,见图6。
图5DS18B20的内部结构
图6DS18B20的管脚排列
ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。
64位ROM的排的循环冗余校验码(CRC=X8+X5+X4+1)。
ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
DS18B20中的温度传感器完成对温度的测量,用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB形式表达,其中S为符号位。
例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FF6FH,-55℃的数字输出为FC90H。
高低温报警触发器TH和TL、配置寄存器均由一个字节的EEPROM组成,使用一个存储器功能命令可对TH、TL或配置寄存器写入。
其中配置寄存器的格式如下:
0
R1
R0
1
MSBLSB
R1、R0决定温度转换的精度位数:
R1R0=“00”,9位精度,最大转换时间为93.75ms;
R1R0=“01”,10位精度,最大转换时间为187.5ms;
R1R0=“10”,11位精度,最大转换时间为375ms;
R1R0=“11”,12位精度,最大转换时间为750ms;
未编程时默认为12位精度。
高速暂存器是一个9字节的存储器。
开始两个字节包含被测温度的数字量信息;
第3、4、5字节分别是TH、TL、配置寄存器的临时拷贝,每一次上电复位时被刷新;
第6、7、8字节未用,表现为全逻辑1;
第9字节读出的是前面所有8个字节的CRC码,可用来保证通信正确。
2)DS18B20的工作时序
DS18B20的一线工作协议流程是:
初始化→ROM操作指令→存储器操作指令→数据传输。
其工作时序包括初始化时序、写时序和读时序,如图7(a)(b)(c)所示。
(a)初始化时序
(b)写时序
(c)读时序
图7DS18B20的工作时序图
3)DS18B20与微处理器的连接
DS18B20与微处理器的连接如下图8所示。
(a)寄生电源工作方式
(b)外接电源工作方式
图8DS18B20与微处理器的典型连接图
3.1.2DS2480B
1)DS2480B主要特性
串口UART/RS232至单总线通信协议的转接桥,可直接连到UART和5VRS232系统中,支持Dallas全系列单总线器件,如数字温度传感器DS18B20、A/D转换器DS2450等;
将主机从单总线时序控制中解脱出来,提供规范的、灵活的和强驱动的单总线定时;
支持标准UART通信,支持9.6(默认)、19.2、57.6和115.2kbps速率;
具有较强的总线驱动能力,通信距离可达300m;
可编程下拉摆率控制和有源上拉,工作范围5V,-40~+85℃,8引脚SOIC封装。
2)管脚图及引脚说明
图9DS2480B的封装和引脚
DS2480B为8脚贴片式封装,如图9所示。
引脚功能如表1所列
引脚号
引脚名称
引脚功能
1
GND
地线
2
1-W
单总线输入输出端
3
NC
悬空
4
VDD
4.5~5.5V电压
5
VPP
EPROM编程电压
6
POL
RXD/TXD选择端
7
TXD
发送端
8
RXD
接收端
表1引脚功能说明
DS2480B工作原理框图如图10所示。
图10DS2480B工作原理框图
3)DS2480B与RS232的接口技术:
DS2480B与RS232的接口如图11所示。
图11DS2480B与RS232的接口图
3.2元件清单
序号
元件
个数
PC机串行口UART/RS232
1个
转接桥DS2480B
数字温度传感器DS18B20
电容U07HF
稳压管
2个
二极管M7
电路板XF07
表2元件清单
4学习心得
通过该温度监控实验,我们可以发现:
基于DS18B20数字温度传感器构成的实时监控系统确实具有精度高、抗干扰能力强、电路简单等诸多优点,温度传感器得到电缆长度达到几十米都可以正常读取温度数据,并且已经在站长开发的机房安全监控系统中得到了实际考验,那可是要365天从不间断地对机房及相关设备提供实时温度监控的哦。
相比之下,传统的温度检测系统采用热敏电阻等温度敏感元件,热敏电阻成本低,但需要后续信号调理、AD转换处理电路才能将温度信号转换成数字信号,不但电路复杂,而且热敏电阻的可靠性相对较差,测量温度的精度差,很难保证热敏电阻的一致性和线性,在应用中需要很好的解决引线误差补偿问题、共模干扰问题和放大电路零点漂移误差等技术问题。
因此,如果你开发的系统对温度监控精度要求不是非常高,而且测温的范围DS18B20的-55~+125℃之间的话,那么采用DS18B20是一个不错的选择,通过软件的插值运算,其实DS18B20的测温精度还可以进一步提高的,具体的实现方法大家可以参考DALLAS公司相关技术资料。
当然,如果你有条件的话,也可以预先对每一个DS18B20进行一次校验,在标准恒温箱中测量并记录下每个传感器的测温误差,在实际应用中,我们就可以根据每个传感器的实际校准对读出的实时温度进行适当的误差纠正,这样也不失为提高DS18B20测温精度的一个好办法。
可惜的是,并非大家都有这种高精度的恒温箱来校验传感器,如果你的参考温度不准确,那么校准将会适得其反。
通过对这个课程设计的学习,为我们掌握单片机实时温度监控的开发、串口通信程序的开发及计算机串口实时控制开发原理及PC监控软件的开发,以及开发其他功能更加完善的单片机综合应用系统打好基础。
5参考文献
[1]DS18B20ProgrammableResolution1-WireDigitalThermometer
[2]DS2480BSerial1-WireLineDriverwithLoadSensor
[3]左冬红,谢瑞和.实现单总线搜索ROM命令的一种算法
[4]求是科技.单片机典型模块设计实例导航
附:
源程序清单
{------------------------------------------------------------------------------------------------------
TEMPDL32:
ThisutilityusesTMEXtoviewareadthetemperaturefrom
aDS18B20.Itrequiresthe32-BitWindowsTMEXdrivers
tobepresent.
Compiler:
BorlandDelphi5.0
}
procedureTForm1.FormCreate(Sender:
Tobject;
Var
ztbuf:
array[0..200]ofChar;
Typebuf:
array[0..200]ofChar;
i,k,RetValue:
smallint;
RetStr:
SetupDone:
Boolean;
PortNum,PortType:
begin
dieer:
=false;
SetupDone:
=FALSE;
{TMSetupnotdoneyet}
Label4.Caption:
='
'
;
{ReaddefaultPortNumberandPortTypefromregistry}
RetValue:
=TMReadDefaultPort(@PortNum,@PortType);
if(RetValue<
1)then
TMReadDefaultPort(@PortNum,@PortType)
begin
ShowMessage('
Pleasesetportfirst'
);
Halt;
end
else
{readthetmexversionandtypeversion}
Get_Version(@ztbuf);
Label1.Caption:
=StrPas(ztbuf);
TMGetTypeVersion(PortType,@Typebuf);
Label2.Caption:
=StrPas(Typebuf);
{attemptogetasession}
Done:
=False;
Repeat
SHandle:
=TMExtendedStartSession(PortNum,PortType,NIL);
If(SHandle>
0)Then
if(TMSetup(SHandle)=1)then
{ThedevicethatwillbefoundisTemperatureDeviceDS18B20,
soFamilyTypeissetto$28}
FindFirstFamily($28,SHandle)
TMEndSession(SHandle);
FailtosetupMicroLan!
end;
if(SHandle<
0)then
Begin
TheDefaultPortTypedoesnothaveadriver!
{Releasecontrolbacktowindow}
Application.ProcessMessages;
until(Done);
Repeat
if(TMSetup(SHandle)=1)then
FindSecondFamily($28,SHandle)
label18.Caption:
=keke1;
label19.caption:
=keke2;
table1.Active:
=true;
iftable1.CanModifythen
table1.Append;
table1.Fields[0].AsDateTime:
=now;
table1.Fields[1].AsString:
=floattostr(diwei1);
table1.Fields[2].AsFloat:
=shangxian1;
table1.Fields[3].AsFloat:
=xiaxian1;
table1.Fields[4].AsString:
=floattostr(diwei2);
table1.Fields[5].AsFloat:
=shangxian2;
table1.Fields[6].AsFloat:
=xiaxian2;
table1.Post;
end;
procedureTForm1.FindFirstFamily(family:
SHandle:
longint);
var
i,flag:
romstr:
string;
rom:
array[0..8]ofsmallint;
{Setuptofindthefirstdevicewiththefamily'
family'
}
if(TMFamilySearchSetup(SHandle,@stateBuf,family)=1)then
if(TMNext(SHandle,@stateBuf)=1)then
{Readtheromnumberbysettingrom[0]to0forreadingandusingTMRom}
rom[0]:
=0;
TMRom(SHandle,@stateBuf,@rom);
{Checkifcorrecttype}
if((familyand$7F)=(rom[0]and$7F))then
fori:
=7downto0do
=romstr+IntToHex(ROM[i],2);
Label3.caption:
SerialROMID1:
'
+romstr;
ReadTemperature1(SHandle);
ThereisnoTemperatureDeviceontheport'
halt;
procedureTForm1.ReadTemperature1(session_handle:
tsht,i,tmp1:
cr,cpc,tmpf,tmp:
Extended;
rbuf:
array[0..9]ofsmallint;
st:
longint;
CRCByte,xiaxianbyte:
Byte;
tmp:
=0.00;
{accessthedevice}
if(TMAccess(session_handle,@StateBuf)=1)then
{SendtherecallE2command(bysetting$B8tooutbyteinTMTouchByte)
makesureScratchiscorrect}
TMTouchByte(session_handle,$B8);
{SendthestartTcommand}
if(TMAccess(session_handle,@StateBuf)=1)then
{PreparethestrongpullupafternextTMTouchByte}
TMOneWireLevel(session_handle,LEVEL_SET,LEVEL_STRONG_PULL_UP,PRIMED_BYTE);
{Sendtheconversioncommand(bysetting$44tooutbyteinTMTouchByte)}
TMTouchByte(session_handle,$44);
{Sleepforasecond}
=GetTickCount+1000;
While(GetTickCount<
st)do
TMValidSession(Session_handle);
{Disablethestrongpullup}
TMOneWireLevel(session_handle,LEVEL_SET,LEVEL_NORMAL,PRIMED_NONE);
{verifyconversioniscompletebysetting$01tooutbitinTMTouchBitand
checkthereturnvaluewith1}
if(TMTouchBit(session_handle,$01)=$01)then
{Accessdevice}
If(TMAccess(session_handle,@StateBuf)=1)then
{Sendreadscratchcommandbysetting$BEtooutbyteinTMTouchByte}
TMTouchByte(session_handle,$BE);
CRC8:
{Readscratch(setting$FFtooutbyteinTMTouchByte)andcheckcrcfor
eachbyte}
=0to7do
rbuf[i]:
=TMTouchByte(session_handle,$FF);
CRCByte:
=Byte(rbuf[i]);
{thebytetorunthroughCRC8routine}
=TMCRC(1,@CRCByte,CRC8,0);
{Checkcrc}
=Byte(TMTouchByte(session_handle,$FF));
if(CRC8=0)then
{Calculatethetemperarure
tsht:
=rbuf[0];
if((rbuf[1]and$01)=1)then
=tshtor(-256);
tmp1:
=Round((tsht)/2);
=tmp1;
cr:
=rbuf[6];
cpc:
=rbuf[7];
if(rbuf[7]<
>
0)then
=tmp-(0.25)+(cpc-cr)/cpc;
}
if((rbuf[1]and$F8)=$F8)then
BEGIN
END
ELSE
case(rbuf[4]and$60)of
$00:
fenbianlv1:
=9;
tmp:
=(rbuf[1]and$07)*16+(rbuf[0]and$f8)/16;
diwei1:
=(rbuf[0