
课程论文
题 目: DS18B20
作 者: 吉兵
学 号: 20081303001
所在学院: 信息科学与工程学院
专业年级: 电信08-1
指导老师:
职 称:
2010 年 10 月 7日
数字温度传感器 DS1820(DS18B20)的应用
DSl820 数字温度计提供 9 位(二进制)温度读数 指示器件的温度 信息经过单线接口送入 DSl820 或从 DSl820 送出 因此从主机 CPU 到DSl820 仅需一条线(和地线) DSl820 的电源可以由数据线本身提供而不需要外部电源 因为每一个 DSl820 在出厂时已经给定了唯一的序号 因此任意多个 DSl820 可以存放在同一条单线总线上 这允许在许多不同的地方放置温度敏感 DSl820 的测量范围从-55 到+125 增量值为 0.5 可在 l s(典型值)内把温度变换成数字.每一个 DSl820 包括一个唯一的 位长的序号 该序号值存放在 DSl820 内部的 ROM(只读存贮器)中 开始8 位是产品类型编码(DSl820 编码均为(10H)接着的48位是每个器件唯一的序号最后8位是前面 56位的CRC(循环冗余校验)码DSl820 中还有用于贮存测得的温度值的两个 8 位存贮器 RAM 编号为 0 号和 1号1号存贮器存放温度值的符号,如果温度为负,则 1 号存贮器 8 位全为 1,否则全为 0, 0 号存贮器用于存放温度值的补码,LSB(最低位)的1表示0.5将存贮器中的二进制数求补再转换成十进制数并除以 2 就得到被测温度值(-550 125 ),DSl820 的引脚如图 2 26-l 所示 。每只 DS18b20 都可以设置成两种供电方式 :即数据总线供电方式和外部供电方式 ,采取数据总线供电方式可以节省一根导线 ,但完成温度测量的时间较长;采取外部供电方式则多用一根导线,但测量速度较快.
温度计算
1、DS18b20用9位存贮温度值,最高位为符号位。下图为 18b20 的温度存储方式,负温度 S=1,正温度 S=0,如00AAH 为+85 ,0032H 为 25, FF92H 为55
2、Ds18b20 用 12 位存贮温值度,最高位为符号位 ,下图为18b20的温度存储方式,负温度S=1,正温度 S=0。如0550H 为+85,0191H 为25.0625 ,FC90H 为-55
二DSl820 工作过程及时序
DSl820 工作过程中的协议如下
初始化RoM 操作命令 存储器操作命令 处理数据
1初始化
单总线上的所有处理均从初始化开始
2 ROM 操作品令
总线主机检测到 DSl820 的存在便可以发出 ROM 操作命令之一 这些命令如
代码 指令
Read ROM(读 ROM) [33H]
Match ROM(匹配 ROM) [55H]
Skip ROM(跳过 ROM] [CCH]
Search ROM(搜索 ROM) [F0H]
Alarm search(告警搜索) [ECH]
3存储器操作命令
代码 指令
Write Scratchpad(写暂存存储器) [4EH]
Read Scratchpad(读暂存存储器) [BEH]
Copy Scratchpad(复制暂存存储器) [48H]
Convert Temperature(温度变换) [44H]
Recall EPROM(重新调出) [b8H]
Read Power supply(读电源) [b4H]
4 时序
主机使用时间隙(time slots)来读写 DSl820 的数据位和写命令字的位
(1)初始化
时序见图 2.25-2主机总线 to 时刻发送一复位脉冲(最短为 480us 的低电平信号)接着在 tl 时刻释放总线并进入接收状DSl820 在检测到总线的上升沿之后 等待 15-60us接DS1820 在 t2 时刻发出存在脉冲(低电平持续 60-240 us)如图中虚线所示以下子程序在 MCS51 仿真机上通过其晶振为 12M. 初始化子程序
C语言程序:
#include #include sbit DQ=P2^0; unsigned int p[6]; unsigned char code buff[12]={0X3f,0X06,0X5b,0X4f,0X66, 0X6d,0X7d,0X07,0X7f,0X6f,0x40,0x00 }; void delay(unsigned char delay_time) { while(delay_time) delay_time--; } void init() { DQ=0; delay(50); DQ=1; delay(4); while(DQ==1); delay(52); DQ=1; _nop_(); } /*void wait() { unsigned char i; while(DQ); while(~DQ); i = 4; while (i>0) i--; } */ void write_byte(unsigned int date) { unsigned char n; for(n=0;n<8;n++) { DQ=0; _nop_(); if(date&0x01==1) DQ=1; delay(20); date=date>>1; DQ=1; _nop_(); } delay(5); } unsigned int read_byte() { unsigned int m,rt=0; bit b; for(m=0;m<8;m++) { DQ=0; _nop_(); DQ=1; b=DQ; delay(12); rt>>=1; if(b) rt=rt|0x80; DQ=1; _nop_(); } delay(10); return(rt); } void ds18b20() { unsigned int msb=0,lsb=0; unsigned char t1=0; unsigned int t2=0; unsigned int t3=0; unsigned int flag; init(); write_byte(0xcc); _nop_(); write_byte(0x44); delay(5); init(); write_byte(0xcc); write_byte(0xbe); lsb=read_byte(); msb=read_byte(); if((msb&0xf0)>=1) flag=1; else flag=0; if(flag) { msb=~msb; lsb=~lsb+1; } P3=msb; t3=(msb<<4)|(lsb>>4);t1=t3*0.625; //t2=(lsb&0x0f)*0.0625*10000; if(flag) {p[0]=10;} else {p[0]=11;} p[1]=t1/100; p[2]=(t1/10)%10; p[3]=t1%10; } void display() { unsigned int j,temp=0xdf; for(j=0;j<6;j++) { P1=temp; if(j==3) { P0=buff[p[j]]|0x80; } else { P0=buff[p[j]]; } temp=(temp>>1)|0x80; delay(5000); } } void main() { while(1) { ds18b20(); display(); } }
