视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
传感器课程设计 --DS18B20数字温度计的设计
2025-09-29 17:04:27 责编:小OO
文档
       

传感器课程设计说明书

    设计题目:DS18B20数字温度计的设计

专业班级:  10机电一体化2班   

姓    名:                     

          组    员:                     

指导教师:                     

                                2012年11月20日

目    录

一、设计方案比较    2

1    、设计方案    2

2    、方案论证    3

3    、方案选择    4

二、设计原理    5

1、硬件方面的介绍    5

1.1    ATC51芯片介绍    5

1.2    DS18B20简介    6

1.3    LED显示模块    10

2、软件方面的介绍    11

2.1    KeilμVision 软件    11

2.2    Proteus ISIS 软件    11

3、系统框架设计    11

4、Proteus ISIS温度测量模拟原理图    12

5、温度测量实物图    12

三、调试小结    13

1、软件调试    13

2、硬件调试    13

四、课程设计心得体会    14

五、参考文献    14

    附录一:基于DS18B20数字温度计的设计C语言程序    15

一、设计方案比较                                    

通过查阅大量相关技术资料,并结合自己的实际知识,我们主要提出了三种技术方案来实现系统功能,方案一基于热敏电阻的温度计设计;方案二为基于SHT71的数字温度计设计;方案三是基于DS18B20的数字温度计设计。下面我首先对这三种方案的实现原理分别进行说明,并分析比较它们的特点,然后再选择方案并阐述我选择方案的原因。

1、设计方案

1.1方案一基于热敏电阻的温度计设计

方案一主要由温度传感器、A/D转换电路、单片机控制电路、数码显示电路组成。采用合肥三晶电子有限公司生产的SJMFE-347-103F型热敏电阻。采集的模拟温度值输入A/D转换电路,A/D转换采用LM331型U/f变换器来实现。U/f变换器把电压信号转换为频率信号。由热敏电阻的电阻温度特性表可以求出每个温度点所对应的UIN,再由公式FOUT=256*UIN计算出每个温度点所对应的输出频率,进而由单片机处理显示被测量的温度值。温度信号处理由于热敏电阻是非线性的器件,所以温度与频率输出成非线性,需要补偿温度。单片机利用查表法实现温度补偿。所谓查表法是把事先计算或测量的数据按一定的顺序排列成表格的形式,固化在单片机内。只要测量出LM331的频率值,就可以通过查表法准确的得出环境的温度值。再交由单片机驱动数码管显示温度。这样就实现了温度的采集与显示。

1.2方案二基于SHT71的数字温度计设计

方案二主要由数字温度传感器、单片机控制电路、数码显示电路组成。SHT71将温度传感器、信号放大调理、A/D转换、I2C总线接口全部集成于一个芯片上。SHT11先利用传感器产生温度信号;经放大送至A/D 转换器进行模数转换、校准和纠错;由2线接口将信号送至微控制器;再利用微控制器完成相对湿度的非线性补偿和温度补偿。SHT71测量过程包括4 个部分:启动传输、发送测量命令、等待测量完成和读取测量数据。在启动传输时序之后, 微控制器可以向SHT71 发送命令,SHT71则通过在数据传输的第8个SCK时钟周期下降沿之后,将DATA拉低来表示正确接收到命令,并第9个SCK时钟周期的下降沿之后释放DATA线(即恢复高电平),SHT71则通过拉低DATA表示测量结束,并且把测量结果存储在内部的存储器内,然后自动进入空闲状态,等微控制器执行完其他任务后再来读取。测量数据读取前,微控制器先重新启动SCK,接着2字节的测量数据和1字节的CRC 校验将由SHT71传送给微控制器。2字节的测量数据是从高字节的高位开始传送,并以CRC 校验字节的确认为表示通信结束。微控制器需要通过拉低DATA来确认接收的每个字节,若不使用CRC校验位则微控制器可以在接收完测量数据的最低位后保持DATA为高电平来终止通信。单片机只需将读取传输的数据通过驱动数码管显示即可。

1.3方案三基于DS18B20的数字温度计设计

方案三主要也由数字温度传感器、单片机控制电路、数码显示电路组成。DS18B20 测量温度采用了特有的温度测量技术。它是通过计数时钟周期来实现的。低温度系数振荡器输出的时钟信号通过由高温度系数振荡器产生的门周期而被计数。计数器被预置在与- 55 ℃相对应的一个基权值。如果计数器在高温度系数振荡周期结束前计数到零,表示测量的温度值高于- 55℃,被预置在- 55 ℃的温度寄存器的值就增加1℃,然后重复这个过程,直到高温度系数振荡周期结为止这时温度寄存器中的值就是被测温度值,这个值以16 位形式存放在便笺式存贮器中,此温度值可由主机通过发存贮器读命令而读出,读取时低位在前,高位在后。斜率累加器用于补偿温度振荡器的抛物线特性。读出的二进制数可以直接转换为十进制由单片机驱动数码管显示输出。

2、方案论证

     2.1方案一:热敏电阻温度传感器的特点是自身的电阻值随温度而变化。热敏电阻是利用半导体材料制成的敏感组件,通常所有的热敏电阻温度传感器都是具有负温度系数的热敏电阻,它的电阻率受温度的影响很大,而且随温度的升高而减小。其优点是灵敏度高,体积小,寿命长,工作稳定,易于实现远距离测量;缺点是互换性差,非线性严重。它的测量范围一般为-10~+300℃,也可做到-200~+10℃,甚至可用于+300~+1200℃环境中作测温用。热敏电阻器温度计的精度可以达到0.1℃,感温时间可少至10s以下。

  2.2方案二:SHT7I是瑞士Sens on公司生产的具有二线串行接口的单片全校准数字式新型相对湿度和温度传感器,可用来测量相对湿度、温度和露点等参数,具有数字式输出、免调试、免标定、免外围电路及全互换的特点该传感器将CMOS芯片技术与传感器技术结合起来,发挥出强大的优势互补作用。由于SHT71是I2C总线结构的串行数据传送,它只需要DATA和SCK两根线完成数据的传送过程。因此,我们在进行程序设计的时候,也得按着I2C协议来对SHT71芯片数据访问。对于STCC52单片机本身没有I2C硬件资源,所以必须用软件来模拟I2C协议过程。一般使用单片机通用I/ O 口线来虚拟I2C 总线,并利用P1. 0 来虚拟数据线DATA ,利用P1. 1 口线来虚拟时钟线,并在DATA 端接入一只4. 7kΩ 的上拉电阻,同时,在VDD及GND 端接入一只0. 1μF 的去耦电容。温度测量范围:-40~+123.8℃;温度测量精度:±0.4℃@25℃;响应时间:<4s;低功耗 (typ. 30µW)。

SHT71是一种全新的基于智能传感器设计理念的新型传感器,该传感器将温度传感器、信号调理、数字变换、串行数字通信接口、数字校准全部集成到一个高集成度、体积极小的芯片当中,实现了温度传感器的数字式输出、且免调试、免标定、免外围电路。极大方便了温度传感器在测控领域的应用,因而该传感器在数字式温湿度测控领域有着广泛的应用前景

2.3方案三:DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃;可编程 的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温,典型的转换时间为200ms;用户可以设定温度的上下限;独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。DS1820具有测温系统简单、测温精度高、连接方便、占用口线少等优点,所以在测量领域得到广泛的运用。

3、方案选择

现代传感器在原理和结构上千差万别,如何根据具体的测量目的、测量对象以及测控环境合理地选择传感器,是单片机测控系统首先要解决的问题。当传感器选定后,与之相配套的测控电路也就可以确定了。测控结果的成败,在很大程度上取决于传感器的选择是否合理。作为单片机控制系统的前向通道的关键部件,在选择传感器时应考虑以下几个方面的:①根据测控对象与测控环境确定传感器的类型;②灵敏度的选择,通常情况下,在传感器的线性范围内,希望传感器的灵敏度越高越好;③频率响应特性,频率响应特性决定了被测量的频率范围,频率响应好,可测信号的频率范围就越宽;④线性范围,线性范围越宽,其量程越大,并且能保证一定的精度;⑤稳定性,稳定性是指其性能保持不变化的能力;⑥精度的选择,传感器的精度越高,其价格越贵,因此传感器的精度只是满足整个测控系统的精度要求就可以了,不必选得过高。

方案的选择即是传感器的选择。对比三种方案可以得知,方案一是采用模拟式温度传感器,方案二和方案三都采用数字式温度传感器。模拟式温度传感器输出的是随温度变化的模拟量信号。其特点是输出响应速度较快和MPU接口复杂。热敏电阻精度低,灵敏度高,价格最低。数字式温度传感器输出的是随温度变化的数字量,更直观,与模拟输出相比,它输出速度响应较慢,但容易与MPU接口。能输出温度数据及相关的温度控制量;能以最简方式构成高性价比、多功能的智能化温度控制系统;能在硬件的基础上通过软件编程来实现测试功能。所以数字式温度传感器才是今后发展的方向。而SHT71与DS18B20相比,前者精度较高,转换速度较快,但性价比不高,单片价格在一百左右,DS18B20相对而言价格较低在十块左右。考虑到我们设计的目的和要求不是很精密严格。所以我们选择方案三以DS18B20数字温度传感器进行后续设计。

二、 设计原理

1、硬件方面的介绍

1.1、ATC51芯片介绍

ATC51是一种低电压、高性能CMOS 8位微处理器,它自带4K字节闪存可编程可擦除只读存储器(FPEROM—Flash Programmable and Erasable Read Only Memory),俗称单片机。单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪存存储器组合在单个芯片中,ATMEL的ATC51是一种高效微控制器。ATC系列单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。它的部分引脚功能介绍如下。

     

ATC52单片机的外形及引脚排列如上图:

1.2、 DS18B20简介

    DALLAS最新单线数字温度传感器DS18B20简介新的“一线器件”体积更小、适用电压更宽、更经济 Dallas 半导体公司的数字化温度传感器DS1820是世界上第一片支持 “一线总线”接口的温度传感器。一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。DS18B20、 DS1822 “一线总线”数字化温度传感器 同DS1820一样,DS18B20也支持“一线总线”接口,测量温度范围为 -55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。DS1822的精度较差为± 2°C 。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。与前一代产品不同,新的产品支持3V~5.5V的电压范围,使系统设计更灵活、方便。而且新一代产品更便宜,体积更小。 DS18B20、 DS1822 的特性 DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。可选更小的封装方式,更宽的电压适用范围。分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。DS18B20的性能是新一代产品中最好的!性能价格比也非常出色! DS1822与 DS18B20软件兼容,是DS18B20的简化版本。省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。 继“一线总线”的早期产品后,DS1820开辟了温度传感器技术的新概念。DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。

 DS18B20中的温度传感器对温度的测量

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

这是12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。

1.2.1   DS18B20的内部结构

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

DQ为数字信号输入/输出端;

GND为电源地;

VDD为外接供电电源输入端(在寄生电源接线方式时接地)。

DS18B20的封装形式

DS18B20内部结构图

  位的ROM

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

   DS18B20温度传感器的存储器

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

     暂存存储器包含了8个连续字节,前两个字节是测得的温度信息,第一个字节的内容是温度的低八位,第二个字节是温度的高八位。第三个和第四个字节是TH、TL的易失性拷贝,第五个字节是结构寄存器的易失性拷贝,这三个字节的内容在每一次上电复位时被刷新。第六、七、八个字节用于内部计算。第九个字节是冗余检验字节。

   DS18B20的时序

    由于DS18B20采用的是单总线协议方式,即在一根数据线实现数据的双向传输,而对C51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。

    由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。

    DS18B20的复位时序

   DS18B20的读时序

  对于DS18B20的读时序分为读0时序和读1时序两个过程。对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60us才能完成。

    DS18B20的写时序

  对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。

1.2.2   DS1820使用中注意事项 

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

  较小的硬件开销需要相对复杂的软件进行补偿,由于DS1820与微处理器间采用串行数据传送,因此,在对DS1820进行读写编程时,必须严格的保证读写时序,否则将无法读取测温结果。在使用PL/M、C等高级语言进行系统程序设计时,对DS1820操作部分最好采用汇编语言实现。 

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

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

在DS1820测温程序设计中,向DS1820发出温度转换命令后,程序总要等待DS1820的返回信号,一旦某个DS1820接触不好或断线,当程序读该DS1820时,将没有返回信号,程序进入死循环。这一点在进行DS1820硬件连接和软件设计时也要给予一定的重视。

1.3、 LED显示模块

本课题的LED显示模块是由一个四联共阴七段数码管组成。七段数码管是由若干发光二极管组合而成的,一般的“8”字形显示块由“a、b、c、d、e、f、g、h”8发光二极管组成。四个七段数码管分别与P0口相连,通过对单片机输入程序达到控制显示输出的目的。

四个七段数码管由单片机的P1.0~P1.3控制亮灭,P1.0~P1.3分别对应S1~S3,当P1.0~P1.3其中之一置低电平,对应的三级管导通,段码管亮,置高电平,对应的三级管截止,段码管灭。

2、软件方面的介绍

  2.1   KeilμVision 软件

KeilμVision 2是Keil公司关于8051系列MCU的开发工具,可以用来编译C源码、汇编源程序、连接和重定位目标文件和库文件、创建HEX文件、调试目标程序等,是一种集成化的文件管理编译环境。它集成了文件编辑处理、编译连接、项目管理、窗口、工具引用和软件仿真调试等多种功能,是相当强大的开发工具。实验中我们采用KeilμVision 2来对我们编写的程序进行编译、链接和生成HEX文件。在下载程序出错时进行必要的调试,再下载验证。

2.2   Proteus ISIS 软件

Proteus ISIS是英国Labcenter公司开发的电路分析与实物仿真软件。可以仿真、分析(SPICE)各种模拟器件和集成电路,该软件的特点是: 实现了单片机仿真和SPICE电路仿结合、支持主流单片机系统的仿真、提供软件调试功能、具有强大的原理图制作功能等。

同时采用Proteus和Keil结合仿真的方法对设计的单片机测温系统进行了虚拟仿真和性能检测,得到了比较好的仿真结果和分析结果。结果证明采用Proteus和Keil结合仿真的可以大大简化硬件电路的设计过程,可以降低单片机系统的开发成本、提高效率和开发速度,具有很好的实际应用和指导意义。

3、系统框架设计如下图所示:

4、Proteus ISIS温度测量模拟原理图:

                          图1 

5、温度测量实物图

                         图2

三、调试小结

调试方法:写好一段程序后不能急于上机调试,而是先进行逻辑分析、可行性分析。用KeilμVision 2软件进行调试,不能出现错误,警告可以有,只要不影响生成HEX文件即可。理解其实现的功能,预想程序应该出现的结果。先进行软件仿真,出现错误马上修改,不断进行。先一个模块一个模块的仿真,准确后再连线总体仿真。仿真完后出现预期的效果后再下载程序到硬件进行验证,往往还有问题,还得反复修改,编译,调试,下载,验证。采用KeilμVision 2软件和单片机学习板结合调试可以大大简化软、硬件电路的设计过程。

软件调试

   采用 KeilμVision 2软件仿真的优势在于,可以设置断点、单步运行等,这在用实物调试是不能实现的,通过软件仿真,可以知道程序哪儿出错了,便于及时改正。若直接下载在芯片中用实物调试,只能知道程序错了,只能去盲目查找程序的错误之处。在程序的编写之中难免会出现一些无法错误,用KeilμVision 2编译会得到及时的提示,方便立即修改,大大缩短了设计的时间,提高设计效率。

采用Proteus ISIS软件对本系统温度测量范围的仿真,仿真模拟温度输入为27℃,系统8位七段显示数码管显示的也为27℃(如图1),由于仿真软件不考虑测量误差,所以测量的温度没有误差,做出的实物出现了一点误差,但误差在允许的范围内。

在设计初期,我们通过软件仿真发现了很多错误,比如语法错误,乱码,字符闪烁问题,后来这些问题都一一克服,语法错误一样是缺少括号,乱码是由于共阴、共阳译码的错误,还有就是由于人眼的“滞留”问题,必须要位选,在进行译码。字符闪烁一般是由于延时过短等问题。这些问题都是通过软件调试找出来的,从而说明软件调试的必要性。

硬件调试

单片机开发板是用于学习51、STC、AVR型号的单片机实验设备。根据单片机使用的型号又有51单片机开发板、STC单片机开发板、AVR单片机开发板。我们使用的是51单片机开发板,先把DS18B20与单片机P3口连接,再把写好的程序下载到芯片,然后再进行调试修改。

四、课程设计心得体会

通过这次课设让我们对传感器的运用有了进一步的了解,同时也使我们在单片机方面的知识有了进一步的巩固。对Proteus仿真软件和KeilμVision软件有了一定了解。使我们在课堂上学到的知识得到进一步加深和运用。能够使我们熟练掌握单片机控制电路的设计、程序编写和系统调试,从而全面地提高我们对单片机的软件、硬件等方面的理解。

在实验前期我们通过了对DS18B20的各种资料进行查找,了解DS18B20内部结构主要由四部分组成:位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。以及DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的E2RAM,后者存放高温度和低温度触发器TH、TL和结构寄存器。了解DS18B20复位时序、读时序、写时序还有DS18B20使用中应该注意的事项。用单片机软件的运行、以及整体系统调试,并写出完善的设计报告。总之,通过这次的课程设计我们收获了许多,而学到的知识在以后的生活和学习中会对我们有很大的帮助!我们将争取更大的进步!

五、参考文献

[1]  于永.51单片机C语言常用模块与综合系统设计实例精讲[M].北京:电子工业出版社,2008

[2] 戴永成等.基于DS18B20的数字温度测量仪[J].北华航天工业学院学报,2008

[3] 甘勇等. 数字温度传感器DS18B20 在多点测温系统中的应用. 河南农业大学学报,2001

[4] 张越等.基于DS18B20温度传感器的数字温度计[J].微电子学,2007

    [5] 赵亮等.单片机C语言编程和实例[M].人民邮电出版社,2003

[6] 张毅刚等.单片机原理及运用[M].高等教育出版社,2003

附录一:基于DS18B20数字温度计的设计C语言程序

#include"reg51.h" 

#include"intrins.h"      //_nop_();延时函数用 

#define dm      P0          //段码输出口  

#define uchar   unsigned char                

#define uint unsigned int                            

sbit DQ=P3^6;        //温度输入口 

sbit w0=P2^0;        //数码管4 

sbit w1=P2^1;        //数码管3 

sbit w2=P2^2;        //数码管2 

sbit w3=P2^3;        //数码管1 

sbit set=P2^6;        //温度设置切换键 

sbit add=P2^4;        //温度加 

sbit dec=P2^5;        //温度减 

int temp1=0;           //显示当前温度和设置温度的标志位为0时显示当前温度 

uint h;                                              

uint temp; 

uchar r; 

uchar high=35,low=20; 

uchar sign; 

uchar q=0; 

uchar tt=0; 

uchar scale; 

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

uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; 

//小数断码表 

uchar code table_dm[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40}; 

//共阴LED段码表                "0" "1" "2" "3" "4" "5" "6" "7" "8" "9""不亮""-" 

char table_dm1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //个位带小数点的断码表 

uchar data temp_data[2]={0x00,0x00};              //读出温度暂放 

uchar data display[5]={0x00,0x00,0x00,0x00,0x00};    //显示单元数据,共4个数据和一个运算暂用 

/*****************11us延时函数*************************/ 

void delay(uint t) 

{ for( ;t>0;t--);

void scan() 

{ int j ;

for(j=0;j<4;j++)

     {

          switch(j) 

            { 

                case 0: dm=table_dm[display[0]];w0=0;delay(50);w0=1;//小数 

             case 1: dm=table_dm1[display[1]];w1=0;delay(50);w1=1;//各位

            case 2: dm=table_dm[display[2]];w2=0;delay(50);w2=1;//十位

         case 3: dm=table_dm[display[3]];w3=0;delay(50);w3=1;//百位 

} //***************DS18B20复位函数************************/ 

ow_reset(void) 

char presence=1; 

while(presence) 

{  while(presence) 

  { 

DQ=1;_nop_();_nop_();//从高拉倒低 

DQ=0; 

delay(50);              //550us 

DQ=1; 

delay(6);               //66us 

presence=DQ;              //presence=0 复位成功,继续下一步 

    } 

    delay(45);               //延时500us 

    presence=~DQ; 

DQ=1;                          //拉高电平 

} /****************DS18B20写命令函数************************/ 

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

void write_byte(uchar val) 

   uchar i; 

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

   { 

    DQ=1;_nop_();_nop_();                           //从高拉倒低 

    DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_(); //5us 

    DQ=val&0x01;                                       //最低位移出 

    delay(6);                                       //66us 

    val=val/2;                                     //      1   右移 位 

    } 

    DQ=1; 

    delay(1); 

} /****************DS18B20读1字节函数************************/ 

//   从总线上取 个字节 

uchar read_byte(void) 

uchar i; 

uchar value=0; 

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

   DQ=1;_nop_();_nop_(); 

value>>=1;

   DQ=0;_nop_();_nop_();_nop_();_nop_();                 //4us 

   DQ=1;_nop_();_nop_();_nop_();_nop_();                 //4us 

   if(DQ)value|=0x80; 

   delay(6);                                               //66us 

DQ=1; 

return(value); 

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

read_temp() 

   ow_reset();                       //总线复位 

   delay(200); 

   write_byte(0xcc);                //发命令 

   write_byte(0x44);                //发转换命令 

   ow_reset(); 

   delay(1); 

   write_byte(0xcc);                //发命令 

   write_byte(0xbe); 

 temp_data[0]=read_byte();       // 读温度值的第字节 

   temp_data[1]=read_byte();       //读温度值的高字节 

   temp=temp_data[1]; 

temp<<=8;

   temp=temp|temp_data[0];          // 两字节合成一个整型变量。 

return temp;                       //返回温度值 

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

//二进制高字节的低半字节和低字节的高半字节组成一字节,这个 

//字节的二进制转换为十进制后就是温度值的百十个位值而剩,                                     , 

//下的低字节的低半字节转化成十进制后,就是温度值的小数部分 

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

work_temp(uint temp) 

uchar n=0; 

if(temp>63488) // 温度值正负判断 

      {temp=65536-temp;n=1;}                   // 负温度求补码,标志位置1 

        display[4]=temp&0x0f;                // 取小数部分的值 

   display[0]=ditab[display[4]]; // 存入小数部分显示值 

display[4]=temp>>4; // 取中间八位,即整数部分的值 

display[3]=display[4]/100;       // 取百位数据暂存 

   display[1]=display[4]%100;        // 取后两位数据暂存 

   display[2]=display[1]/10;        // 取十位数据暂存 

   display[1]=display[1]%10;        //个位数据 

   r=display[1]+display[2]*10+display[3]*100; /////符号位显示判断///// 

   if(!display[3]) 

   { 

     display[3]=0x0a;               //最高位为0时不显示 

     if(!display[2]) 

    display[2]=0x0a;           //次高位为0时不显示 

   } 

                    if(n){display[3]=0x0b;}        //负温度时最高位显示"-" } 

//*********设置温度显示转换************// 

void xianshi(int horl) 

{                          

       int n=0; 

if(horl>128)

       { 

              horl=256-horl;n=1; 

       } 

       display[3]=horl/100; 

       display[3]=display[3]&0x0f; 

       display[2]=horl%100/10; 

       display[1]=horl%10; 

       display[0]=0; 

       if(!display[3]) 

       { 

             display[3]=0x0a;                  //最高位为0时不显示 

             if(!display[2]) 

              { 

                  display[2]=0x0a;                //次高位为0时不显示 

              } 

       } 

          if(n) 

          { 

               display[3]=0x0b;//负温度时最高位显示"-" 

          } 

} //*********按键查询程序**************// 

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

void main() 

        dm=0x00;                            //初始化端口 

        w0=0; 

        w1=0; 

        w2=0; 

        w3=0; 

for(h=0;h<4;h++) //开机显示"0000" 

        { 

             display[h]=0; 

        } 

        ow_reset();                             //开机先转换一次 

        write_byte(0xcc);                     //SkipROM 

        write_byte(0x44);                      //发转换命令 

for(h=0;h<100;h++) //开机显示"0000" 

        { 

             scan();

        } 

        while(1) 

        { 

       if(temp1==0) 

             { 

                    work_temp(read_temp());             //处理温度数据 

                            scan();                             //显示温度值 

             } 

                } 

下载本文

显示全文
专题