094 温度程序.docx
《094 温度程序.docx》由会员分享,可在线阅读,更多相关《094 温度程序.docx(15页珍藏版)》请在冰点文库上搜索。
![094 温度程序.docx](https://file1.bingdoc.com/fileroot1/2023-5/27/7294d635-1f35-46de-ba7f-2e29f192b682/7294d635-1f35-46de-ba7f-2e29f192b6821.gif)
094温度程序
题目:
温度传感器课外作业
学院:
机电信息工程学院
年级专业:
自动化094
学号:
20090234152007050415
学生姓名:
陆成超姜东镇
指导教师:
谢春利
目录
1.ds18b20的简介………………………………………
2.作业的目的…………………………………………..
3.原理图………………………………………………..
4.程序清单……………………………………………..
一.DS18B20温度传感器使用简介
DS18xx系列温度传感器是数字式温度传感器,相对于传统温度传感器精度高、稳定性好、电路简单、控制方便,在这里以DS18B20为例做简单应用介绍。
详细资料请参阅芯片手册。
(一)、特性:
(1)应用中不需要外部任何元器件即可实现测温电路。
(2)测温范围-55~+125℃,最大精度0.0625℃。
(3)只通过一条数据线即可实现通信。
(4)每个DS1820器件上都有独一无二的序列号,所以一条数据线上可以挂接很多该传感器。
(5)内部有温度上、下限告警功能。
(二)、操作简介
DS18B20工作时需要接收特定的指令来完成相应功能(指令,可以简单的理解为可以被识别并有相应意义的一系列高低电平信号),它的指令可分为ROM指令和RAM指令;ROM指令主要对其内部的ROM进行操作,如查所使用DS18B20的序列号等,如果只使用一个DS18B20,ROM操作一般就可以直接跳过了;RAM指令主要是完成对其内RAM中的数据进行操作,如让其开始进行数据采集、读数据等。
DS18B20数字温度传感器是单总线器件,数据的读写只通过一条数据线进行并且这一条线上允许挂很多该传感器;这样对器件进行读写指令时就会麻烦一些,必须应用特定时序来识别高低电平信号(如写高电平1,并不是把数据线直接拉高,而是用有一定时序关系的高低电平来代表写1),所以指令表中的0、1在写给DS18B20时就得变成代表0、1电平的时序段序列。
同样,从DS18B20读数据时,也是由特定的时序来完成数据读取。
对DS18B20进行读写的时序图如下:
硬件连接方式有两种,一种是由单独电源供电(3~5V);第二种是由数据线为DS18B20供电(工作速度相对较慢)。
单独电源供电方式
数据线为DS1820供电方式
(三)、DS1820的工作过程:
1.复位操作
2.执行ROM操作的5条指令之一:
1)读ROM,2)匹配ROM,3)搜索ROM,4)跳过ROM,5)报警搜索。
3.存储器操作命令:
温度转换、读取温度、设定上下限温度值等指令
4.读取温度数据:
主机读取温度数据后进行数据处理。
可以初始化数据精度,按芯片手册写入固定指令。
数据位数可设置成9、10、11、12位,其中7位为温度整数部分,1位表示温度正负,其余位数为小数。
如9位数据时,有1位为小数,精度为0.5。
(四)、指令功能介绍:
(1)ROM操作指令:
1.读ROM指令:
ReadROM[33h]
这个命令允许总线控制器读到DS1820的8位系列编码、唯一的序列号和8位CRC码。
只有在总线上存在单只DS1820的时候才能使用这个命令。
如果总上有不止一个从机,当所有从机试图同时传送信号时就会发生数据冲突(漏极开路连在一起开成相与的效果)。
2.匹配ROM指令:
MatchROM[55h]
匹配ROM命令,后跟64位ROM序列,让总线控制器在多点总线上定位一只特定的DS1820。
只有和64位ROM序列完全匹配的DS1820才能响应随后的存储器操作命令。
所有和64位ROM序列不匹配的从机都将等待复位脉冲。
这条命令在总线上有单个或多个器件时都可以使用。
3.跳过ROM指令:
SkipROM[CCh]
这条命令允许总线控制器不用提供64位ROM编码就使用存储器操作命令,在单点总线情况下右以节省时间。
如果总线上不止一个从机,在SkipROM命令之后跟着发一条读命令,由于多个从机同时传送信号,总线上就会发生数据冲突(漏极开路下拉效果相当于相与)。
4.搜索ROM指令:
SearchROM[F0h]
当一个系统初次启动时,总线控制器可能并不知道单线总线上有多少器件或它们的64位ROM编码。
搜索ROM命令允许总线控制器用排除法识别总线上的所有从机的64位编码。
5.报警搜索指令:
AlarmSearch[ECh]
这条命令的流程图和SearchROM相同。
然而,只有在最近一次测温后遇到符合报警条件的情况,DS18B20才会响应这条命令。
报警条件定义为温度高于TH或低于TL。
只要DS18B20不掉电,报警状态将一直保持,直到再一次测得的温度值达不到报警条件。
(2)存储器操作指令:
(五)、复位时序:
DS18B20需要严格的协议以确保数据的完整性。
协议包括几种单线信号类型:
复位脉冲、存在脉冲、写0、写1、读0和读1。
所有这些信号,除存在脉冲外,都是由总线控制器发出的。
和DS18B20间的任何通讯都需要以初始化序列开始,初始化序列见上图。
一个复位脉冲跟着一个存在脉冲表明DS18B20已经准备好发送和接收数据(适当的ROM命令和存储器操作命令)。
(六)、数据处理:
下面以9位温度数据格式为例。
DS18B20内部对此计算的结果可提供0.5℃的分辨力。
温度以16位带符号位扩展的二进制补码形式读出,表1给出了温度值和输出数据的关系。
数据通过单线接口以串行方式传输。
DS1820测温范围-55℃~+125℃,以0.5℃递增。
如用于华氏温度,必须要用一个转换因子查找表。
读取数据时需要读取前16位数据,低字节在前,高字节为符号为。
DS1820内温度表示值为1/2℃LSB,如下所示9位格式:
表1温度值和输出数据的关系
二.作业目的
通过温度传感器和单片机系统,做出一个测温系统。
这个系统能把周围的环境温度通过单片机系统的显示屏显示出来。
三.原理图
四.程序清单
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P3^1;
sbitEN=P0^5;
sbitRW=P0^6;
sbitRS=P0^7;
unsignedcharcodestr1[]={"Thetemperatureis:
"};
unsignedcharcodestr2[]={""};
uchardatadisdata[5];
uintvalue;
ucharflag;
voiddelay1ms(unsignedintms)
{
unsignedinti,j;
for(i=0;ifor(j=0;j<100;j++);
}
voidwr_com(unsignedcharcom)
{
delay1ms
(1);
RS=0;
RW=0;
EN=0;
P2=com;
delay1ms
(1);
EN=1;
delay1ms
(1);
EN=0;
}
voidwr_dat(unsignedchardat)
{
delay1ms
(1);;
RS=1;
RW=0;
EN=0;
P2=dat;
delay1ms
(1);
EN=1;
delay1ms
(1);
EN=0;
}
voidlcd_init()
{
delay1ms(15);
wr_com(0x38);delay1ms(5);
wr_com(0x08);delay1ms(5);
wr_com(0x01);delay1ms(5);
wr_com(0x06);delay1ms(5);
wr_com(0x0c);delay1ms(5);
}
voiddisplay(unsignedchar*p)
{
while(*p!
='\0')
{
wr_dat(*p);
p++;
delay1ms
(1);
}
}
voidinit_play()
{
lcd_init();
wr_com(0x80);
display(str1);
wr_com(0xc0);
}
voiddelay_18B20(unsignedinti)
{
while(i--);
}
voidds1820rst()
{
unsignedcharx=0;
DQ=1;
delay_18B20(4);
DQ=0;
delay_18B20(100);
DQ=1;
delay_18B20(40);
}
uchards1820rd()
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
voidds1820wr(ucharwdata)
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=wdata&0x01;
delay_18B20(10);
DQ=1;
wdata>>=1;
}
}
read_temp()
{
uchara,b;
ds1820rst();
ds1820wr(0xcc);
ds1820wr(0x44);
ds1820rst();
ds1820wr(0xcc);
ds1820wr(0xbe);
a=ds1820rd();
b=ds1820rd();
value=b;
if(a>=tg){baojing=0;laba=0;}
else{baojing=1;laba=1;}
if(a<=td){baojing=0;laba=0;}
else{baojing=1;laba=1;}
value<<=8;
value=value|a;
if(value<0x0fff)
flag=0;
else
{
value=~value+1;
flag=1;
}
value=value*(0.625);
}
voidds1820disp()
{
ucharflagdat;
disdata[0]=value/1000+0x30;
disdata[1]=value%1000/100+0x30;
disdata[2]=value%100/10+0x30;
disdata[3]=value%10+0x30;
if(tflag==0)
flagdat=0x20;
else
flagdat=0x2d;
if(disdata[0]==0x30)
{
disdata[0]=0x20;
if(disdata[1]==0x30)
{
disdata[1]=0x20;
}
}
wr_com(0xc0);
wr_dat(flagdat);
wr_com(0xc1);
wr_dat(disdata[0]);
wr_com(0xc2);
wr_dat(disdata[1]);
wr_com(0xc3);
wr_dat(disdata[2]);
wr_com(0xc4);
wr_dat(0x2e);
wr_com(0xc5);
wr_dat(disdata[3]);
}
voidmain()
{
init_play();
while
(1)
{
read_temp();
ds1820disp();
}
}