DS18B20温度测量显示实验
发布时间:2006年8月15日 19时10分
[实验要求]
用单片机控制实验板上的DS18B20数字温度传感器,读取当前环境温度,精度达0.1度,温度范围0-99度,并用数码管的前三位显示出来。同时实验板上的单片机还能把温度值通过串口线发送到计算机,在计算机上安装该目录下的.exe文件后,打开应用程序可看到温度值。
注意:DS18B20 数字温度传感器是DALLAS 公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。DS18B20 产品的特点(1)、只要求一个I/O 口即可实现通信。(2)、在DS18B20 中的每个器件上都有独一无二的序列号。(3)、实际应用中不需要外部任何元器件即可实现测温。(4)、测量温度范围在
-55 到+125摄氏度之间。(5)、数字温度计的分辨率用户可以从9 位到12 位选择。(6)、内部有温度上、下限告警设置。
DS18B20 详细引脚功能描述1、GND 地信号;2、DQ数据输入出引脚。开漏单总线接口引脚。当被用在寄生电源下,也可以向器件提供电源;3、VDD可选择的VDD 引脚。当工作于寄生电源时,此引脚必须接地。DS18B20 的使用方法。由于DS18B20 采
用的是1-Wire 总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S52 单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。
[实验目的]
学习单总线器件的读写方法,数值合成,数字类型变化等。
[硬件电路]
[源代码]
//安装目录下的EXE文件,通过串口线连接计算机与实验板,打开
//软件后可在软件界面上显示当前温度值。
#include #define uchar unsigned char #define uint unsigned int sbit DS=P2^2; //define interface 定义DS18B20接口 uint temp; // variable of temperature uchar flag1; // sign of the result positive or negative sbit dula=P2^6; sbit wela=P2^7; unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//不带小数点编码。 unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,0xff,0xef}; //带小数点编码。 void delay(uint count) //delay { uint i; while(count) { i=200; while(i>0) i--; count--; } } ///////功能:串口初始化,波特率9600,方式1/////// void Init_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } void dsreset(void) //send reset and initialization command { uint i; //DS18B20初始化 DS=0; i=103; while(i>0)i--; DS=1; i=4; while(i>0)i--; } bit tmpreadbit(void) //read a bit 读一位 { uint i; bit dat; DS=0;i++; //i++ for delay 小延时一下 DS=1;i++;i++; dat=DS; i=8;while(i>0)i--; return (dat); } uchar tmpread(void) //read a byte date 读一个字节 { uchar i,j,dat; dat=0; for(i=1;i<=8;i++) { j=tmpreadbit(); dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好//一个字节在DAT里 } return(dat); //将一个字节数据返回 } void tmpwritebyte(uchar dat) //write a byte to ds18b20 { //写一个字节到DS18B20里 uint i; uchar j; bit testb; for(j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if(testb) //write 1 { DS=0; i++;i++; DS=1; i=8;while(i>0)i--; } else { DS=0; //write 0 写1部分 写0部分 i=8;while(i>0)i--; DS=1; i++;i++; } } } void tmpchange(void) //DS18B20 begin change 发送温度转换命令 { dsreset(); //初始化DS18B20 delay(1); //延时 tmpwritebyte(0xcc); // 跳过序列号命令 tmpwritebyte(0x44); //发送温度转换命令 } uint tmp() //get the temperature 获得温度 { float tt; uchar a,b; dsreset(); delay(1); tmpwritebyte(0xcc); tmpwritebyte(0xbe); a=tmpread(); b=tmpread(); temp=b; temp<<=8; temp=temp|a; //发送读取数据命令 //连续读两个字节数据 //two byte compose a int variable //两字节合成一个整型变量。 tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20 //可以精确到0.0625度,所以读回数据的最低位代表的是 //0.0625度。 temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位 //也转换为可显示数字,同时进行一个四舍五入操作。 return temp; //返回温度值 } void readrom() //read the serial 读取温度传感器的序列号 { //本程序中没有用到此函数 uchar sn1,sn2; dsreset(); delay(1); tmpwritebyte(0x33); sn1=tmpread(); sn2=tmpread(); } void delay10ms() //delay { uchar a,b; for(a=10;a>0;a--) for(b=60;b>0;b--); } void display(uint temp) //显示程序 { uchar A1,A2,A2t,A3,ser; ser=temp/10; //分离出三位要显示的数字 SBUF=ser; A1=temp/100; A2t=temp%100; A2=A2t/10; A3=A2t%10; dula=0; P0=table[A1]; dula=1; dula=0; wela=0; P0=0x7e; wela=1; wela=0; //显示百位 delay(1); dula=0; P0=table1[A2]; dula=1; dula=0; wela=0; P0=0x7d; wela=1; wela=0; delay(1); P0=table[A3]; dula=1; dula=0; //显示十位 带小数点的 //显示个位 P0=0x7b; wela=1; wela=0; delay(1); } void main() { uchar a; Init_Com(); do { tmpchange(); for(a=10;a>0;a--) //主函数 //初始化串口 //温度转换 { display(tmp()); //显示十次 } } while(1); } 因篇幅问题不能全部显示,请点此查看更多更全内容