基于AT89C51单片机的测温系统Word格式文档下载.docx

上传人:b****5 文档编号:17319328 上传时间:2022-12-01 格式:DOCX 页数:24 大小:370.18KB
下载 相关 举报
基于AT89C51单片机的测温系统Word格式文档下载.docx_第1页
第1页 / 共24页
基于AT89C51单片机的测温系统Word格式文档下载.docx_第2页
第2页 / 共24页
基于AT89C51单片机的测温系统Word格式文档下载.docx_第3页
第3页 / 共24页
基于AT89C51单片机的测温系统Word格式文档下载.docx_第4页
第4页 / 共24页
基于AT89C51单片机的测温系统Word格式文档下载.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

基于AT89C51单片机的测温系统Word格式文档下载.docx

《基于AT89C51单片机的测温系统Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《基于AT89C51单片机的测温系统Word格式文档下载.docx(24页珍藏版)》请在冰豆网上搜索。

基于AT89C51单片机的测温系统Word格式文档下载.docx

3.无需外部器件

4.可通过数据线供电,电压围:

3.0~5.5V

5.测温围-55℃~+125℃,在-10~+85℃时精度为±

0.5℃

6.零待机功耗

7.温度以9或12位数字量读出

8.报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件

9.负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作

四:

硬件电路原理框图

由于本次实验是在学习板上做的,所以没有硬件接线图,原理主要讲解DS18B20的工作原理。

硬件设计

1.单片机系统电路原理图

图4.1系统电路原理图

2.DS18B20温度传感器电路设计

电源供电方式如图,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源。

图4.2DS18B20温度传感器电路

3.报警电路设计

报警电路是在测量温度大于上限或小于下限时提供报警功能的电路。

该电路是由一个蜂鸣器组成,具体的电路如图所示

图4.3报警电路

4.显示电路设计

显示电路是由四位一体的共阴数码管进行显示的

软件设计

(1)DS18B20部结构

如图所示

主要由4部分组成:

64位ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。

ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。

64位ROM的排的循环冗余校验码(CRC=X^8+X^5+X^4+1)。

ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。

DS18B20中的温度传感器完成对温度的测量,用16位二进制形式提供,形式表达,其中S为符号位。

DS18B20温度传感器主要用于对温度进行测量,数据可用16位符号扩展的二进制补码读数形式提供,并以0.0625℃/LSB形式表示。

表2是部分温度值对应的二进制温度表示数据。

(2)DS18B20的工作时序

DS18B20的一线工作协议流程是:

初始化→ROM操作指令→存储器操作指令→数据传输

初始化时序

主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,并在随后的480微秒时间对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。

若无低电平出现一直都是高电平说明总线上无器件应答。

  做为从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。

若没有检测到就一直在检测等待。

接下来就是主机发出各种操作命令,但各种操作命令都是向DS18B20写0和写1组成的命令字节,接收数据时也是从DS18B20读取0或1的过程。

因此首先要搞清主机是如何进行写0、写1、读0和读1的。

写周期最少为60微秒,最长不超过120微秒。

写周期一开始做为主机先把总线拉低1微秒表示写周期开始。

随后若主机想写0,则继续拉低电平最少60微秒直至写周期结束,然后释放总线为高电平。

若主机想写1,在一开始拉低总线电平1微秒后就释放总线为高电平,一直到写周期结束。

而做为从机的DS18B20则在检测到总线被拉底后等待15微秒然后从15us到45us开始对总线采样,在采样期总线为高电平则为1,若采样期总线为低电平则为0。

对于读数据操作时序也分为读0时序和读1时序两个过程。

读时隙是从主机把单总线拉低之后,在1微秒之后就得释放单总线为高电平,以让DS18B20把数据传输到单总线上。

DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。

若要送出1则释放总线为高电平。

主机在一开始拉低总线1微秒后释放总线,然后在包括前面的拉低总线电平1微秒在的15微秒时间完成对总线进行采样检测,采样期总线为低电平则确认为0。

采样期总线为高电平则确认为1。

完成一个读时序过程,至少需要60us才能完成

让DS18B20进行一次温度的转换,那具体的操作就是:

(1).主机先作个复位操作,

(2).主机再写跳过ROM的操作(CCH)命令,

(3).然后主机接着写个转换温度的操作命令,后面释放总线至少一秒,让DS18B20完成转换的操作。

在这里要注意的是每个命令字节在写的时候都是低字节先写,例如CCH的二进制为11001100,在写到总线上时要从低位开始写,写的顺序是“零、零、壹、壹、零、零、壹、壹”。

整个操作的总线状态如下图。

(3)初始化时序程序

bitInit_DS18B20(void)

{

bitflag;

//储存DS18B20是否存在的标志,flag=0,存在;

flag=1,不存在

DQ=1;

//先将数据线拉高

for(time=0;

time<

2;

time++);

//略微延时约6微秒//再将数据线从高拉低,要求保持480~960us

DQ=0;

200;

//略微延时约600微秒//以向DS18B20发出一持续480~960us的低电平复位脉冲

//释放数据线(将数据线拉高)

10;

//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)

flag=DQ;

//让单片机检测是否输出了存在脉冲(DQ=0表示存在)

//延时足够长时间,等待存在脉冲输出完毕

return(flag);

//返回检测成功标志

unsignedcharReadOneChar(void)

{

unsignedchari=0;

unsignedchardat;

//储存读出的一个字节数据

for(i=0;

i<

8;

i++)

DQ=1;

//先将数据线拉高

_nop_();

//等待一个机器周期

//单片机从DS18B20读书据时,将数据线从高拉低即启动读时序

//等待一个机器周期

//将数据线"

人为"

拉高,为单片机检测DS18B20的输出电平作准备

//延时约6us,使主机在15us采样

dat>

>

=1;

if(DQ==1)

dat|=0x80;

//如果读到的数据是1,则将1存入dat

else

dat|=0x00;

//如果读到的数据是0,则将0存入dat

time++);

//延时3us,两个读时序之间必须有大于1us的恢复期

}

return(dat);

//返回读出的十六进制数据

WriteOneChar(unsignedchardat)

i<

i++)

{

DQ=0;

//将数据线从高拉低时即启动写时序

DQ=dat&

0x01;

//利用与运算取出要写的某位二进制数据,

//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样

DQ=1;

//释放数据线

1;

//延时3us,两个写时序间至少需要1us的恢复期

//将dat中的各二进制位数据右移1位

}

4;

//稍作延时,给硬件一点反应时间

五、程序流程图(主程序,各子程序)

1.主程序

实时温度显示子程序:

驱动数码管把实时温度值送出在LED数码管显示

主程序流程图:

定时器初始化、启动

显示实时温度

温度设定

图5.1主程序流程图

2.读温度值模块

读温度值模块需要调用4个子程序,分别为:

1.DS18B20初始化子程序:

让单片机知道DS18B20在总线上且已准备好操作

2.DS18B20写字节子程序:

对DS18B20发出命令

3.DS18B20读字节子程序:

读取DS18B20存储器的数据

4.延时子程序:

对DS18B20操作时的时序控制

读温度值模块流程图:

图5.2读温度值子程序流程图

DS18B20初始化子程序流程图:

延时>

480us

DQ拉高电平

DQ为低电平?

延时15~60us

N

Y

返回

图5.3DS18B20初始化子程序流程图

DS18B20写字节和读字节子程序流程图:

图5.4DS18B20写字节子程序流程图图5.5DS18B20读字节子程序流程图

六:

调试(步骤,心得,结论)

优点:

1.线性好,精度适中,体积小,实用方便。

2.实时显示当前温度。

缺点:

温度传感器会有一定的时间延时,从而间接地影响了整个报警系统的灵敏性和准确性。

(2)心得体会:

在本次设计的过程中,我们发现了很多的问题,虽然以前也做过类似的课程设计,但是这次确实让我们学到了很多。

我们不仅要选好元件,还要把这些元件合理地组织起来,所以我们要学会如何寻找和搜索自己需要的资料。

这一次,我们用了老师给的参考电路图,然后修改了一些地方,比如去掉了一个LED,再加入了几个电阻。

虽然有些困难,但是经过努力,我们还是完成了电路的设计。

经过本次的设计,我们学到了很多的知识,了解到了传感器能够把自然界的各种非电量转换为电信号的能量物理理念。

从本次的实习设计中,我们意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识运用到实际当中,实践是检验真理的唯一标准。

培养了一定的独立思考能力、解决问题的能力。

同时也学到了和他人愉快合作的技巧。

每当我们遇到问题时,我们学会了理性的分析,最终解决问题。

同时在讨论问题时认真聆听别人的思想和意见也很重要,在聆听的同时也会学到很多东西。

所以这次实习让我们学到了很多的东西。

七:

附录(电路图,程序)

#include"

reg51.h"

intrins.h"

//_nop_();

延时函数用

#defineDisdataP0//段码输出口

#definediscanP2//扫描口

#defineucharunsignedchar

#defineuintunsignedint

sbitDQ=P3^3;

//温度输入口

sbitDIN=P0^7;

//LED小数点控制

sbitbuzzer=P3^6;

uchartemp_buzzer;

ucharup_alarm=20;

uinth;

uinti;

ucharflag;

//**************温度小数部分用查表法***********//

ucharcodeditab[16]=

{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};

//

ucharcodedis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};

//共阳LED段码表"

0"

"

1"

2"

3"

4"

5"

6"

7"

8"

9"

不亮"

-"

ucharcodescan_con[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

//列扫描控制字

uchardatatemp_data[2]={0x00,0x00};

//读出温度暂放

uchardatadisplay[8];

//显示单元数据,共4个数据和一个运算暂用

/***********11微秒延时函数**********/

voidser_init()

TMOD=0X20;

SCON=0X50;

TH1=0XFD;

TL1=0XFD;

TR1=1;

}

voiddelay(uintt)

for(;

t>

0;

t--);

/***********显示扫描函数**********/

scan()

chark;

for(k=0;

k<

7;

k++)//四位LED扫描控制

//Disdata=0xff;

Disdata=dis_7[display[k]];

if(k==4){DIN=0;

discan=scan_con[k];

delay(200);

discan=0xff;

voiddelayms(unsignedintxms)//延时函数,延时xms

unsignedinti,j;

for(i=0;

i<

xms;

for(j=0;

j<

110;

j++);

voidfengming(doubletempl)

{uchari;

if(templ>

=34)//温度报警限设置

for(i=0;

20;

buzzer=0;

delayms

(1);

buzzer=1;

}

/***********18B20复位函数**********/

ow_reset(void)

charpresence=1;

while(presence)

DQ=1;

_nop_();

DQ=0;

//

delay(50);

//550us

delay(6);

//66us

presence=DQ;

//presence=0继续下一步

delay(45);

//延时500us

presence=~DQ;

/**********18B20写命令函数*********/

//向1-WIRE总线上写一个字节

voidwrite_byte(ucharval)

uchari;

for(i=8;

i>

i--)//

DQ=0;

//5us

DQ=val&

//最低位移出

//66us

val=val/2;

//右移一位

DQ=1;

delay

(1);

/*********18B20读1个字节函数********/

//从总线上读取一个字节

ucharread_byte(void)

ucharvalue=0;

i>

i--)

value>

//4us

if(DQ)value|=0x80;

return(value);

/***********读出温度函数**********/

read_temp()

ow_reset();

//总线复位

write_byte(0xCC);

//发SkipROM命令

write_byte(0xBE);

//发读命令

temp_data[0]=read_byte();

//温度低8位

temp_data[1]=read_byte();

//温度高8位

//SkipROM

write_byte(0x44);

//发转换命令

/***********温度数据处理函数**********/

voidwork_temp()

ucharn=0,th=0,tl=0;

inttemp=0;

ucharflag3=1,flag2=1;

//数字显示修正标记

if(temp_data[0]>

255)

temp_data[1]++;

tl=temp_data[0]&

0x0f;

display[7]=tl;

if(display[7]&

0x08)temp+=5000;

0x04)temp+=2500;

0x02)temp+=1250;

0x01)temp+=625;

display[0]=temp%10;

display[1]=(temp%100)/10;

display[2]=(temp%1000)/100;

display[3]=temp/1000;

display[7]=((temp_data[0]&

0xf0)>

4)|((temp_data[1]&

0x07)<

<

4);

display[6]=display[7]/100;

display[5]=display[7]/10%10;

display[4]=display[7]%10;

if(!

display[6])

display[6]=0x0a;

flag3=0;

if(!

display[5])

display[5]=0x0a;

flag2=0;

}//最高位为0时都不显示

/**************主函数****************/

main()

{doubletempl;

ser_init();

Disdata=0xff;

//初始化端口

discan=0xff;

for(h=0;

h<

h++){display[h]=0;

}//开机显示8888

//开机先转换一次

write_byte(0x4e

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1