基于AT89S52单片机与DS18B20的温度测量系统Word格式文档下载.docx
《基于AT89S52单片机与DS18B20的温度测量系统Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《基于AT89S52单片机与DS18B20的温度测量系统Word格式文档下载.docx(16页珍藏版)》请在冰豆网上搜索。
数字温度计的分辨率用户可以从9位到12位选择。
内部有温度上、下限告警设置。
TO-92封装的DS18B20的引脚排列见图4-2,其引脚功能描述见表4-1。
图4-2DS18B20引脚结构图(底视图)
表4-1 DS18B20详细引脚功能描述
序号
名称
引脚功能描述
1
GND
地信号
2
DQ
数据输入/输出引脚。
开漏单总线接口引脚。
当被用着在寄生电源下,也可以向器件提供电源。
3
VDD
可选择的VDD引脚。
当工作于寄生电源时,此引脚必须接地。
(3)DS18B20的内部结构
DS18B20的内部框图如图4-3所示。
64位ROM存储器件独一无二的序列号。
暂存器包含两字节(0和1字节)的温度寄存器,用于存储温度传感器的数字输出。
暂存器还提供一字节的上线警报触发(TH)和下线警报触发(TL)寄存器(2和3字节),和一字节的配置寄存器(4字节),使用者可以通过配置寄存器来设置温度转换的精度。
暂存器的5、6和7字节器件内部保留使用。
第八字节含有循环冗余码(CRC)。
使用寄生电源时,DS18B20不需额外的供电电源;
当总线为高电平时,功率由单总线上的上拉电阻通过DQ引脚提供;
高电平总线信号同时也向内部电容CPP充电,CPP在总线低电平时为器件供电。
图4-3DS18B20的内部框图
DS18B20加电后,处在空闲状态。
要启动温度测量和模拟到数字的转换,处理器须向其发出ConvertT[44h]命令;
转换完后,DS18B20回到空闲状态。
温度数据是以带符号位的16-bit补码存储在温度寄存器中的,如图4-4所示:
图4-4温度寄存器格式
符号位说明温度是正值还是负值,正值时S=0,负值时S=1。
表4-2给出了一些数字输出数据与对应的温度值的例子。
表4-2温度/数据的关系
(4)DS18B20的命令序列
初始化
ROM命令跟随着需要交换的数据;
功能命令跟随着需要交换的数据。
访问DS18B20必须严格遵守这一命令序列,如果丢失任何一步或序列混乱,DS18B20都不会响应主机(除了SearchROM和AlarmSearch这两个命令,在这两个命令后,主机都必须返回到第一步)。
①初始化:
DS18B20所有的数据交换都由一个初始化序列开始。
由主机发出的复位脉冲和跟在其后的由DS18B20发出的应答脉冲构成。
当DS18B20发出响应主机的应答脉冲时,即向主机表明它已处在总线上并且准备工作。
②ROM命令:
ROM命令通过每个器件64-bit的ROM码,使主机指定某一特定器件(如果有多个器件挂在总线上)与之进行通信。
DS18B20的ROM如表4-3所示,每个ROM命令都是8bit长。
表4-3DS18B20ROM命令
命令
描述
协议
此命令发出后1-Wire
总线上的活动
SEARCHROM
识别总线上挂着的所有DS18B20的ROM码
F0h
所有DS18B20向主机
传送ROM码
READROM
当只有一个DS18B20挂在总线上时,可用此命令来读取ROM码
33h
DS18B20向主机传送ROM码
MATCHROM
主机用ROM码来指定某一DS18B20,只有匹配的DS18B20才会响应
55h
主机向总线传送一个ROM码
SKIPROM
用于指定总线上所有的器件
CCh
无
ALARMSEARCH
与SEARCHROM命令类似,但只有温度超出警报线的DS18B20才会响应
ECh
超出警报线的DS18B20
向主机传送ROM码
③功能命令:
主机通过功能命令对DS18B20进行读/写Scratchpad存储器,或者启动温度转换。
DS18B20的功能命令如表4-4所示。
表4-4DS18B20功能命令
命令
温度转换命令
ConvertT
开始温度转换
44h
DS18B20向主机传送转换状态(寄生电源不适用)
存储器命令
ReadScratchpad
读暂存器完整的数据
BEh
DS18B20向主机传送
总共9字节的数据
WriteScratchpad
向暂存器的2、3和4字节写入数据(TH,TL和精度)
4Eh
主机向DS18B20传送
3个字节的数据
CopyScratchpad
将TH,TL和配置寄存器的数据复制到EEPROM
48h
RecallE2
将TH,TL和配置寄存器的数据从EEPROM中调到暂存器中
B8h
DS18B20向主机传送调用状态
ReadPowerSupply
向主机示意电源供电状态
B4h
DS18B20向主机传送供电状态
(5)DS18B20的信号方式
DS18B20采用严格的单总线通信协议,以保证数据的完整性。
该协议定义了几种信号类型:
复位脉冲、应答脉冲、写0、写1、读0和读1。
除了应答脉冲所有这些信号都由主机发出同步信号。
总线上传输的所有数据和命令都是以字节的低位在前。
1初始化序列:
复位脉冲和应答脉冲
在初始化过程中,主机通过拉低单总线至少480µ
s,以产生复位脉冲(TX)。
然后主机释放总线并进入接收(RX)模式。
当总线被释放后,5kΩ的上拉电阻将单总线拉高。
DS18B20检测到这个上升沿后,延时15µ
s~60µ
s,通过拉低总线60µ
s~240µ
s产生应答脉冲。
初始化波形如图4-5所示。
图4-5初始化脉冲
②读和写时序
在写时序期间,主机向DS18B20写入数据;
而在读时序期间,主机读入来自DS18B20的数据。
在每一个时序,总线只能传输一位数据。
读/写时序如图3-6所示。
✧写时序
存在两种写时序:
“写1”和“写0”。
主机在写1时序向DS18B20写入逻辑1,而在写0时序向DS18B20写入逻辑0。
所有写时序至少需要60µ
s,且在两次写时序之间至少需要1µ
s的恢复时间。
两种写时序均以主机拉低总线开始。
产生写1时序:
主机拉低总线后,必须在15µ
s内释放总线,然后由上拉电阻将总线拉至高电平。
产生写0时序:
主机拉低总线后,必须在整个时序期间保持低电平(至少60µ
s)。
在写时序开始后的15µ
s期间,DS18B20采样总线的状态。
如果总线为高电平,则逻辑1被写入DS18B20;
如果总线为低电平,则逻辑0被写入DS18B20。
✧读时序
DS18B20只能在主机发出读时序时才能向主机传送数据。
所以主机在发出读数据命令后,必须马上产生读时序,以便DS18B20能够传送数据。
所有读时序至少60µ
s,且在两次独立的读时序之间至少需要1µ
每次读时序由主机发起,拉低总线至少1µ
s。
在主机发起读时序之后,DS18B20开始在总线上传送1或0。
若DS18B20发送1,则保持总线为高电平;
若发送0,则拉低总线。
当传送0时,DS18B20在该时序结束时释放总线,再由上拉电阻将总线拉回空闲高电平状态。
DS18B20发出的数据在读时序下降沿起始后的15µ
s内有效,因此主机必须在读时序开始后的15µ
s内释放总线,并且采样总线状态。
图4-6DS18B20读/写时序图
DS18B20在使用时,一般都采用单片机来实现数据采集。
只需将DS18B20信号线与单片机1位I/O线相连,且单片机的1位I/O线可挂接多个DS18B20,就可实现单点或多点温度检测。
(6)小数的显示方法
DS18B20转换后的数据有四位二进制小数,精度为0.0625,可连续表示一位十进制小数,因此在数码显示时,只显示1位小数。
在对四位二进制小数进行处理时,可先计算出这四位二进制小数对应的四位十进制小数,然后对这四位十进制小数舍弃后三位,只保留一位。
在编写程序时,可编制一个反映二进制小数与显示码对应关系的表格,根据四位二进制小数的十六种不同情况查找对应的一位十进制小数的段码,具体映射关系如表4-5所示:
表4-5二进制小数与显示码的对应关系
二进制小数位
四位十进制小数
保留一位
对应显示码(共阴)
0000
0.0000
3FH
0001
0.0625
06H
0010
0.1250
0011
0.1875
5BH
0100
0.2500
4FH
0101
0.3125
0110
0.3750
4
66H
0111
0.4375
1000
0.5000
5
6DH
1001
0.5625
6
7DH
1010
0.6250
1011
0.6875
7
07H
1100
0.7500
8
7FH
1101
0.8125
1110
0.8750
9
6FH
1111
0.9375
4.程序设计流程
5.C语言程序源代码
/*---------------------------------------------------
名称:
编写:
吴善刚
日期:
2011-07-17
内容:
用AT89S52控制DS18B2,读取数据并在数码管上显示
----------------------------------------------------*/
//包含头文件,程序开始
#include<
reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P2^4;
//18B20数据线引脚
unsignedcharflag;
//负数标志
//行扫描数组
ucharcodescan[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//数码管显示的段码表
ucharcodetable[13]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x39,0x00};
//小数部分显示查询表
ucharcodeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
uchardispbuf[8];
//显示缓冲区
uchartemper[2];
//存放温度的数组
//延时函数
voiddelay(unsignedintus)
{
while(us--);
}
//DS18B20复位函数
voidreset(void)
ucharx=0;
DQ=1;
delay(8);
DQ=0;
delay(80);
delay(14);
x=DQ;
delay(20);
//从DS18B20中读一个字节
ucharreadbyte(void)
uchari=0;
uchardat=0;
for(i=8;
i>
0;
i--)
{
DQ=0;
dat>
>
=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
//向DS18B20中写一个字节
voidwritebyte(unsignedchardat)
DQ=dat&
0x01;
delay(5);
delay(4);
//从DS18B20中读取实时温度值
voidreadtemp(void)
uchara=0,b=0;
reset();
writebyte(0xCC);
//跳过序列号
writebyte(0x44);
//启动温度转换
writebyte(0xBE);
//读九个寄存器,前两个为温度
a=readbyte();
//低位
b=readbyte();
//高位
if(b>
0x0f)//判断是否为负值
a=~a+1;
if(a==0)
b=~b+1;
else
b=~b;
flag=10;
else
flag=12;
temper[0]=a&
0x0f;
a=a>
4;
temper[1]=b<
<
temper[1]=temper[1]|a;
//动态扫描显示函数
voidscandisp()
unsignedchari,value;
for(i=0;
i<
8;
i++)
P3=0xff;
value=table[dispbuf[i]];
if(i==3)
value|=0x80;
P0=value;
P3=scan[i];
delay(50);
//主函数
voidmain()
uchartemp,temp1;
while
(1)
scandisp();
readtemp();
temp1=temper[0];
temp=temper[1];
dispbuf[4]=ditab[temp1];
dispbuf[1]=temp/100;
dispbuf[3]=temp%10;
temp=temp/10;
dispbuf[2]=temp%10;
dispbuf[0]=flag;
dispbuf[5]=11;