C51单片机12(温度传感器)_第1页
C51单片机12(温度传感器)_第2页
C51单片机12(温度传感器)_第3页
C51单片机12(温度传感器)_第4页
C51单片机12(温度传感器)_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第12讲温度传感器温度传感器概述温度传感器DS1820Dallas公司生产的数字温度传感器单总线接口方式,只需要与MCU的一个端口连接即可实现双向通信可以直接将温度转化成串行数字信号只有三个引脚(VDD、GND、DQ)同一总线上可以挂接多个温度传感器芯片适用于远距离多点温度检测+5V供电,也可以在信号线上高电平时为内部电容充电,供低电平时消耗电源极性接反时,芯片发烫,但不会烧坏主要性能指标温度测量范围:-55℃~+125℃温度测量精度:±0.5℃(-10℃~+85℃)温度数字量转换时间:200ms(典型值)DS18B20的外观与引脚DALLASDS18B20123GNDDQVDDOOO123仰视图正视图DS1820内部结构框图64位ROM和单线端口电源检测VDD存储器和控制逻辑温度传感器上限触发TH下限触发TL8位CRC产生器暂存器内部VDD工作过程内部低温度系统振荡器振荡频率随温度变化很小,为计数器1提供一个频率稳定的计数脉冲内部高温度系统振荡器振荡频率对温度很敏感,为计数器2提供一个频率随温度变化的计数脉冲温度测量原理低温度系数振荡器高温度系数振荡器计数器1计数器2温度寄存器斜坡累加器比较预置=0?=0?预置增加停止温度测量过程初始时温度寄存器被预置成-55℃计数器1被预置成与-55℃相对应的一个量计数器1从预置数开始减计数到0时,温度寄存器中的温度值增加1℃斜率累加器为计数器1提供新的计数值计数器1开始新的减计数,这个过程重复进行,直到计数器2计数到0为止除初始值以外,计数器1每一个循环的预置数都由斜率累加器提供为了补偿振荡器温度特性的非线性,斜率累加器提供的预置数将随温度而相应变化(也就是说,在不同温度范围时,使温度寄存器值增加1℃所需要的计数个数是不同的)DS18B20芯片的地址编码当单一总线上挂接多个DS18B20芯片时,使用64位光刻ROM地址来区别不同芯片64位地址码是产品出厂前光刻好的产品类型标号(说明是温度传感器)序列号(与网卡MAC地址相似)CRC码(CRC=X8+X5+X4+1,用于校验)8位CRC码48位序列号8位产品类型标号DS18B20的操作指令0x33——读取ROM。读传感器ROM中的64位编码0x55——匹配ROM。发出此命令后,接着发出64位编码,访问单一总线上相应的DS18B20,并使之做出响应,为读写做准备0xF0——搜索ROM。用于确定挂接在同一总线上的DS18B20芯片数,识别64位地址,为操作各器件做准备0xCC——跳过ROM。当总线上只有一个温度传感器芯片时,忽略64位地址,直接向DS18B20发出命令0xEC——告警搜索。执行后,只有温度超过预设上、下限的芯片才做出响应DS18B20的操作指令44H——温度转换。启动DS18B20进行温度转换,结果存入内部RAMBEH——读暂存器。读内部RAM中的温度数据4EH——写暂存器。发出向内部RAM第2、3字节写上、下限值的命令,紧接着传送2字节数据48H——复制暂存器。将内部RAM第2、3字节内容复制到EEPROMB8H——重调EEPROM。将EEPROM中内容恢复到内部RAM第2、3字节B4H——读供电方式。读得0,DS18B20采用寄生供电;读得1,DS18B20利用外接电源供电DS18B20内部RAM地址安排9字节存储器内容字节地址温度值低位0温度值高位1温度上限值2温度下限值3配置寄存器4保留5保留6保留7CRC校验值8DS18B20的温度数据存储格式位7位6位5位4位3位2位1位0232221202-12-22-32-4位15位14位13位12位11位10位9位8SSSSS262524DS18B20的温度数据存储格式字节0字节1位7位6位5位4位3位2位1位0232221202-12-22-32-4位15位14位13位12位11位10位9位8SSSSS262524符号位(1:负值0:正值)测得数据×0.0625=实际温度值单个DS1820芯片与单片机的连接在有条件的情况下,最好每个温度传感器都使用独立电源接MCU初始化数据线置“1”延时(时间要求不严格,但尽量短一点)数据线置“0”延时750us(480~960us)数据线置“1”(15~60us)延时等待芯片返回的低电平若读到数据线上低电平0,再延时(从5开始至少480us)数据线再次置“1”,结束VccGND主控制器发出的480~960us芯片应答的60~240us15~60us初始化的子过程voiddsreset(void)//18B20复位,初始化函数{ //加电时已有一个初始高电平

uinti;

ds=0; //数据线上输出低电位并延时750us i=103;

while(i>0)i--;

ds=1; //数据线上输出高电位并延时30us i=4;

while(i>0)i--;}写数据数据线置“0”延时15us按从低到高的顺序,逐位发送数据延时45us数据线置“1”重复1~5步骤,直到发送完整个数据字节数据线再次置“1”,结束VccGND15us15us15us15us30us30usmintypmaxmintypmax主控制器写“0”时隙主控制器写“1”时隙写数据字节的子过程(方法一)voidtempwritebyte(uchar

dat)//向18B20写一个字节数据{

uinti;

ucharj; bittestb;

for(j=1;j<=8;j++) {

testb=dat&0x01; //判断写数据最低位

if(testb) //写"1" {

ds=0; //数据线输出低电平

i++;i++; //延时15us

ds=1; //数据线输出高电平(写"1")

i=8;while(i>0)i--; //延时>45us } else //写"0" {

ds=0; //数据线输出低电平

i=8;while(i>0)i--; //延时>45us

ds=1; //数据线输出高电平

i++;i++; //延时15us }

dat=dat>>1; //右移一位,准备下次写操作

}}写数据字节的子过程(方法二)voidds1820writebyte(ucharwdata) //ds1820写数据字节{

uchari=0;for(i=8;i>0;i--) //按从低到高的顺序,逐位输出数据字节

{ DQ=0; //数据线输出0 DQ=wdata&0x01; //准备写数据位(同时延时15us)

ds1820delay(10); //延时45us DQ=1; //数据线输出1

wdata>>=1; //右移一位,准备下次发送

}}DS18B20启动子过程voidtempchange(void) //{

dsreset(); //温度传感器复位

delay(1); //延时

tempwritebyte(0xcc); //写跳过读ROM指令

//(因为只有一个温度传感器) tempwritebyte(0x44); //写温度转换指令

//启动温度转换开始}读数据数据线置“1”延时2us数据线置“0”延时2us数据线置“1”延时4us读数据线,得到一个状态位,并进行数据处理延时30us重复1~7步骤,直到读完一个字节读数据字节的子过程(方法一)bittempreadbit(void) //读1个数据位{

uinti; bitdat;

ds=0;i++; //数据线拉低到0,延时2us

ds=1;i++;i++; //数据线拉高到1,延时4us

dat=ds; //读数据线,得到1个数据位

i=8;while(i>0)i--; //延时15us return(dat); //返回数据位}uchar

tempreadbyte(void) //读1个数据字节{

uchari,j,dat;

dat=0; //清除存储单元,准备接收数据

for(i=1;i<=8;i++) { j=tempreadbit(); //读取1个数据位

dat=(j<<7)|(dat>>1); //读出数据低位在前

}

return(dat);}读数据字节的子过程(方法二)uchards1820readbyte() //ds1820读数据字节{

uchari=0;

uchar

dat=0; for(i=8;i>0;i--) //逐位读取温度传器提供的数据

{ DQ=0; //数据线输出0

dat>>=1; //右移1位,准备用当前最高位存放读得的数据位

DQ=1; //数据线输出1,执行下面的语句相当于延时4us

if(DQ) //读数据线状态,得到一个数据位

dat|=0x80; //若读得状态位为1,保存到dat的当前最高位上

ds1820delay(10); //延时30us }

return(dat);}举例说明读数据字节的过程(1)设tempreadbit()第一次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=00000000dat=(j<<7)|(dat>>1); //dat=10000000举例说明读数据字节的过程(2)设tempreadbit()第二次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=01000000dat=(j<<7)|(dat>>1); //dat=11000000举例说明读数据字节的过程(3)设tempreadbit()第三次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=01100000dat=(j<<7)|(dat>>1); //dat=01100000举例说明读数据字节的过程(4)设tempreadbit()第四次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=00110000dat=(j<<7)|(dat>>1); //dat=10110000举例说明读数据字节的过程(5)设tempreadbit()第五次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=01011000dat=(j<<7)|(dat>>1); //dat=01011000举例说明读数据字节的过程(6)设tempreadbit()第六次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=00101100dat=(j<<7)|(dat>>1); //dat=00101100举例说明读数据字节的过程(7)设tempreadbit()第七次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=00010110dat=(j<<7)|(dat>>1); //dat=10010110举例说明读数据字节的过程(8)设tempreadbit()第八次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=01001011dat=(j<<7)|(dat>>1); //dat=01001011读取传感器中存储的温度数据uint

get_temp() //读取传感器中存储的温度数据{

uchar

a,b;

dsreset(); //温度传感器复位

delay(1); tempwritebyte(0xcc); //写跳过读ROM指令(因为只有一个温度传感器) tempwritebyte(0xbe); //读内部RAM的命令

a=tempreadbyte();//第一次读到的是低8位,地址自动修正

b=tempreadbyte();//第二次读到的是高8位

temp=b; //先保存高8位到temp temp<<=8; //左移8位,低8位以0填充

temp=temp|a; //两个字节组合为1个字

f_temp=temp*0.0625; //温度在寄存器中为12位分辨率位0.0625° temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入

f_temp=f_temp+0.05; returntemp; //temp是整型}temp和f_temp都是在程序开头定义的变量,在各过程中都有效温度值在LED数码管上显示voiddisp_temp(uintreal) //温度值转换成便于输出显示的形式{ LED[7]=0; LED[6]=real%10; //温度值小数点后第1位 LED[5]=(real/10)%10;

//温度值个位数 LED[4]=real/100; //温度值十位数}voiddisplay() //数码管显示{ P2=0; P0=table[LED[0]];delay(2); //表示第0号传感器

P2=4; P0=table[LED[4]];delay(2); //温度值十位数

P2=5; P0=table[LED[5]]|0x80;delay(2); //温度值个位数,包含小数点

P2=6; P0=table[LED[6]];delay(2); //温度值1/10位

P2=7; P0=table[LED[7]];delay(2); //温度值1/100位(实际上总为0)}数据定义#include<reg52.h>#include<stdio.h>#defineucharunsignedchar#defineuintunsignedintsbit

ds=P2^3;//温度传感器信号线uint

temp,realtemp;floatf_temp;ucharcodetable[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //0123456789ucharLED[8]={0,10,10,10,0,0,0,0};voiddelay(uintz) //延时函数{

uint

x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);}主控程序main()voidmain(){ while(1) { display();

tempchange(); display();

realtemp=get_temp(); display();

disp_temp(realtemp); }}由于一次温度采集的过程很长(超过2ms),故不便于利用中断方式控制LED数码管显示过程多点温度采集需要解决的问题:系统中共包含多少个温度传感器?怎样区分不同的温度传感器?怎样对指定的温度传感器执行操作?执行操作的时间有多长?温度数据传输的最大距离有多远?温度传感器的供电问题怎样解决?多点测温网络的构建方法多个DS18B20挂接在同一条总线上在硬件系统搭建时,先读取DS18B20的ROM序列号,并将它们固化在程序中(如数组),单片机向总线发送匹配ROM命令之后,紧跟发送一个序列号,接下来读取的温度数据就来自与ROM序列号匹配的那个DS18B20每一个I/O口挂接一个DS18B20利用SEARCHROM指令动态搜索64位ROM码(二叉树遍历)二叉树遍历SEARCHROM指令:发出searchrom

指令后,ds18b20将所有的第一位0,0,0放到总线上,单片机读到的是相与的结果为0。接着ds18b20将所有器件的第一位的补码1,1,1放到总线上,单片机读到的数据是相与的结果为1.等待主机响应之后,继续将下一位及其反码,发送到总线上。

每次读ds18b20发出的两位会得到00,01,10,11的结果其含义如下:00:挂在总线上的ds18b20在这一位上有冲突,即有的在这一位上为0,有的在这一位上为101:所有DS18B20此位数据均为010:所有DS18B20此位数据均为111:没有DS18B20二叉树遍历ROM搜索过程是简单三步过程的重复(1)读一位(2)读核位的补码(3)写所需的那一位的值:发0,则选中这一位为0的ds18b20,在此后的过程中,仅这一位为0的ds18b20参与向总线收发数据发1,则选中这一位为1的ds18b20,在此后的过程中,仅这一位为1的ds18b20参与向总线收发数据总线主机在ROM的每一位上完成这三步过程。全部过程完成之后,总线主机便知道一个器件中ROM的内容读取传感器序列号并上传到串口助手#include<reg52.h>#defineucharunsignedchar#defineuintunsignedintsbitDQ=P2^3; //温度传感器信号线ucharfCode[8];voidds1820delay(uinti) //延时1微秒{

while(i--);}复位voidds1820reset() //ds1820复位{ DQ=1; //数据线输出高电平

ds1820delay(4); //延时

DQ=0; //数据线输出低电平

ds1820delay(100); //延时480~960us DQ=1; //数据线输出高电平

ds1820delay(40); //延时15~60us}读数据字节uchards1820readbyte() //ds1820读数据字节{

uchari=0;

uchar

dat=0; for(i=8;i>0;i--) //逐位读取温度传器提供的数据

{ DQ=0; //数据线输出0

dat>>=1; //右移一位,准备用存放读得的数据位

DQ=1; //数据线输出1,执行下面语句延时4us

if(DQ) //读数据线状态,得到一个数据位

dat|=0x80; //若读得1,保存到dat的当前最高位上

ds1820delay(10); //延时30us }

return(dat);}写数据字节voidds1820writebyte(ucharwdata) //ds1820写数据字节{

uchari=0;for(i=8;i>0;i--) //按从低到高顺序,逐位输出数据字节

{ DQ=0; //数据

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论