您的当前位置:首页正文

基于AT89S52的数字显示温度计设计

2023-11-05 来源:好走旅游网
摘要

2012年黑龙江八一农垦大学电子协会电子设计竞赛论文及总结报告

题目:数字显示温度计组号:2012205001

组员:代健行李宏覃荣晴导师:柴雪强

时间:2012年3月20日--4月1日

摘要

摘要说明

随着现代化信息技术的飞速发展,单片机技术已经十分普及,在实时检测和自动控制的单片机应用系统中,单片机往往是作为核心部件来使用。

本论文介绍了一种以单片机AT89S52为主要控制器件,以DS18B20为温度传感器通过LCD液晶屏传送数据,实现温度显示的新型数字温度计。该数字温度计的测量范围为0~120℃,显示分辨率为0.1℃,误差≤±0.10℃。由于采用了温度传感器DS18B20作为检测元件,与传统的温度计相比,本文设计的数字温度计减少了外部的硬件电路,具有读数方便,测温范围广,测温精确,数字显示,适用范围宽等特点。DS18B20温度计还可以在高温报警、远距离多点测温控制等方面进行应用开发。该系统结构简单,抗干扰能力强,适合于各种环境下进行现场温度测量,可广泛应用于工业控温系统、温度计、消费产品以及其它温度测控系统。我们利用单片机的这种强大的多功能控制了水温的系统,我们相信在我们的努力下,一定能够实现我们的目的,单片机有着极其远大的发展前途。

关键词:单片机AT89S52;温度传感器DS18B20;DS1302;LCD液晶屏显示;变压器等。

目录3

ABSTRACT

Withtherapiddevelopmentofmoderninformationtechnology,microcontrollertechnologyhasbecomequitecommon,real-timedetectionandautomaticcontrolinthemicrocomputerapplicationsystems,microcontrollerisoftenusedasacorecomponenttouse.

Thispaperintroducesasingle-chipcontroldeviceformainAT89C52fortemperaturesensorDS18B20,totransmitdatabyLCDscreen,realizetemperaturedisplayofthenewdigitalthermometer.Thisdigitalthermometermeasurementrangeis0~120℃,thedisplayresolution℃for0.1℃,erroracuities+0.5.AsaresultofthetemperaturesensorDS18B20asthetestcomponentscomparedwiththetraditionalthermometer,thispaperdesigneddigitalthermometerreduceexternalhardwarecircuit,whichreadingsconvenient,temperaturemeasuringrange,temperaturemeasurementprecision,thedigitaldisplaycharacteristics,wideapplicationscope.DS18B20thermometercanstillinhightemperaturealarm,long-rangemulti-pointmeasurementtemperaturecontrolaspectsofapplicationdevelopment.Thesystemstructureissimple,stronganti-jammingcapability,suitableforallkindsofenvironmenttemperaturemeasurementonthesite,andcanbewidelyusedinindustrialcontroltemperaturesystem,thermometer,consumerproductsandothertemperaturemeasurementandcontrolsystem.

Keywords:SCMAT89C52single;TemperaturesensorDS18B20;Digitalthermometer;LCDdisplay

目录i

目录

一.绪论..........................................................................................................................11.1研究背景.................................................................................................................11.2研究现状.................................................................................................................1二.总体设计方案..........................................................................................................32.1设计思路.................................................................................................................32.2总体设计框图.........................................................................................................32.3所用材料.................................................................................................................4三.硬件设计..................................................................................................................53.1单片机的选择........................................................................................................53.2温度传感器的选择................................................................................................93.3温度检测电路......................................................................................................163.4温度报警电路......................................................................................................173.5复位电路..............................................................................................................183.6时钟电路..............................................................................................................193.7显示电路..............................................................................................................203.8主电路原理图......................................................................................................21四.软件设计................................................................................................................234.1概述......................................................................................................................234.2主程序模块..........................................................................................................234.3各模块流程设计..................................................................................................244.4报警模块流程......................................................................................................27五.仿真........................................................................................................................295.1PROTEUS介绍.......................................................................................................295.2ALTIUMDESIGNE介绍........................................................................................30六.综合调试..................................................................................................................336.1焊接.......................................................................................................................336.2调试.......................................................................................................................33

ii目录

七.总结与体会............................................................................................................35致谢................................................................................................................................37参考文献........................................................................................................................39附录................................................................................................................................41

第一部分绪论1

第一部分绪论

1.1研究背景

随着现代信息技术的飞速发展和传统工业改造的逐步实现,人们在生产过程中会越来越关注精密而实用的仪器,能够独立工作的温度检测和显示系统应用于诸多领域。其中数字温度计就是一个典型的例子,但人们对它的要求越来越高,要为现代人工作、科研、生活等提供更好更方便快捷的设施就需要从单片机技术入手,一切向着数字化控制,智能化控制方向发展。

目前温度计的发展很快,从原始的玻璃管温度计发展到了现在的热电阻温度计、热电偶温度计、数字温度计、电子温度计等等,温度计中传感器是它的重要组成部分,它的精度、灵敏度基本决定了温度计的精度、测量范围、控制范围和用途等。传感器应用极其广泛,目前已经研制出多种新型传感器。

传统的温度检测以热敏电阻为温度敏感元件。热敏电阻的成本低,但需后续信号处理电路,而且可靠性相对较差,测温准确度低,检测系统也有一定的误差。本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温精确,数字显示,适用范围宽等特点,主要用于对测温比较准确的场所或科研实验室使用,可广泛用用于工业控温系统、温度计、消费产品以及其它温度测控系统。目前,该产品已在温控系统中得到了广泛使用。

因此本设计就尝试通过编程与芯片的结合来解决传统数字温度计的弊端,设计出新型数字温度计。

1.2研究现状

温度传感器的发展现状:温度传感器使用范围广,数量多,居各种传感器之首,其发展大致经历了以下3个阶段:

1、传统的分立式温度传感器(含敏感元件)——热电偶传感器,主要是能够进行非电量和电量之间转换。

2数字显示温度计的设计

2、模拟集成温度传感器/控制器,集成传感器是采用硅半导体集成工艺制成的,因此亦称硅传感器或单片集成温度传感器。

3、智能温度传感器。它是微电子技术、计算机技术和自动测试技术(ATE_)的结晶。智能温度传感器内部包含温度传感器、A/D传感器、信号处理器、存储器(或寄存器)和接口电路。

本设计课题的研究可以应用领域生产、生活等很多领域。对于家用电器从洗衣机、微波炉到音响等等到处都可以用到温度控制器来方便大家的日常生活。开发此产品后也可方便应用安装在小至家庭大到工厂车间,小至一个芯片大到一个机械设备。例如在家庭客厅卧室等必要地方显示室温,可防止家里食物是否变质及早采取措施。工业生产控制中用数字温度计可清晰显示温度来防止元气件失效或损坏等不必要的非人为损失,对做好车间机器维修与保养起很重要的作用。

第二章总体设计方案3

第二部分总体设计方案

2.1设计思路

本设计是一个基于单片机AT89S51的数字温度计和温度传感器DS18B20的设计,用来测量环境温度,测量范围为0~120℃,显示分辨率为0.1℃,误差≤±0.5℃,当温度高于55℃或低35℃于程序设定值时,报警电路就会发出报警,并且在LCD液晶屏第二行温度值的后面显示出高温超限或低温超限。

整个设计系统主要包括硬件电路的设计和系统软件的设计。硬件电路主要包括主控制器,测温电路和显示电路等。主控制器采用单片机AT89C51,温度传感器采用美国DALLAS半导体公司生产的DS18B20来实现环境温度的采集和A/D转换,同时因其输出为数字形式,且为串行输出,这就方便了单片机进行数据处理,但同时也对编程提出了更高的要求。单片机把采集到的温度进行相应的转换后,显示电路采用LCD液晶显示器以动态扫描法直读显示。系统程序主要包括主程序,读出温度子程序,写入温度子程序,报警子程序等。

2.2总体设计框图

本系统采用单片机作为微控制器,如图2.2.1,分为:测温电路,显示电路,报警电路,复位电路。单片机用AT89C51、温度传感器用DS18B20,采用12MHZ晶振,电源采用5V。该电路经过设计分析、绘图、仿真调试、制板、焊接等工作后温度计成形。

采用数字温度芯片DS18B20测量温度,输出信号全数字化。便于单片机处理及控制,省去传统的测温方法的很多外围电路。且该芯片的物理化学性很稳定,它能用做工业测温元件,此元件线形较好。在0—100摄氏度时,最大线形偏差小于1摄氏度。DS18B20的最大特点之一采用了单总线的数据传输,由数字温度计DS18B20和微控制器AT89C51构成的温度测量装置,它直接输出温度的数字信号,可直接与计算机连接。这样,测温系统的结构就比较简单,体积也不大。采用52单片机控制,

4数字显示温度计的设计

软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制,而且体积小,硬件实现简单,安装方便。

图2.2.1总体设计框图

2.3所用主要元器件

单片机AT89S51一个,温度传感器DS18B20一个,12MHz晶振一个,LCD12864个,蜂鸣器一个,电源一个,排阻一个,三极管一个,USB一个,,电阻电容及导线若干。

第三章硬件设计5

第三章硬件设计

3.1单片机的选择

AT89S51作为温度测试系统设计的核心器件。该器件是INTEL公司生产的MCS一5l系列单片机中的基础产品,采是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89S51单片机在电子行业中有着广泛的应用。单片机小系统的电路图如图3-1-1所示。

图3.1.1单片机小系统电路

3.1.1AT89S51单片机的主要特性:

6数字显示温度计的设计

(1)兼容MCS-51指令系统,4K字节可编程闪烁存储器;(2)8k可反复擦写(大于1000次)FlashROM;

(3)寿命为1000次写/擦周期,数据保留时间可10年以上;(4)全静态工作模式:0Hz-33Hz;(5)三级程序存储器锁定;

(6)128*8位内部RAM,32可编程I/O线;(7)两个16位定时器/计数器,6个中断源;

(8)全双工串行UART通道,低功耗的闲置和掉电模式;(9)低功耗空闲和掉电模式,软件设置睡眠和唤醒功能;

(10)有PDIP、PQFP、TQFP及PLCC等几种封装形式,以适应不同产品的需求。

3.1.2引脚功能及管脚电压

AT89S51为8位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xS52相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。主要管脚有:XTAL1(19脚)和XTAL2(18脚)为振荡器输入输出端口,外接12MHz晶振。RST(9脚)为复位输入端口,外接电阻电容组成的复位电路。VCC(40脚)和VSS(20脚)为供电端口,分别接+5V电源的正负端。P0~P3为可编程通用I/O脚,其功能用途由软件定义,在本设计中,P0端口(32~39脚)被定义为N1功能控制端口,分别与N1的相应功能管脚相连接,13脚定义为IR输入端,10脚和11脚定义为I2C总线控制端口,分别连接N1的SDAS(18脚)和SCLS(19脚)端口,12脚、27脚及28脚定义为握手信号功能端口,连接主板CPU的相应功能端,用于当前制式的检测及会聚调整状态进入的控制功能。如图3.1.2所示。

第三不封硬件设计7

图3.1.2PDIP封装的AT89C52引脚图

(1)P0口

P0口是一组8位漏极开路型双向I/O口,也即地址/数据总线复用口。作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口P0写“1”时,可作为高阻抗输入端用。

在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。

在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。(2)P1口

P1是一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。

与AT89C51不同之处是,P1.0和P1.1还可分别作为定时/计数器2的外部计数输入(P1.0/T2)和输入(P1.1/T2EX),参见表3.1.1。

Flash编程和程序校验期间,P1接收低8位地址。

表3.1.1

P1.0和P1.1的第二功能

引脚号功能特性

8数字显示温度计的设计

P1.0P1.1

(3)P2口

T2,时钟输出T2EX(定时/计数器2)

P2是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口P2写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。

在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX@DPTR指令)时,P2口送出高8位地址数据。在访问8位地址的外部数据存储器(如执行MOVX@RI指令)时,P2口输出P2锁存器的内容。

Flash编程或校验时,P2亦接收高位地址和一些控制信号。(4)P3口

P3口是一组带有内部上拉电阻的8位双向I/O口。P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。此时,被外部拉低的P3口将用上拉电阻输出电流(IIL)。

P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能。P3口还接收一些用于Flash闪速存储器编程和程序校验的控制信号。(5)RST

复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。(6)ALE/PROG

当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个ALE脉冲。

对Flash存储器编程期间,该引脚还用于输入编程脉冲(PROG)。

如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。该位置位后,只有一条MOVX和MOVC指令才能将ALE激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE禁止位无效。(7)PSEN

第三不封硬件设计9

程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89C52由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。在此期间,当访问外部数据存储器,将跳过两次PSEN信号。(8)EA/VPP

外部访问允许。欲使CPU仅访问外部程序存储器(地址为0000H—FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。

如EA端为高电平(接VCC端),CPU则执行内部程序存储器中的指令。Flash存储器编程时,该引脚加上+12V的编程允许电源VPP,当然这必须是该器件是使用12V编程电压VPP。(9)XTAL1

振荡器反相放大器的及内部时钟发生器的输入端。(10)XTAL2

振荡器反相放大器的输出端。

3.2温度传感器的选择

DS18B20温度传感器是美国DALLAS公司推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且具有耐磨耐碰,体积小,使用方便,封装形式多样等特点,适用于各种狭小空间设备数字测温和控制领域。

3.2.1DS18B20的主要特性

(1)适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电;

(2)独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯;

10数字显示温度计的设计

(3)DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温;

(4)DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内;

(5)温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃;

(6)可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温;

(7)在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快;

(8)测量结果直接输出数字温度信号,以“一线总线”串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力;

(9)负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。

3.2.2DS18B20的引脚结构

温度传感器DS18B20引脚如图3.2.1所示。

图3.2.1DS18B20引脚

引脚功能说明:

(1)NC(1、2、6、7、8脚):空引脚,悬空不使用;

(2)VDD(3脚):可选电源脚,电源电压范围3~5.5V。当工作于寄生电源时,此引脚必须接地。

(3)DQ(4脚):数据输入/输出脚。漏极开路,常态下高电平。

第三不封硬件设计11

(4)GND(5脚):为电源地

3.2.3DS18B20工作原理

图3.2.2DS18B20内部结构图

DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。DS18B20测温原理如图3.2.3所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。图3.2.3中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。

12数字显示温度计的设计

图3.2.3DS18B20测温原理框图

DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。

(1)光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。

(2)DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB形式表达,其中S为符号位。

表3.2.1:DS18B20温度值格式表

这是12位转化后得到的12位数据,存储在DS18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FE6FH,-55℃的数字输出为FC90H。

第三不封硬件设计13

表3.2.2:DS18B20温度数据表

温度+125℃+85+25.0625℃+10.125℃+0.5℃0℃-0.5℃-10.125℃-25.0625℃-55℃

数字输出(二进制)0000011111010000000001010101000000000001100100010000000010100010000000000000100000000000000000001111111111111000111111110101111011111110011011111111110010010000

数字输入(十六进制)07D0H0550H0191H00A2H0008H0000HFFF8HFF5EHFF6FHFC90H

(3)DS18B20温度传感器的存储器DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EEPRAM,后者存放高温度和低温度触发器。TH、TL和结构寄存器。

(4)配置寄存器该字节各位的意义如下:

表3.2.3:配置寄存器结构

TMR1R011111

低五位一直都是\"1\",TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在DS18B20出厂时该位被设置为0,用户不要去改动。R1和R0用来设置分辨率,如下表所示:(DS18B20出厂时被设置为12位)

表3.2.4:温度分辨率设置表

R10011

R00101

分辨率9位10位11位12位

温度最大转换时间

93.75ms187.5ms375ms750ms

14数字显示温度计的设计

3.2.4高速暂存存储器

高速暂存存储器由9个字节组成,其分配如表3.2.5所示。当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式如表3.2.1所示。对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变为原码,再计算十进制值。表3.2.2是对应的一部分温度值。第九个字节是冗余检验字节。

表3.2.5:DS18B20暂存寄存器分布

寄存器内容温度值低位(LSByte)温度值高位(MSByte)

高温限值(TH)低温限值(TL)配置寄存器

保留保留保留CRC校验值

字节地址

012345678

根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。

第三不封硬件设计15

表3.2.6:ROM指令表

指令读ROM符合ROM

约定代码33H55H

功能

读DS1820温度传感器ROM中的编码(即64位地址)发出此命令之后,接着发出64位ROM编码,访问单总线上与该编码相对应的DS1820使之作出响应,为下一步对该DS1820的读写作准备。

搜索ROM0FOH用于确定挂接在同一总线上DS1820的个数和识别64ROM地址。为操作各器件作好准备。

跳过ROM0CCH忽略64位ROM地址,直接向DS1820发温度变换命令。适用于单片工作。

告警搜索命令

0ECH执行后只有温度超过设定值上限或下限的片子才做出响应。

表3.2.7:RAM指令表

指令温度变换读暂存器写暂存器复制暂存

器重调EEPROM

约定代码44H0BEH4EH

功能

启动DS1820进行温度转换,12位转换时最长为750ms(9位为93.75ms)。结果存入内部9字节RAM中读内部RAM中9字节的内容

发出向内部RAM的3、4字节写上、下限温度数据命令,紧跟该命令之后,是传送两字节的数据。

将RAM中第3、4字节的内容复制到EEPROM中。

48H

0B8H将EEPROM中内容恢复到RAM中的第3、4字节。

3.2.5DS1820使用中注意事项

DS1820虽然具有测温系统简单、测温精度高、连接方便、占用口线少等优点,但在实际应用中也应注意以下几方面的问题:

(1)较小的硬件开销需要相对复杂的软件进行补偿,由于DS1820与微处理

16数字显示温度计的设计

器间采用串行数据传送,因此,在对DS1820进行读写编程时,必须严格的保证读写时序,否则将无法读取测温结果。在使用PL/M、C等高级语言进行系统程序设计时,对DS1820操作部分最好采用汇编语言实现。

(2)在DS1820的有关资料中均未提及单总线上所挂DS1820数量问题,容易使人误认为可以挂任意多个DS1820,在实际应用中并非如此。当单总线上所挂DS1820超过8个时,就需要解决微处理器的总线驱动问题,这一点在进行多点测温系统设计时要加以注意。

(3)连接DS1820的总线电缆是有长度限制的。试验中,当采用普通信号电缆传输长度超过50m时,读取的测温数据将发生错误。当将总线电缆改为双绞线带屏蔽电缆时,正常通讯距离可达150m,当采用每米绞合次数更多的双绞线带屏蔽电缆时,正常通讯距离进一步加长。这种情况主要是由总线分布电容使信号波形产生畸变造成的。因此,在用DS1820进行长距离测温系统设计时要充分考虑总线分布电容和阻抗匹配问题。

(4)在DS1820测温程序设计中,向DS1820发出温度转换命令后,程序总要等待DS1820的返回信号,一旦某个DS1820接触不好或断线,当程序读该DS1820时,将没有返回信号,程序进入死循环。这一点在进行DS1820硬件连接和软件设计时也要给予一定的重视。测温电缆线建议采用屏蔽4芯双绞线,其中一对线接地线与信号线,另一组接VCC和地线,屏蔽层在源端单点接地。

3.3温度检测电路

DS18B20最大的特点是单总线数据传输方式,DS18B20的数据I/O均由同一条线来完成。DS18B20的电源供电方式有2种:外部供电方式和寄生电源方式。工作于寄生电源方式时,VDD和GND均接地,他在需要远程温度探测和空间受限的场合特别有用,原理是当1Wire总线的信号线DQ为高电平时,窃取信号能量给DS18B20供电,同时一部分能量给内部电容充电,当DQ为低电平时释放能量为DS18B20供电。但寄生电源方式需要强上拉电路,软件控制变得复杂(特别是在完成温度转换和拷贝数据到E2PROM时),同时芯片的性能也有所降低。因此,在条件允许的场合,尽量采用外供电方式。无论是内部寄生电源还是外部供电,I/O

第三不封硬件设计17

口线要接5KΩ左右的上拉电。在这里采用前者方式供电。DS18B20与芯片连接电路如图3.3.1所示:

图3.3.1DS18B20和单片机的接口连接

外部电源供电方式是DS18B20最佳的工作方式,工作稳定可靠,抗干扰能力强,而且电路也比较简单,可以开发出稳定可靠的多点温度监控系统。在开发中使用外部电源供电方式,毕竟比寄生电源方式只多接一根VCC引线。在外接电源方式下,可以充分发挥DS18B20宽电源电压范围的优点,即使电源电压VCC降到3V时,依然能够保证温度量精度。

由于DS18B20只有一根数据线,因此它和主机(单片机)通信是需要串行通信,而AT89S51有两个串行端口,所以可以不用软件来模拟实现。经过单线接口访问DS18B20必须遵循如下协议:初始化、ROM操作命令、存储器操作命令和控制操作。要使传感器工作,一切处理均严格按照时序。

3.4温度报警电路

本设计的发挥部分,是加入了报警,如果我们所设计的系统是监控某一设备,一当设备的温度超过我们所设定的温度值(35℃~55℃)时,系统会产生报警。

报警时由单片机产生一定频率的脉冲,由P2.7引脚输出,P2.7外接一只PNP的三极管来驱动杨声器发出声音,以便操作员来维护,从而达到报警的目的。如下图3-4-1所示:

18数字显示温度计的设计

图3.4.1温度报警电路

3.5复位电路

本系统中上电复位采用电平方式开关复位,如图3.5.1所示。上电复位用RC电路,电容用10F,电阻用10K。

根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。

单片机复位是使CPU和系统中的其它功能部件都处在一个确定的初始状态,复位是单片机的初始化操作,其主要功能是把PC初始化为0000H,使单片机从0000H单元开始执行程序。单片机复位的条件是:必须使RST引脚加上持续两个机器周期的高电平,复位电路在接电瞬间,RESET端的电位与VCC相同,随着充电电流的减少,RESET的电位逐渐下降。只要保证RESET为高电平的时间大于两个机器周期,便能正常复位。复位后PC值为0000H,表明复位后程序从0000H开始执行,从第一个单元取指令。例如,若时钟频率为12Mz,每机器周期为1us,则只需2us以上的高电平,在RST引脚出现高电平后的第二个机器周期执行复位。单片机复位期间不产生ALE信号,即ALE=1.表明单片机复位期间不会有任何取指操作。

第三不封硬件设计19

本设计采用的是按键电平复位的方式,其电路如图3.5.1所示,这种方式电路比较简单,且又避免了上电自动复位需要切断电源的缺点。

图3.5.1复位电路

3.6时钟电路

单片机的晶振频率低于40MHZ,所用我们采用12MHZ,加两个30p电容。如图3.6.1所示。

时钟电路用于产生单片机工作所需要的时钟信号,单片机本身就是一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格的按时序进行工作。

一般的晶振振荡电路都是在一个反相放大器的两端接入晶振,再有两个电容分别接到晶振的两端,另一端接地,这两个电容串联的容量值应该等于负载电容。

在单片机内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2,在芯片的外部通过这两个引脚跨接晶体震荡器和微调电容,形成反馈电路,就构成一个稳定的自激震荡器,一般的晶振的负载电容为20p-45p之间,考虑到元件引脚的等效输入电容,本设计采用两个22p的电容构成晶振的振荡电路。设计电路中所使用的是12MHz的晶振,机器周期为1us,具体的时钟电路如图3.6.1所示。

图3.6.1晶振电路

20数字显示温度计的设计

第三不封硬件设计21

3.7显示电路

温度的显示可以采用LED数码管来显示,LED亮度高、醒目,但是电路复杂,占用资源多且信息量小。而采用液晶显示器有明显的优点:工作电流比LED小几个数量级,故其功耗低;尺寸小,厚度约为LED的1/3;字迹清晰、美观,寿命长,使用方便,故本设计采用LCD12864来显示温度。

3.7.1LCD12864引脚接口

LCD12864采用标准的20脚接口,其中:第1脚:VSS为地电源第2脚:VDD接5V正电源

第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度

第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。第7~14脚:D0~D7为8位双向数据线。第15~17脚:地址的传输端。第18脚:空引脚。第19脚:接高电平+5V。第20脚:接地引脚。

3.7.2LCD12864和AT89S51连接

LCD12864液晶显示模块可以和单片机AT89S51直接接口,电路如图3.7.1所示。

22数字显示温度计的设计

图3.7.1LCD12864和AT89S51连接

3.8主电路原理图

第三不封硬件设计23

图3.5.1主电路原理图

数字显示温度计的工作原理:

基于AT89S51的温度测量系统电路图把温度转化成带符号的数字信号(以十六位补码形式,占两个字节),若采用带屏蔽的双绞电缆线,连线的长度可以达到150m,输出脚I/0直接与单片机的P3.4相连,R1为上拉电阻,传感器采用外部电源供电。AT89S51是整个系统的核心部分,内含2KB的FLASHROM,用户程序存放在这里。显示器模块由四位一体的共阳数码管和四个9012组成。系统程序分传感器控制程序和显示器程序两部分,传感器控制程序是按照DSl8B20的通信协议编制。系统的工作是在程序控制下,完成对传感器的读写和对温度的显示。

产品的主要技术指标:测量范围:0~+125℃,测量精度:0.5℃;反应时间小于等于500ms。

第四部分软件设计25

第四部分软件设计

4.1概述

整个系统的功能是由硬件电路配合软件来实现的,当硬件基本定型后,软件的功能也就基本定下来了。从软件的功能不同可分为两大类:一是监控软件(主程序),它是整个控制系统的核心,专门用来协调各执行模块和操作者的关系。二是执行软件(子程序),它是用来完成各种实质性的功能如测量、计算、显示、通讯等。每一个执行软件是一个小的功能执行模块。这里将各执行模块一一列出,并为每一个执行模块进行功能定义和接口定义。各执行模块规划好后,就可以规划监控程序了。首先要根据系统的总体功能选择一种最合适的监控程序结构,然后根据实时性的要求,合理地安排监控软件和各执行模块之间地调度关系。

4.2主程序模块

主程序需要调用4个子程序,各模块程序功能如下:

(1)数码管显示程序:向数码的显示送数,控制系统的显示部分。

(2)温度测试及处理程序:对温度芯片送过来的数据进行处理,进行判断和显示。(3)报警子程序:进行温度上下限判断及报警输出。(4)中断设定程序:实现设定上下限报警功能。

主程序流程见图4.2.1:

4.3各模块流程设计

下面对主要子程序的流程图做介绍

温度检测流程DS18B20在单片机控制下分三个阶段:(1)DS18B20初始化:

26数字显示温度计的设计

4.4报警模块流程

报警程序读出温度值C清除报警标志位YC>MAX?YC第五部分仿真27

第五部分仿真

5.1PROTEUS介绍

Proteus软件是英国Labcenterelectronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前最好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等,2010年即将增加Cortex和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器。

Proteus软件具有其它EDA工具软件(例:multisim)的功能。这些功能是:(1)原理布图;

(2)PCB自动或人工布线;(3)SPICE电路仿真。革命性的特点:(1)互动的电路仿真

用户甚至可以实时采用诸如RAM,ROM,键盘,马达,LED,LCD,AD/DA,部分SPI器件,部分IIC器件。

(2)仿真处理器及其外围电路

可以仿真51系列、AVR、PIC、ARM、等常用主流单片机。还可以直接在基于原理图的虚拟原型上编程,再配合显示及输出,能看到运行后输入输出的效果。配合系统配置的虚拟逻辑分析仪、示波器等,Proteus建立了完备的电子设计开发环境。

28数字显示温度计的设计

5.2AltiumDesigner介绍

r是PORTEL公司在80年代末推出的EDA软件PORTEL的升AltiumDesigneDesigner

级版本,在电子行业的CAD软件中,它当之无愧地排在众多EDA软件的前面,是电子设计者的首选软件,它较早就在国内开始使用,在国内的普及率也最高,有些高校的电子专业还专门开设了课程来学习它,几乎所有的电子公司都要用到它,许多大公司在招聘电子设计人才时在其条件栏上常会写着要求会使用Altium

Designe。

早期的AltiumDesign主要作为印制板自动布线工具使用,运行在DOS环境,对硬件的要求很低,在无硬盘286机的1M内存下就能运行,但它的功能也较少,只有电原理图绘制与印制板设计功能,其印制板自动布线的布通率也低,而现今的PROTEL已发展到AltiumDesigne(网络上可下载到它的测试板),是个庞大的EDA软件,完全安装有200多M,它工作在WINDOWS95环境下,是个完整的板级全方位电子设计系统,它包含了电路原理图绘制、模拟电路与数字电路混合信号仿真、多层印制电路板设计(包含印制电路板自动布线)、可编程逻辑器件设计、图表生成、电子表格生成、支持宏操作等功能,并具有Client/Server(客户/服务器)体系结构,同时还兼容一些其它设计软件的文件格式,如ORCAD,PSPICE,EXCEL等,其多层印制线路板的自动布线可实现高密度PCB的100%布通率。在国内PROTEL软件较易买到,有关PROTEL软件和使用说明的书也有很多,这为它的普及提供了基础。

AltiumDesigne共分5个模块,分别是原理图设计、PCB设计(包含信号

完整性分析)、自动布线器、原理图混合信号仿真、PLD设计。以下介绍一些Altium

Design的部分最新功能:

(1)可生成30多种格式的电气连接网络表;(2)强大的全局编辑功能;

(3)在原理图中选择一级器件,PCB中同样的器件也将被选中;

(4)同时运行原理图和PCB,在打开的原理图和PCB图间允许双向交叉查找

第五部分仿真29

元器件、引脚、网络;

(5)既可以进行正向注释元器件标号(由原理图到PCB),也可以进行反向注释(由PCB到原理图),以保持电气原理图和PCB在设计上的一致性;

(6)满足国际化设计要求(包括国标标题栏输出,GB4728国标库);*方便易用的数模混合仿真(兼容SPICE3f5);

(7)支持用CUPL语言和原理图设计PLD,生成标准的JED下载文件;*PCB可设计32个信号层,16个电源-地层和16个机加工层;

(8)可以输入和输出DXF、DWG格式文件,实现和AutoCA等软件的数据交换;(9)强大的“规则驱动”设计环境,符合在线的和批处理的设计规则检查。

第六部分综合调试31

第六部分综合调试

6.1焊接

6.1.1焊接要求

(1)电阻、二极管(发光二极管除外)均采用水平安装,紧贴印刷版。(2)电解电容等尽量插到底,元件底面离印刷版最高不能大于4毫米。(3)插件装配要美观、均匀、端正、整齐,不能歪斜,高矮要有序。(4)所焊出来的焊点要求圆滑、光亮、防止虚焊、搭焊和散锡。(5)布局合理,疏密适当。(6)用比较好的助焊剂。6.1.2焊接方法

(1)右手持电烙铁。左手用尖嘴钳或镊子夹持元件或导线。焊接前,电烙铁要充分预热。烙铁头刃面上要吃锡,即带上一定量焊锡。

(2)将烙铁头刃面紧贴在焊点处。电烙铁与水平面大约成60℃角。以便于熔化的锡从烙铁头上流到焊点上。烙铁头在焊点处停留的时间控制在2~3秒钟。

(3)抬开烙铁头。左手仍持元件不动。待焊点处的锡冷却凝固后,才可松开左手。

(4)用镊子转动引线,确认不松动,然后可用偏口钳剪去多余的引线。(5)焊接时先用焊锡把导线接一下,一遍有毛刺,有放电现象。

6.2调试

对于整个系统的调试是将温度传感器置于被监测温度处,接通系统电源,系统开始运行,随着温度的不断上升,显示温度不断变化,离开被监测温度处,显示温度不断下降。当温度大于27℃或小于24℃时,蜂鸣器就会发出报警信号。再将显示温度同时间温度进行多次计算比较,结果显示温度同实际温度间的误差小

32数字显示温度计的设计

于0.1℃,满足系统设计要求。以上过程通过多次反复检测系统均运行正常、稳定,系统基本上完全实现了预定的功能。

系统需要的改进方向:(1)停电正常工作

系统能在断电时正常工作,使用将更加方便。(2)在外界干扰出错后能自动恢复正常

在外界干扰出错后能自动恢复正常,就不必要手动复位。(3)电路元器件占空间较大,对于有的场合不适用。

将各种繁杂的电路元器件集成化,便于在小型温控地方携带与安装。

第七部分总结与体会33

第七部分总结与体会

作为一名信息技术方面的大二学生,通过这半年的时间在对本课题的设计过程中,深深地体会到“工欲善其事,必先利其器”的道理,生活中无论做什么事都应该事前有充分的准备,做到心中有数,才能更好的完成任务。

在做这次比赛设计的过程中,我感触最深的当属查阅大量的设计资料。为了让自己的设计更加完善,查阅这方面的实际资料是十分必要的,也是必不可少的。其次,在这次课程设计中,全面实践一个基于单片机的应用系统的开发过程,我们运用了以前学过的专业课知识,如:proteus仿真、C语言、单片机知识等是一个综合性很高的实践。一些以前没有学得很杂实的课程的内容,由于需要在实践中运用,刚开始也感到很头痛。但回过头再去看有关的资料和书籍,经过一段时间的钻研,对与这些知识点的相关的背景,概念和解决方案理解得更透彻了,学习起来也越来越有兴趣,越来越轻松。

另外还充分体会了从事单片机开发工作需要特别严谨认真的态度和作风,一点都马虎不得。每一个细微的细节都必须十分的注意,如果不认真思考决策,就会出现或大或小的错误,如果早期的错误隐藏下来,对后面的工作影响就会很大,甚至有时要推倒很多前面做的工作重来。要做好一个比赛的设计,就必须做到:在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机有哪些资源;要有一个清晰的思路和一个完整的软件流程图;在设计程序时,不能妄想一次将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,这样为资料的保留和交流提供了方便;在设计中遇到的问题要记录,以免下次遇到同样的问题。

经过不断的学习和反复的实践,辛勤努力有了回报,终于做出了一个简单的系统,虽然这个系统的功能非常的简单,而且在实际的运用中,也许还有些不足。从这次的设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单片机更应该这样,程序只有在经常地写与读的过程中才能提高,这就是我在这次设计中的最大收获。我们学习了那么多的东西从来未用过感到有点失望,但现在用的时候却不知道从何入手。

参考文献35

致谢

在本系统的设计过程和论文编写过程中,很多老师、同学和朋友给予了我许多无私的帮助,尤其是我的指导老师协会会长柴雪强给我的设计和论文提出了很多宝贵的修改意见,在这里,我向这些无私帮助我的人表示衷心的感谢和良好的祝愿。

通过这次比赛设计,受益匪浅,这主要得益于认真负责的工作态度、严谨活泼的治学精神和深厚专业的理论水平。在撰写论文之前,自己对论文的基本要求理解不是很充分,在老师的帮助与指导下,现在对论文有了一定的认识,对它的基本结构、所要论述的重点问题、以及撰写论文的基本步骤和评审都达到了相当的水平。老师无论在理论上还是在实践中,都给予了本人很大的帮助,使自己的理论和技术水平都得到很大的提高,这对于自己以后的工作和学习都是一种巨大的鼓舞。

至此,衷心感谢各位老师及同学多年来的辛勤培育和教导!并衷心祝愿老师:工作顺利!身体健康!万事如意!

参考文献37

参考文献

[1]杨振江,单片机原理与实践指导[M],北京:中国电力出版社,2008

[2]夏继强,单片机应用设计培训教程——实践篇[M],北京:北京航空航天大学出版社,2008.[3]

郭天祥,51单片机程序设计教程

哈尔滨

电子工业出版社

2008

[4]祈伟杨亭.《单片机C51程序设计教程与实验》[M]北京:北京航空航天大学出版社,2003年.

[5]康华光.电子技术基础(模拟部分)(第五版)[M].武汉:华中科技大学出版社,2007.[7]51单片机设计与仿真--基于keil与proteus

丁明亮

:北京航天航空大学出版社

[8]张毅刚,彭喜元,孟升卫,刘兆庆.《MCS-51单片机使用子程序设计》[M].哈尔滨:哈尔滨工业大学出版社,2003年.

[9]魏大慧,《基于AT89S52单片机的数字温度控制系统软件设计》[D]

[10]张越,张炎,赵延军,《基于DS18B20温度传感器的数字温度计》[D],2006年.

附录39

附录

附录1:源程序代码

功能:实现对DS18B20的读取原理:单总线协议

注意:单总线协议对延时要求比较严格,此程序中采用的是11.0592M的晶振。#include#include#include#defineucharunsignedchar#defineuint/*端口定义*/#defineLCD_datasbitLCD_RSsbitLCD_RWsbitLCD_EN

===

P0P2^0;P2^1;P2^2;P3^7;

//数据口//寄存器选择输入//液晶读/写控制//液晶使能控制//串/并方式控

unsignedint

sbitLCD_PSB=

voiddelay_1ms(uintx){uinti,j;for(j=0;jfor(i=0;i<110;i++);}

/*******************************************************************//*

/*写指令数据到LCD

/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。/*

*/*/*/*/

40数字显示温度计的设计

/*******************************************************************/voidwrite_cmd(ucharcmd){

LCD_RS=0;LCD_RW=0;LCD_EN=0;P0=cmd;delay_1ms(5);LCD_EN=1;delay_1ms(5);LCD_EN=0;}

/*******************************************************************//*

/*写显示数据到LCD

/*RS=H,RW=L,E=高脉冲,D0-D7=数据。/*

*/*/*/*/

/*******************************************************************/voidwrite_dat(uchardat){

LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;delay_1ms(5);LCD_EN=1;delay_1ms(5);LCD_EN=0;}

/*********************************************************/

附录41

/*

/*设定显示位置/*

*/*/*/

/*********************************************************/voidlcd_pos(ucharX,ucharY){uchar

pos;

if(X==0){X=0x80;}elseif(X==1){X=0x90;}elseif(X==2){X=0x88;}elseif(X==3){X=0x98;}pos=X+Y;write_cmd(pos);}

//显示地址

/*******************************************************************//*/*/*

LCD初始化设定

*/*/*/

/*******************************************************************/voidlcd_init(){

LCD_PSB=1;write_cmd(0x30);delay_1ms(5);write_cmd(0x0C);

//显示开,关光标//并口方式//基本指令操作

42数字显示温度计的设计

delay_1ms(5);write_cmd(0x01);delay_1ms(5);}

//清除LCD的显示内容

sbitDQ=P3^0;//定义DS18B20端口DQ

sbitBEEP=P3^1;//蜂鸣器驱动线sbitjdq=P3^2;

bitpresence,flag;

bitcompare_th,compare_tl,alarm_on_off=0,temp_th,temp_tl;sbitsbitsbitsbit

K1=P1^0;K2=P1^1;K3=P1^2;K4=P1^7;

cdis2[]={\"cdis3[]={\"DS18B20cdis4[]={\"

\ERROR\

\\TL:-:

-\:\

code

\

ucharcodeucharcodeucharcodeucharcodeucharcodeucharcodeucharcode/*uchar

PLEASECHECK

cdis5[]={\"TEMP:cdis6[]={\"TH:table[]={\"日期:table1[]={\"时间:

table2[]={0xCF,0xFF,0xB7,0xFF,0xB7,0xFF,0xCC,0x17,0xF9,0xC7,0xF3,0xE7,0xF3,0xF7,0xF3,0xFF,0xF3,0xFF,0xF3,0xFF,0xF3,0xFF,0xF9,0xF7,0xFC,0xEF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFF};

*/

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

附录43

unsignedchardataunsignedchardata显示

unsignedchardataunsigned

temp_alarm[2]={0x00,0x00};display[5]=

{0x00,0x00,0x00,0x00,0x00};//温度值

display1[3]=

data

{0x00,0x00,0x00};//温度报警值显示

RomCode[8]

=

char

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

#definedelayNOP();{_nop_();_nop_();_nop_();_nop_();};unsignedcharTemp,temp_comp,timecount,count;unsignedchar

crc;

voidDisp_Temp_alarm(ucharaddr,ucharnum);void

spk(ucharaddr);

voidset_temp_alarm();voidtemp_compare();voidbeep();

/*******************************************************************//*

/*us级延时函数/*

*/*/*/

/*******************************************************************/

voidDelay(unsignedintnum){

while(--num);}

/*******************************************************************//*

/*初始化ds1820/*

*/*/*/

44数字显示温度计的设计

/*******************************************************************/Init_DS18B20(void){

DQ=1;Delay(8);

//DQ复位//稍做延时

DQ=0;Delay(90);

//单片机将DQ拉低//精确延时大于480us

DQ=1;Delay(8);

//拉高总线

presence=DQ;Delay(100);DQ=1;

//如果=0则初始化成功=1则初始化失败

return(presence);//返回信号,0=presence,1=nopresence}

/*******************************************************************//*

/*读一个字节/*

*/*/*/

/*******************************************************************/ReadOneChar(void){

unsignedchari=0;unsignedchardat=0;

for(i=8;i>0;i--)

附录45

{

DQ=0;//给脉冲信号dat>>=1;

DQ=1;//给脉冲信号

if(DQ)dat|=0x80;Delay(4);}

return(dat);}

/*******************************************************************//*

/*写一个字节/*

*/*/*/

/*******************************************************************/WriteOneChar(unsignedchardat){

unsignedchari=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;Delay(5);

DQ=1;dat>>=1;}}

46数字显示温度计的设计

/*******************************************************************//*

/*温度报警值写入DS18B20/*

*/*/*/

/*******************************************************************/Write_Temperature_alarm(void){

Init_DS18B20();

WriteOneChar(0xCC);WriteOneChar(0x4e);WriteOneChar(temp_alarm[0]);WriteOneChar(temp_alarm[1]);

WriteOneChar(0x7f);

//跳过读序号列号的操作

//将设定的温度报警值写入DS18B20//写TH//写TL

//12位精确度

Init_DS18B20();

WriteOneChar(0xCC);WriteOneChar(0x48);}

//跳过读序号列号的操作

//把暂存器里的温度报警值拷贝到EEROM

/*******************************************************************//*

/*读取64位序列码/*

*/*/*/

/*******************************************************************/Read_RomCord(void){

unsignedcharj;Init_DS18B20();

附录47

WriteOneChar(0x33);for(j=0;j<8;j++){

//读序列码的操作

RomCode[j]=ReadOneChar();}}

/*******************************************************************//*

/*DS18B20的CRC8校验程序/*

*/*/*/

/*******************************************************************/ucharCRC8(){

uchari,x;ucharcrcbuff;

crc=0;

for(x=0;x<8;x++){

crcbuff=RomCode[x];for(i=0;i<8;i++){

if(((crc^crcbuff)&0x01)==0)crc>>=1;else{

crc^=0x18;crc>>=1;crc|=0x80;}

//CRC=X8+X5+X4+1

48数字显示温度计的设计

crcbuff>>=1;}

}

returncrc;}

/*******************************************************************//*

/*数据转换与显示/*

*/*/*/

/*******************************************************************/

Disp_RomCode(ucharH_num){

ucharj;

if(H_num==1)lcd_pos(2,0);if(H_num==2)lcd_pos(3,0);

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

Temp=RomCode[j];

display[0]=((Temp&0xf0)>>4);if(display[0]>9)

{display[0]=display[0]+0x37;}else{display[0]=display[0]+0x30;}write_dat(display[0]);

//高位数显示

附录49

display[1]=(Temp&0x0f);if(display[1]>9)

{display[1]=display[1]+0x37;}else{display[1]=display[1]+0x30;}write_dat(display[1]);}}

//低位数显示

/*******************************************************************//*

/*读取温度/*

*/*/*/

/*******************************************************************/Read_Temperature(void){

ucharTR0=0;

Init_DS18B20();

i;

//关中断,防止读数错误

WriteOneChar(0xCC);WriteOneChar(0x44);

//跳过读序号列号的操作//启动温度转换

Init_DS18B20();

WriteOneChar(0x55);for(i=0;i<8;i++)

WriteOneChar(RomCode[i]);

//匹配ROM命令

WriteOneChar(0xBE);//读取温度寄存器

50数字显示温度计的设计

temp_data[0]=ReadOneChar();temp_data[1]=ReadOneChar();temp_alarm[0]=ReadOneChar();temp_alarm[1]=ReadOneChar();

//温度低8位//温度高8位//温度报警TH

//温度报警TL

temp_comp=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);

//取温度整数值

TR0=1;}

/*******************************************************************//*

/*数据转换与温度显示/*

*/*/*/

//开中断

/*******************************************************************/Disp_Temperature(){

uchars=0,i;

if(temp_data[1]>127){

temp_data[0]=(~temp_data[0])+1;if((~temp_data[0])>=0xff)temp_data[1]=(~temp_data[1])+1;elsetemp_data[1]=~temp_data[1];s=1;}

//取反加一,将补码变成原码//温度为负值

display[4]=temp_data[0]&0x0f;display[0]=(display[4]*10/16)+0x30;

display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);

附录51

display[3]=display[4]/100+0x30;display[1]=display[4]%100;display[2]=display[1]/10+0x30;display[1]=display[1]%10+0x30;

if(display[3]==0x30){

display[3]=0x20;if(display[2]==0x30)display[2]=0x20;}if(s)

display[3]=0x2d;

//高位为0,不显示

//次高位为0,不显示

//显示负号

lcd_pos(2,3);

write_dat(display[3]);write_dat(display[2]);write_dat(display[1]);write_dat('.');write_dat(display[0]);write_dat(0x00);

write_dat('C');}

/*******************************************************************//*

/*蜂鸣器响一声/*

*/*/*/

//小数位数显示//显示自定义字符

//显示C//百位数显示//十位数显示//个位数显示

/*******************************************************************/voidbeep(){

52数字显示温度计的设计

unsignedchary;for(y=0;y<100;y++){

Delay(70);BEEP=!BEEP;}BEEP=1;Delay(25000);}

//关闭蜂鸣器//BEEP取反

/*******************************************************************//*

/*ROMCORD显示菜单/*

*/*/*/

/*******************************************************************/void{

ucharm;lcd_init();

//初始化LCD

RomCode_Menu()

lcd_pos(2,0);for(m=0;m<16;m++)//write_dat(cdis1[m]);

//设置显示位置为第一行//显示字符

Read_RomCord();CRC8();if(crc==0){

//Disp_RomCode(2);}

//读取64位序列码//CRC效验//CRC效验正确

//显示64位序列码

附录53

}

/*******************************************************************//*

/*DS18B20ERROR显示菜单/*

*/*/*/

/*******************************************************************/void{

uchar

m;

//初始化LCD

Error_Menu()

lcd_init();

lcd_pos(2,0);for(m=0;m<16;m++)write_dat(cdis3[m]);

//设置显示位置为第一行的第1个字符

//显示字符

lcd_pos(3,0);for(m=0;m<16;m++)write_dat(cdis4[m]);}

//设置显示位置为第二行第1个字符

//显示字符

/*******************************************************************//*

/*DS18B20正常显示菜单/*

*/*/*/

/*******************************************************************/void{uchar

m,i;Natural_Menu()

54数字显示温度计的设计

delay_1ms(10);lcd_init();

//延时//初始化LCD

lcd_init();lcd_pos(0,0);i=0;

while(table[i]!='\\0'){

write_dat(table[i]);i++;}

lcd_pos(1,0);i=0;

while(table1[i]!='\\0'){

write_dat(table1[i]);i++;}

//显示字符

//设置显示位置为第三行的第1个字符

//显示字符

//设置显示位置为第二行的第1个字符

lcd_pos(2,0);for(m=0;m<16;m++)write_dat(cdis5[m]);

//设置显示位置为第一行的第1个字符

//显示字符

lcd_pos(3,0);for(m=0;m<17;m++)

//设置显示位置为第二行第1个字符

附录55

write_dat(cdis6[m]);//显示字符

Read_Temperature();Disp_Temp_alarm(0x9a,0);Disp_Temp_alarm(0x9d,1);Disp_Temperature();}

//显示TH值//显示TL值//显示实时温度值

/***********************************************************************

以下是DS1302芯片的操作程序

************************************************************************/

unsignedcharcodedigit[10]={\"0123456789\sbitSCLK=P1^3;sbitDATA=P1^4;sbitRST=P1^5;

//位定义1302芯片的接口,数据输出端定义在P1.1引脚//位定义1302芯片的接口,复位端口定义在P1.1引脚

//定义字符数组显示数字

/*****************************************************函数功能:延时1ms

(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒***************************************************/voiddelay1ms(){

unsignedchari,j;for(i=0;i<10;i++)for(j=0;j<33;j++);

56数字显示温度计的设计

}

/*****************************************************函数功能:延时若干毫秒入口参数:n

***************************************************/voiddelaynms(unsignedcharn){

unsignedchari;for(i=0;i/*****************************************************

/*****************************************************

函数功能:延时若干微秒入口参数:n

***************************************************/voiddelaynus(unsignedcharn){

unsignedchari;for(i=0;i;}

/*****************************************************函数功能:向1302写一个字节数据入口参数:x

附录57

***************************************************/voidWrite1302(unsignedchardat){

unsignedchari;SCLK=0;delaynus(2);for(i=0;i<8;i++){

DATA=dat&0x01;delaynus(2);SCLK=1;delaynus(2);SCLK=0;dat>>=1;

据位

}

//取出dat的第0位数据写入1302//稍微等待,使硬件做好准备//上升沿写入数据

//稍微等待,使硬件做好准备//重新拉低SCLK,形成脉冲

//将dat的各数据位右移1位,准备写入下一个数//拉低SCLK,为脉冲上升沿写入数据做好准备//稍微等待,使硬件做好准备//连续写8个二进制位数据

}

/*****************************************************函数功能:根据命令字,向1302写一个字节数据入口参数:Cmd,储存命令字;dat,储存待写的数据***************************************************/voidWriteSet1302(unsignedcharCmd,unsignedchardat){RST=0;SCLK=0;RST=1;delaynus(2);Write1302(Cmd);Write1302(dat);

//禁止数据传递

//确保写数居前SCLK被拉低//启动数据传输

//稍微等待,使硬件做好准备//写入命令字//写数据

58数字显示温度计的设计

SCLK=1;RST=0;}

//将时钟电平置于已知状态//禁止数据传递

/*****************************************************函数功能:从1302读一个字节数据入口参数:x

***************************************************/unsignedcharRead1302(void){

unsignedchari,dat;delaynus(2);for(i=0;i<8;i++){

dat>>=1;

低位

if(DATA==1)dat|=0x80;SCLK=1;delaynus(2);SCLK=0;delaynus(2);}returndat;}

/*****************************************************函数功能:根据命令字,从1302读取一个字节数据入口参数:Cmd

***************************************************/unsignedchar{

ReadSet1302(unsignedcharCmd)

//将读出的数据返回//如果读出的数据是1

//将1取出,写在dat的最高位//将SCLK置于高电平,为下降沿读出//稍微等待

//拉低SCLK,形成脉冲下降沿//稍微等待

//将dat的各数据位右移1位,因为先读出的是字节的最//稍微等待,使硬件做好准备//连续读8个二进制位数据

附录59

unsignedchardat;RST=0;SCLK=0;RST=1;

Write1302(Cmd);dat=Read1302();SCLK=1;RST=0;returndat;}

/*****************************************************函数功能:1302进行初始化设置

***************************************************/voidInit_DS1302(void)

{

unsignedcharflag;

//拉低RST

//确保写数居前SCLK被拉低//启动数据传输//写入命令字//读出数据

//将时钟电平置于已知状态//禁止数据传递//将读出的数据返回

flag=ReadSet1302(0x81);if(flag&0x80)

{

WriteSet1302(0x8E,0x00);写入不保护指令

WriteSet1302(0x80,((50/10)<<4|(50%10)));写入秒的初始值

WriteSet1302(0x82,((34/10)<<4|(34%10)));写入分的初始值

WriteSet1302(0x84,((8/10)<<4|(8%10)));//根据写小时寄存器命令字,写入小时的初始值

WriteSet1302(0x86,((30/10)<<4|(30%10)));//根据写日寄存器命令字,写入日的初始值

//根据写分寄存器命令字,//根据写秒寄存器命令字,//根据写状态寄存器命令字,

60数字显示温度计的设计

WriteSet1302(0x88,((3/10)<<4|(3%10)));//根据写月寄存器命令字,写入月的初始值

WriteSet1302(0x8c,((12/10)<<4|(12%10)));字,写入小时的初始值

//根据写小时寄存器命令

}}

/*{WriteSet1302(0x8E,0x00);//根据写状态寄存器命令

字,写入不保护指令

WriteSet1302(0x80,((55/10)<<4|(55%10)));写入秒的初始值

WriteSet1302(0x82,((38/10)<<4|(38%10)));写入分的初始值

WriteSet1302(0x84,((13/10)<<4|(13%10)));//根据写小时寄存器命令字,写入小时的初始值

WriteSet1302(0x86,((30/10)<<4|(30%10)));//根据写日寄存器命令字,写入日的初始值

WriteSet1302(0x88,((3/10)<<4|(3%10)));//根据写月寄存器命令字,写入月的初始值

WriteSet1302(0x8c,((12/10)<<4|(12%10)));//根据写年寄存器命令字,写入年的初始值

WriteSet1302(0x90,0xa5);充电方式

WriteSet1302(0x8E,0x80);护指令}*/

//根据写状态寄存器命令字,写入保

//打开充电功能选择2K电阻//根据写分寄存器命令字,//根据写秒寄存器命令字,

附录61

/**************************************************************以下是1302数据的显示程序

**************************************************************//*****************************************************函数功能:显示秒入口参数:x

***************************************************/voidDisplaySecond(unsignedcharx){

unsignedchari,j;i=x/10;//取十位j=x%10;//取个位lcd_pos(1,7);

//写显示地址,将在第2行第7列开始显示

//将百位数字的字符常量写入LCD//将十位数字的字符常量写入LCD//延时1ms给硬件一点反应时间//j,k,l分别储存温度的百位、十位和个位

write_dat(digit[i]);write_dat(digit[j]);delaynms(50);}

/*****************************************************函数功能:显示分钟入口参数:x

***************************************************/voidDisplayMinute(unsignedcharx){

unsignedchari,j;i=x/10;//取十位j=x%10;//取个位

//j,k,l分别储存温度的百位、十位和个位

62数字显示温度计的设计

lcd_pos(1,5);//写显示地址,将在第2行第7列开始显示

//将百位数字的字符常量写入LCD//将十位数字的字符常量写入LCD//延时1ms给硬件一点反应时间

write_dat(digit[i]);write_dat(digit[j]);delaynms(50);}

/*****************************************************函数功能:显示小时入口参数:x

***************************************************/voidDisplayHour(unsignedcharx){

unsignedchari,j;i=x/10;//取十位j=x%10;//取个位lcd_pos(1,3);

//写显示地址,将在第2行第7列开始显示

//将百位数字的字符常量写入LCD//将十位数字的字符常量写入LCD//延时1ms给硬件一点反应时间//j,k,l分别储存温度的百位、十位和个位

write_dat(digit[i]);write_dat(digit[j]);delaynms(50);}

/*****************************************************函数功能:显示日入口参数:x

***************************************************/voidDisplayDay(unsignedcharx){

unsignedchari,j;i=x/10;//取十位j=x%10;//取个位lcd_pos(0,7);

//写显示地址,将在第2行第7列开始显示

//将百位数字的字符常量写入LCD//j,k,l分别储存温度的百位、十位和个位

write_dat(digit[i]);

附录63

write_dat(digit[j]);delaynms(50);}

//将十位数字的字符常量写入LCD//延时1ms给硬件一点反应时间

/*****************************************************函数功能:显示月入口参数:x

***************************************************/voidDisplayMonth(unsignedcharx){

unsignedchari,j;i=x/10;//取十位j=x%10;//取个位lcd_pos(0,5);

//写显示地址,将在第2行第7列开始显示

//将百位数字的字符常量写入LCD//将十位数字的字符常量写入LCD//延时1ms给硬件一点反应时间//j,k,l分别储存温度的百位、十位和个位

write_dat(digit[i]);write_dat(digit[j]);delaynms(50);}

/*****************************************************函数功能:显示年入口参数:x

***************************************************/voidDisplayYear(unsignedcharx){

unsignedchari,j;i=x/10;//取十位j=x%10;//取个位lcd_pos(0,3);

//写显示地址,将在第2行第7列开始显示

//将百位数字的字符常量写入LCD//将十位数字的字符常量写入LCD//延时1ms给硬件一点反应时间//j,k,l分别储存温度的百位、十位和个位

write_dat(digit[i]);write_dat(digit[j]);delaynms(50);

64数字显示温度计的设计

}

voidshijian(){

unsignedcharsecond,minute,hour,day,month,year,i;

存苗、分、小时,日,月,年unsignedcharReadValue;

//储存从1302读取的数据

//分别储

ReadValue=ReadSet1302(0x81);//从秒寄存器读数据

second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//将读出数据转化

DisplaySecond(second);ReadValue=ReadSet1302(0x83);

//显示秒//从分寄存器读

minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//将读出数据转化

DisplayMinute(minute);ReadValue=ReadSet1302(0x85);

//显示分

//从分寄存器读

hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//将读出数据转化DisplayHour(hour);

ReadValue=ReadSet1302(0x87);

//显示小时//从分寄存器读

day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//将读出数据转化DisplayDay(day);

ReadValue=ReadSet1302(0x89);

//显示日//从分寄存器读

month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//将读出数据转化

DisplayMonth(month);

//显示月

附录65

ReadValue=ReadSet1302(0x8d);//从分寄存器读

year=((ReadValue&0xf0)>>4)*10+(ReadValue&0x0F);//将读出数据转化DisplayYear(year);

//显示年

}

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

*/*/*/

/*******************************************************************/voidmain(){uchar

m;

uchari;

TMOD=0x01;TH0=0x4c;TL0=0x00;//50ms定时EA=1;ET0=1;TR0=1;

66数字显示温度计的设计

//将液晶初始化

Init_DS1302();

//将1302初始化

while(1){

Init_DS18B20();if(presence){

Error_Menu();do{

Init_DS18B20();beep();}

while(presence);

}

RomCode_Menu();for(m=0;m<10;m++)Delay(5000);

//显示RomCode

附录67

Natural_Menu();do{

shijian();

Read_Temperature();Disp_Temperature();temp_compare();set_temp_alarm();if(!K4){beep();while(!K4);

//等待键释放

alarm_on_off=~alarm_on_off;}

if(!K1){beep();while(!K1);

//等待键释放

//显示RomCode

//RomCode_Menu();

while(K2);beep();

Natural_Menu();}}

while(!presence);

//等待K2键按下

68数字显示温度计的设计

}

}//endofmain()

/*********************************************************///显示报警温度

/*********************************************************/voidDisp_Temp_alarm(ucharaddr,ucharnum){

//0=TH,1=TL

display1[2]=temp_alarm[num]/100+0x30;display1[0]=temp_alarm[num]%100;display1[1]=display1[0]/10+0x30;display1[0]=display1[0]%10+0x30;

if(display1[2]==0x30){

display1[2]=0x20;if(display1[1]==0x30)display1[1]=0x20;}

//高位为0,不显示

//次高位为0,不显示

lcd_pos(addr);

write_dat(display1[2]);write_dat(display1[1]);

//百位数显示//十位数显示

附录69

write_dat(display1[0]);}

//个位数显示

/**********************************************************///Time0中断函数

/**********************************************************/voidTime0(void)interrupt1using0{

TH0=0x3c;TL0=0xb0;timecount++;if(timecount>9){

timecount=0;flag=~flag;}}

//50ms定时

/*********************************************************///温度比较函数

/*********************************************************/voidtemp_compare(){

if(temp_comp>=temp_alarm[0]){

compare_th=1;

}else

compare_th=0;

//比较TH值

70数字显示温度计的设计

if(temp_compcompare_tl=1;}else

compare_tl=0;

//比较TL值

if(compare_th){

//spk(0x46);

if(!alarm_on_off)beep();}else{

lcd_pos(3,4);write_dat(0x20);}

if(compare_tl){

spk(0x4e);

if(!alarm_on_off)beep();//jdq=0;}else{

lcd_pos(3,8);write_dat(0x20);

}

//小喇叭闪动

//静音选择//小喇叭闪动//静音选择

附录71

}

/*********************************************************///温度报警值闪动

/*********************************************************/void{

if(flag){

temp_alarm[num]=count;Disp_Temp_alarm(addr,num);}else{

lcd_pos(addr);write_dat(0x20);write_dat(0x20);write_dat(0x20);}}

//显示温度报警值

Set_tempalarm_Flash(ucharaddr,ucharnum)

/*********************************************************///设定报警值键函数

/*********************************************************/void{

if(!K2){beep();if(count!=num)

//加键

key_set(ucharnum)

72数字显示温度计的设计

count++;elsecount=0;

}if(!K1){beep();if(count!=0)count--;elsecount=num;}}

//减键

/**********************************************************温度报警值设定

***********************************************************/voidset_temp_alarm(){

if(!K3){beep();temp_th=1;

count=temp_alarm[0];

}

//取实时TH报警值

while(temp_th){

key_set(120);

Set_tempalarm_Flash(0x9a,0);

附录73

if(!K3){beep();temp_th=0;

temp_tl=1;

flag=1;

Set_tempalarm_Flash(0x9a,0);count=temp_alarm[1];}}

while(temp_tl){

key_set(120);

Set_tempalarm_Flash(0x9d,1);

//显示温度报警TH值//取实时TL报警值

if(!K3){beep();temp_tl=0;

flag=1;

Set_tempalarm_Flash(0x9d,1);//显示温度报警TL值Write_Temperature_alarm();count=0;}}}

//报警值写入DS18B20

/**********************************************************/附录2:实物显示图1

74数字显示温度计的设计

附录75

附录2:实物显示图2

因篇幅问题不能全部显示,请点此查看更多更全内容