基于AT89S52和DS18B20的数字温度计设计资料.docx
- 文档编号:25820383
- 上传时间:2023-06-15
- 格式:DOCX
- 页数:26
- 大小:797.01KB
基于AT89S52和DS18B20的数字温度计设计资料.docx
《基于AT89S52和DS18B20的数字温度计设计资料.docx》由会员分享,可在线阅读,更多相关《基于AT89S52和DS18B20的数字温度计设计资料.docx(26页珍藏版)》请在冰豆网上搜索。
基于AT89S52和DS18B20的数字温度计设计资料
题目:
基于AT89S52和DS18B20的数字温度计设计
一、设计要求
数字式温度计要求测温范围为-55~125°C,精度误差在±0.5°C以内,液晶显示。
二、方案确定
根据系统的设计要求,选择DS18B20作为本系统的温度传感器,选择单片机AT89S52为测控系统的核心来完成数据采集、处理、显示功能。
选用数字温度传感器DS18B20,省却了采样/保持电路、运放、数/模转换电路以及进行长距离传输时的串/并转换电路,简化了电路,缩短了系统的工作时间,降低了系统的硬件成本。
该系统的总体设计思路如下:
温度传感器DS18B20把所测得的温度信号发送到AT89S52单片机上,经过单片机处理,然后在1602LCD上进行显示。
其温度测量及显示电路原理图如下:
220V转5V电路原理图如下:
2.1元器件的介绍
2.1.1单片机的选择
AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
使用Atmel公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
AT89S52单片机结构见图2.1:
图2.1AT89S52结构图
2.2.2传感器的选择
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。
DS18B20内部结构主要由四部分组成:
64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
DS18B20的管脚排列、各种封装形式,DQ为数据输入/输出引脚。
开漏单总线接口引脚。
当被用着在寄生电源下,也可以向器件提供电源;GND为地信号;VDD为可选择的VDD引脚。
当工作于寄生电源时,此引脚必须接地。
2.2.3LCD的选择
此设计中采用1602LCD对温度进行显示。
图2.21602LCD实物示意图
2.2温度检测电路
DS18B20最大的特点是单总线数据传输方式,DS18B20的数据I/O均由同一条线来完成。
DS18B20的电源供电方式有2种:
外部供电方式和寄生电源方式。
工作于寄生电源方式时,VDD和GND均接地,他在需要远程温度探测和空间受限的场合特别有用,原理是当1Wire总线的信号线DQ为高电平时,窃取信号能量给DS18B20供电,同时一部分能量给内部电容充电,当DQ为低电平时释放能量为DS18B20供电。
但寄生电源方式需要强上拉电路,软件控制变得复杂(特别是在完成温度转换和拷贝数据到E2PROM时),同时芯片的性能也有所降低。
因此,在条件允许的场合,尽量采用外供电方式。
无论是内部寄生电源还是外部供电,I/O口线要接5KΩ左右的上拉电。
外部电源供电方式是DS18B20最佳的工作方式,工作稳定可靠,抗干扰能力强,而且电路也比较简单,可以开发出稳定可靠的多点温度监控系统。
在开发中使用外部电源供电方式,毕竟比寄生电源方式只多接一根VCC引线。
在外接电源方式下,可以充分发挥DS18B20宽电源电压范围的优点,即使电源电压VCC降到3V时,依然能够保证温度量精度。
由于DS18B20只有一根数据线,因此它和主机(单片机)通信是需要串行通信,而AT89S51有两个串行端口,所以可以不用软件来模拟实现。
经过单线接口访问DC18B20必须遵循如下协议:
初始化、ROM操作命令、存储器操作命令和控制操作。
要使传感器工作,一切处理均严格按照时序。
三、软件设计
3.1概述
整个系统的功能是由硬件电路配合软件来实现的,当硬件基本定型后,软件的功能也就基本定下来了。
从软件的功能不同可分为两大类:
一是监控软件(主程序),它是整个控制系统的核心,专门用来协调各执行模块和操作者的关系。
二是执行软件(子程序),它是用来完成各种实质性的功能如测量、计算、显示、通讯等。
每一个执行软件是一个小的功能执行模块。
这里将各执行模块一一列出,并为每一个执行模块进行功能定义和接口定义。
各执行模块规划好后,就可以规划监控程序了。
首先要根据系统的总体功能选择一种最合适的监控程序结构,然后根据实时性的要求,合理地安排监控软件和各执行模块之间地调度关系。
3.2程序模块
主程序需要调用2子程序,各模块程序功能如下:
●LCD显示程序:
向LCD的显示送数,控制系统的显示部分。
●温度测试及处理程序:
对温度芯片送过来的数据进行处理和显示。
主程序流程见图3.1。
图3.1主程序流程图图3.2DS18B20初始化流程
3.3各模块流程设计
下面对主要子程序的流程图做介绍。
3.3.1温度检测流程
DS18B20在单片机控制下分三个阶段:
●18B20初始化:
初始化流程图见图3.2;
●读18B20时序:
读DS18B20流程见图3.3;
●写18B20时序:
写DS18B20流程见图3.4;
图3.3读18B20流程图图3.4写18B20流程图
3.3.2液晶显示的设置
显示模式的设置:
写入指令码WriteInstruction(0x38),设置功能16*2显示,5*7点阵,8位数据接口;
显示/开关及光标设置:
写入指令码WriteInstruction(0x0c),设置开显示,不显示光标,光标不闪烁;
写入指令码WriteInstruction(0x06),设置:
光标右移,字符不移;
写入指令码WriteInstruction(0x01),清屏幕指令,将以前的显示内容清除;
写入指令码函数WriteInstruction(),写指令过程:
输入:
RS=0,D0-D7=指令码,E=高脉冲;
写入数据函数WriteData(),写指令过程:
输入:
RS=1,D0-D7=数据,E=高脉冲;
数据指针设置:
指令码80H+地址码(0-27H)显示第一行的字符,指令码80H+地址码(40H-67H)显示的第二行字符。
四、硬件的调试
完成的硬件焊接电路见附录。
在硬件调试过程中,出现了许多问题。
在设计电源电路中使用了整流桥进行整流,但是在硬件焊接完毕后,测得的输出电压不正常。
后来利用四个二极管搭建一个整流桥接入电路,输出的电压就正常。
此外,电路中使用了78L05稳压管将从整流桥出来的电压稳在5V,可是78L05输出的电压不是5V,因此自己加了了1K的可调电阻将输出的电压进行转换来给单片机供电。
在焊接外围电路(1602LCD显示电路和18B20数字测温电路)之前,通过在单片的P2.7口接入一个发光二极管,来调试单片机的最小系统是否能正常工作。
单片机中烧入的程序来控制LED的亮和灭。
一步调试很成功。
接下来自己将外围电路焊接进去,可是1602LCD不显示。
经过自己对各个接口端功能的认真分析,发现自己将背光电压调的太高导致1602LCD亮度太高,所以显示的字符看不见,就误认成电路连接有误。
在调低背光电压后,正常显示。
最后出现的问题是在一切正常的情况下1602LCD上显示的是没有找到DS18B20传感器,请检查电路。
经过认真仔细检查电路后,没有发现任何错误。
硬件检查没问题,只能是软件程序编写有错,经过认真查看所编程序,发现里面对DS18B20的信号输入接口设置错了。
改正后,重新编译烧进单片机,电源打开后,能正常显示温度了。
经过以上过程,自己设计的电路达到了开始设想的功能,课程设计圆满结束。
总结和体会
本设计利用AT89S52芯片控制温度传感器DS18B20,再辅之以部分外围电路实现对环境温度的测控,性能稳定,精度教高,而且扩展性能很强大。
由于DS18B20的测量精度只有±0.5度,往往很多场合需要更加精确的温度,在所测温度精度不变的基础上必须对数据进行校正。
由于DS18B20是基于带隙结构的数字式温度传感器,PN结增量电压正比于IC绝对温度(PTAT),它的测温精度较高,但存在着一定的误差.不过,其误差在时间和外部环境变化的条件下,保持相当高的稳定性。
它充分利用监控计算机的处理能力,在监控计算机上用线性插补的数学方法对其进行误差校正补偿,能轻易地将其提高其精度。
在本次设计的过程中,我发现很多的问题,这次设计真的让我长进了很多,单片机C语言课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法,这一次,我全部用的都是16进制的数直接加减,感觉效果比较好,有好多的东西,只有我们去试着做了,才能真正的掌握。
五、元件清单(名称、型号、数量)
元件名称
型号
数量
单片机芯片
AT89S52
1
温度传感器
DS18B20
1
晶振
12MHz
1
220V转7.5V变压器
1
电容
100pF
2
22uF、0.01uF
各1
104
2
1000uF/25V
1
220uF/25V
LCD
1602
1
电阻
1K、4.7K
各1
10K
2
470
1
万能板
1
IC插座
1
导线
若干
稳压块
78L05
1
发光二极管
1
二极管
IN4007
5
开关
1
附录:
程序:
//DS18B20温度检测及其液晶显示
#include
#include
unsignedcharcodedigit[10]={"0123456789"};//定义字符数组显示数字
unsignedcharcodeStr[]={"TestbyDS18B20"};//说明显示的是温度
unsignedcharcodeError[]={"Error!
Check!
"};//说明没有检测到DS18B20
unsignedcharcodeTemp[]={"Temp:
"};//说明显示的是温度
unsignedcharcodeCent[]={"Cent"};//温度单位
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
sbitRS=P2^0;//寄存器选择位,将RS位定义为P2.0引脚
sbitRW=P2^1;//读写选择位,将RW位定义为P2.1引脚
sbitE=P2^2;//使能信号位,将E位定义为P2.2引脚
sbitBF=P0^7;//忙碌标志位,,将BF位定义为P0.7引脚
/*****************************************************
函数功能:
延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
voiddelay1ms()
{
unsignedchari,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:
延时若干毫秒
入口参数:
n
***************************************************/
voiddelaynms(unsignedcharn)
{
unsignedchari;
for(i=0;i delay1ms(); } /***************************************************** 函数功能: 判断液晶模块的忙碌状态 返回值: result。 result=1,忙碌;result=0,不忙 ***************************************************/ bitBusyTest(void) { bitresult; RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态 RW=1; E=1;//E=1,才允许读写 _nop_();//空操作 _nop_(); _nop_(); _nop_();//空操作四个机器周期,给硬件反应时间 result=BF;//将忙碌标志电平赋给result E=0;//将E恢复低电平 returnresult; } /***************************************************** 函数功能: 将模式设置指令或显示地址写入液晶模块 入口参数: dictate ***************************************************/ voidWriteInstruction(unsignedchardictate) { while(BusyTest()==1);//如果忙就等待 RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令 RW=0; E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲, //就是让E从0到1发生正跳变,所以应先置"0" _nop_(); _nop_();//空操作两个机器周期,给硬件反应时间 P0=dictate;//将数据送入P0口,即写入指令或地址 _nop_(); _nop_(); _nop_(); _nop_();//空操作四个机器周期,给硬件反应时间 E=1;//E置高电平 _nop_(); _nop_(); _nop_(); _nop_();//空操作四个机器周期,给硬件反应时间 E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令 } /***************************************************** 函数功能: 指定字符显示的实际地址 入口参数: x ***************************************************/ voidWriteAddress(unsignedcharx) { WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x" } /***************************************************** 函数功能: 将数据(字符的标准ASCII码)写入液晶模块 入口参数: y(为字符常量) ***************************************************/ voidWriteData(unsignedchary) { while(BusyTest()==1); RS=1;//RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲, //就是让E从0到1发生正跳变,所以应先置"0" P0=y;//将数据送入P0口,即将数据写入液晶模块 _nop_(); _nop_(); _nop_(); _nop_();//空操作四个机器周期,给硬件反应时间 E=1;//E置高电平 _nop_(); _nop_(); _nop_(); _nop_();//空操作四个机器周期,给硬件反应时间 E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令 } /***************************************************** 函数功能: 对LCD的显示模式进行初始化设置 ***************************************************/ voidLcdInitiate(void) { delaynms(15);//延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38);//显示模式设置: 16×2显示,5×7点阵,8位数据接口 delaynms(5);//延时5ms ,给硬件一点反应时间 WriteInstruction(0x38); delaynms(5);//延时5ms ,给硬件一点反应时间 WriteInstruction(0x38);//连续三次,确保初始化成功 delaynms(5);//延时5ms ,给硬件一点反应时间 WriteInstruction(0x0c);//显示模式设置: 显示开,无光标,光标不闪烁 delaynms(5);//延时5ms ,给硬件一点反应时间 WriteInstruction(0x06);//显示模式设置: 光标右移,字符不移 delaynms(5);//延时5ms ,给硬件一点反应时间 WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除 delaynms(5);//延时5ms ,给硬件一点反应时间 } /************************************************************************ 以下是DS18B20的操作程序 ************************************************************************/ sbitDQ=P2^3; unsignedchartime;//设置全局变量,专门用于严格延时 /***************************************************** 函数功能: 将DS18B20传感器初始化,读取应答信号 出口参数: flag ***************************************************/ bitInit_DS18B20(void) { bitflag;//储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在 DQ=1;//先将数据线拉高 for(time=0;time<2;time++)//略微延时约6微秒 ; DQ=0;//再将数据线从高拉低,要求保持480~960us for(time=0;time<200;time++)//略微延时约600微秒 ;//以向DS18B20发出一持续480~960us的低电平复位脉冲 DQ=1;//释放数据线(将数据线拉高) for(time=0;time<10;time++) ;//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲) flag=DQ;//让单片机检测是否输出了存在脉冲(DQ=0表示存在) for(time=0;time<200;time++)//延时足够长时间,等待存在脉冲输出完毕 ; return(flag);//返回检测成功标志 } /***************************************************** 函数功能: 从DS18B20读取一个字节数据 出口参数: dat ***************************************************/ unsignedcharReadOneChar(void) { unsignedchari=0; unsignedchardat;//储存读出的一个字节数据 for(i=0;i<8;i++) { DQ=1;//先将数据线拉高 _nop_();//等待一个机器周期 DQ=0;//单片机从DS18B20读书据时,将数据线从高拉低即启动读时序 dat>>=1; _nop_();//等待一个机器周期 DQ=1;//将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备 for(time=0;time<2;time++) ;//延时约6us,使主机在15us内采样 if(DQ==1) dat|=0x80;//如果读到的数据是1,则将1存入dat else dat|=0x00;//如果读到的数据是0,则将0存入dat //将单片机检测到的电平信号DQ存入r[i] for(time=0;time<8;time++) ;//延时3us,两个读时序之间必须有大于1us的恢复期 } return(dat);//返回读出的十进制数据 } /***************************************************** 函数功能: 向DS18B20写入一个字节数据 入口参数: dat ***************************************************/ WriteOneChar(unsignedchardat) { unsignedchari=0; for(i=0;i<8;i++) { DQ=1;//先将数据线拉高 _nop_();//等待一个机器周期 DQ=0;//将数据线从高拉低时即启动写时序 DQ=dat&0x01;//利用与运算取出要写的某位二进制数据, //并将其送到数据线上等待DS18B20采样 for(time=0;time<10;time++) ;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样 DQ=1;//释放数据线 for(time=0;time<1;time++) ;//延时3us,两个写时序间至少需要1us的恢复期 dat>>=1;//将dat中的各二进制位数据右移1位 } for(time=0;time<4;time++) ;//稍作延时,给硬件一点反应时间 } /****************************************************************************** 以下是与温度有关的显示设置 ********************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 AT89S52 DS18B20 数字 温度计 设计 资料