在日常生活及工农业生产中,对温度的检测及控制时常显得极其重要。因此,对数显温度计的设计有着实际意义和广泛的应用。本文介绍一种利用单片机实现对温度智能控制及显示的方案。本毕业设计主要研究的是高精度的数字温度计的设计,继而实现对对象的测温。测温系统主要包括供电电源、数字温度传感器的数据采集电路、LED显示电路、蜂鸣器报警电路、按键电路、单片机主板电路,数字温度传感器的数据采集电路与单片机主板电路是整个系统的关键。高精度数字温度计的测温过程,由数字温度传感器采集所测对象的温度,并将温度传输到单片机,最终由液晶显示器显示温度值。该数显温度计要求测温范围为-55℃~+99℃,精度误差在0.1℃以内,LED数码管直读显示。数字式温度计完全可以代替传统的水银温度计,可以在家庭中以及工业中都可以应用,实用价值很高。
关键词:单片机;DS18B20;LED显示
1 引言温度是日常生活、工业、医学、环境保护、化工、石油等领域最常遇到的一个物理量。测量温度的基本方法是使用温度计直接读取温度。最常见到的测量温度的工具是各种各样的温度计,例如,水银玻璃温度计,酒精温度计或热电阻温度计等。它们常常以刻度的形式表示温度的高低,人们必须通过读取刻度值的多少来测量温度。利用单片机和温度传感器构成的电子式智能温度计就可以直接测量温度,得到温度的数字值,既简单方便,又直观准确。 在传统的温度测量系统设计中,往往采用模拟技术进行设计,这样就不可避免地遇到诸如引线误差补偿、多点测量中的切换误差和信号调理电路的误差等问题;而其中某一环节处理不当,就可能造成整个系统性能的下降。随着现代科学技术的飞速发展,特别是大规模集成电路设计技术的发展,微型化、集成化、数字化正成为传感器发展的一个重要方向。美国Dallas半导体公司推出的数字温度传感器DSl8B20,具有独特的单总线接口,仅需要占用一个通用I/O端口即可完成与微处理器的通信;用户可编程设定9~12位的分辨率。以上特性使得DSl8B20非常适用于构建高精度、多点温度测量系统。 本课题设计的高精度数字温度计选用DS18B20数字温度传感器,它与单片机组成一个测温系统,具有线路简单、体积小等特点,而且一条总线可连接多个器件,可以构成一个低电压低功耗的多点数字测温系统,十分方便,也适合于恶劣环境下进行现场温度测量,有广泛的应用前景。
2 概述2.1系统概述在日常生活及工农业生产中经常要用到温度的检测及控制,传统的测温元件有热电偶和热电阻。而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,需要比较多的外部硬度支持,硬件电路[1]复杂,软件调试复杂,制作成本高。 故本设计使用集成传感器DS18B20作为测温传感器。系统主要分为温度采集模块,数据传输模块,报警模块,LED显示模块和供电模块。系统设计原理图如图2-1所示。
图2--1 精密数字温度计的设计原理图 本数字温度计设计采用美国DALLS[2]半导体公司继DS18B20之后推出的一种改进型智能温度传感器DS18B20作为检测元件,测温范围为-55℃~+125℃,最大分辨率可达0.0625℃。DS18B20[3]可以直接读出被测温度值,而且采用3线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点。 数字温度系统有以下几个发展趋势: (1)数字测温系统的小型化,便于携带。测温仪器的应用场合已经走出实验室,需要便携式测温计。超大规模集成(VLSI)新器件、微机电系统(MEMS)、圆片规模集成(WSI)和多芯片模块(MCM)等,采用微控技术、微加工技术、微检测技术、微光源、微分光光学系统、微传感器等,使测温仪器产品体积缩小,精度提高成为可能。 (2)数字测温系统的精确化,使测温能力更加精确。数字技术的出现把模拟仪器的准确度、分辨力与测量速度提高了几个量级,单片机的引入,使仪器的功能发生了质的变化,从单纯的接受、显示转变为控制、分析、处理、计算与显示输出,从用单个仪器进行测量转变成用测量系统进行测量。测量仪器技术指标的提高是行业发展的追求,如测量范围,电阻从超导到1014Ω,温度从接近绝对零度到1010℃。如测量准确度,时间测量从30万年不差1秒提高到600万年不差1秒。 (3)数字测温系统的多用途化,不仅可以测室温,液温,甚至在极端条件下也能准确地测温。 2.2 本设计方案思路本设计以检测温度并显示温度提供上下限报警为目的,按照系统设计功能的要求,确定系统由5个模块组成:主控器[4]、测温电路,报警电路,按键电路及显示电路。 系统以DS18B20为传感器用以将温度模拟量转化为电压数字量以总线传入单片机,以ATmega16为主芯片,在主芯片对DS18B20传入的温度值进行处理,由单片机程序控制,将经处理后的温度由LED数码管显示出来。 本系统具有电路简洁,性能可靠等特点,易于实现。 2.3 研发方向和技术关键(1)合理使用温度传感器,提高系统的精度; (2)外加存储器,提供强大的存储功能; (3)与微机进行数据传输,方便数据的统计、保存、显示和查询。 2.4 主要技术指标(1)测温范围:-55℃~+99℃ (2)测量精度:0.1℃ (3)数字显示位数:四位 (4)最大测量温度:超过150℃
3 总体设计数字温度计是一种将模拟温度数据转化成数字温度数据并加以显示的系统。由传感器测得模拟温度数值,并将其转化为数字信号,通过串行通信的方法将数据传送给单片机,并由单片机处理后显示。 本设计采用ATmega16为控制部件,用4位共LED数码管动态扫描的方式来显示所测的温度值,温度值的最小精确度为0.1℃,基本上满足一般的要求。温度传感器采用DS18B20,其传感器为数字输出,所以不需要进行模数转化直接由单片机控制读取温度值,这样大大减少了硬件的成本。 此测温电路的系统框图如图3-1所示:
图3-1 数字温度计总体电路结构框图
3.1 温度的检测每次测温由单片机向测温传感器发出特定脉冲,测温传感器能够检测到脉冲并做相应的工作。传感器将模拟温度信号经过采集,数字处理,放大后输出。DS18B20使用一个单线接口发送或接受信息,因此在单片机和DS18B20之间只需要一条线链接,用于读写和温度转换的电源可以从数据线获得,无需外接电源。 3.2 数字信号的处理送入单片机内部的数字信号经过单片机的处理,将数据用LED数码管显示出来。其处理过程主要由单片机能存储的程序进行控制。 3.3 温度的显示 使用4位共阳极LED数码管显示。单片机将温度数据经处理后由I/O口输出,由特定的编码用数码管显示出来。LED显示具有显示速度快,显示结果明显,易于制作等优点。 3.4 按键检测 将按键的一段与单片机I/O口链接,一段与地链接,当按键按下时可以由单片机内的程序检测到。通过按键使用者可以控制程序,使用不同的功能,开关系统等。按键使用普通纽扣按键,具有结构简单,价格低廉,使用方便等优点。 3.5 报警功能在单片机程序内设置了报警温度的上下限值,当所测得的温度超过了这一数值,将会由蜂鸣器发出报警。报警功能是本系统的重要功能之一,在工业应用中常常需要在特定的温度条件下进行工作,所以当温度超出范围时及时报警是十分有必要的。
4 硬件设计4.1总体电路设计温度计电路设计原理图如图2所示,控制器使用单片机mega16,温度传感器使用DS18B20,用4位共阳LED数码管以动态扫描法实现温度显示。采用USB烧入程序及供电,用16M晶振。电路还包括按键电路,复位电路,报警电路,单片机外设电路等。整个系统的原理图如图4-1所示:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image007.jpg 图4-1 数字温度计设计电路原理图 4.2主控制器(ATmega16)ATmega16是基于增强的AVR RISC结构的低功耗8 位CMOS微控制器。由于其先进的指令集以及单时钟周期指令执行时间,ATmega16 的数据吞吐率高1MIPS/MHz,从而可以缓减系统在功耗和处理速度之间的矛盾。 AVR 内核具有丰富的指令集和32 个通用工作寄存器。所有的寄存器都直接与算逻单元(ALU) 相连接,使得一条指令可以在一个时钟周期内同时访问两个独立的寄存器。这种结构大大提高了代码效率,并且具有比普通的CISC 微控制器最高至10 倍的数据吞吐率。 ATmega16 有如下特点:16K字节的系统内可编程Flash(具有同时读写的能力,即RWW),512 字节EEPROM,1K 字节SRAM,32 个通用I/O 口线,32 个通用工作寄存器,用于边界扫描的JTAG 接口,支持片内调试与编程,三个具有比较模式的灵活的定时器/ 计数器(T/C),片内/外中断,可编程串行USART,有起始条件检测器的通用串行接口,8路10位具有可选差分输入级可编程增益(TQFP 封装) 的ADC ,具有片内振荡器的可编程看门狗定时器,一个SPI 串行端口,以及六个可以通过软件进行选择的省电模式。 工作于空闲模式时CPU 停止工作,而USART、两线接口、A/D 转换器、SRAM、T/C、SPI 端口以及中断系统继续工作;掉电模式时晶体振荡器停止振荡,所有功能除了中断和硬件复位之外都停止工作;在省电模式下,异步定时器继续运行,允许用户保持一个时间基准,而其余功能模块处于休眠状态; ADC 噪声抑制模式时终止CPU 和除了异步定时器与ADC 以外所有I/O 模块的工作,以降低ADC 转换时的开关噪声; Standby 模式下只有晶体或谐振振荡器运行,其余功能模块处于休眠状态,使得器件只消耗极少的电流,同时具有快速启动能力;扩展Standby 模式下则允许振荡器和异步定时器继续工作。 本芯片是以Atmel 高密度非易失性存储器技术生产的。片内ISP Flash 允许程序存储器通过ISP 串行接口,或者通用编程器进行编程,也可以通过运行于AVR 内核之中的引导程序进行编程。引导程序可以使用任意接口将应用程序下载到应用Flash存储区(ApplicationFlashMemory)。在更新应用Flash存储区时引导Flash区(Boot Flash Memory)的程序继续运行,实现了RWW 操作。 通过将8 位RISC CPU 与系统内可编程的Flash 集成在一个芯片内, ATmega16 成为一个功能强大的单片机,为许多嵌入式控制应用提供了灵活而低成本的解决方案。ATmega16 具有一整套的编程与系统开发工具,包括:C 语言 编译器、宏汇编、 程序调试器/ 软件仿真器、仿真器及评估板。
产品特性: • 高性能、低功耗的 8 位AVR® 微处理器 • 先进的RISC 结构 – 131 条指令 – 大多数指令执行时间为单个时钟周期 – 32个8 位通用工作寄存器 – 全静态工作 – 工作于16 MHz 时性能高达16 MIPS – 只需两个时钟周期的硬件乘法器 • 非易失性程序和数据存储器 – 16K 字节的系统内可编程Flash 擦写寿命: 10,000 次 – 具有独立锁定位的可选Boot 代码区 通过片上Boot 程序实现系统内编程 真正的同时读写操作 – 512 字节的EEPROM 擦写寿命: 100,000 次 – 1K字节的片内SRAM – 可以对锁定位进行编程以实现用户程序的加密 • JTAG 接口( 与IEEE 1149.1 标准兼容) – 符合JTAG 标准的边界扫描功能 – 支持扩展的片内调试功能 – 通过JTAG 接口实现对Flash、EEPROM、熔丝位和锁定位的编程 • 外设特点 – 两个具有独立预分频器和比较器功能的8 位定时器/ 计数器 – 一个具有预分频器、比较功能和捕捉功能的16 位定时器/ 计数器 – 具有独立振荡器的实时计数器RTC – 8路10 位ADC 8 个单端通道 TQFP 封装的7 个差分通道 2 个具有可编程增益(1x, 10x, 或200x)的差分通道 – 面向字节的两线接口 – 两个可编程的串行USART – 可工作于主机/ 从机模式的SPI 串行接口 – 具有独立片内振荡器的可编程看门狗定时器 ATmega16的引脚图如图4-2所示: file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg 图4-2Mega16引脚图
引脚说明: VCC数字电路的电源 GND地端口A(PA7..PA0)端口A 做为A/D 转换器的模拟输入端。 端口A 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口A 处于高阻状态。 端口B(PB7..PB0)端口B 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特 性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口B 处于高阻状态。端口B 也可以用做其他不同的特殊功能。 端口C(PC7..PC0)端口C 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口C 处于高阻状态。如果JTAG接口使能,即使复位出现引脚 PC5(TDI)、 PC3(TMS)与 PC2(TCK)的上拉电阻被激活。 端口D(PD7..PD0)端口D 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,则端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口D 处于高阻状态。端口D 也可以用做其他不同的特殊功能。 RESET复位输入引脚。持续时间超过最小门限时间的低电平将引起系统复位。持续时间小于门限间的脉冲不能保证可靠复位。 XTAL1反向振荡放大器与片内时钟操作电路的输入端。 XTAL2反向振荡放大器的输出端。 AVCCAVCC是端口A与A/D转换器的电源。不使用ADC时,该引脚应直接与VCC连接。使用ADC时应通过一个低通滤波器与VCC 连接。 AREFA/D 的模拟基准输入引脚。
AVR CPU 内核: 为了获得最高的性能以及并行性,AVR 采用了Harvard 结构,具有独立的数据和程序总线。程序存储器里的指令通过一级流水线运行。CPU 在执行一条指令的同时读取下一条指令( 在本文称为预取)。这个概念实现了指令的单时钟周期运行。程序存储器是可以在线编程的FLASH。快速访问寄存器文件包括32 个8 位通用工作寄存器,访问时间为一个时钟周期。从而实现了单时钟周期的ALU 操作。在典型的ALU 操作中,两个位于寄存器文件中的操作数同时被访问,然后执行运算,结果再被送回到寄存器文件。整个过程仅需一个时钟周期。寄存器文件里有6 个寄存器可以用作3 个16 位的间接寻址寄存器指针以寻址数据空间,实现高效的地址运算。其中一个指针还可以作为程序存储器查询表的地址指针。这些附加的功能寄存器即为16 位的X、Y、Z 寄存器。ALU支持寄存器之间以及寄存器和常数之间的算术和逻辑运算。ALU也可以执行单寄存器操作。运算完成之后状态寄存器的内容得到更新以反映操作结果。程序流程通过有/ 无条件的跳转指令和调用指令来控制,从而直接寻址整个地址空间。大多数指令长度为16 位,亦即每个程序存储器地址都包含一条16 位或32 位的指令。程序存储器空间分为两个区:引导程序区(Boot 区) 和应用程序区。这两个区都有专门的锁定位以实现读和读/ 写保护。用于写应用程序区的SPM 指令必须位于引导程序区。在中断和调用子程序时返回地址的程序计数器(PC) 保存于堆栈之中。堆栈位于通用数据SRAM,因此其深度仅受限于SRAM 的大小。在复位例程里用户首先要初始化堆栈指针SP。这个指针位于I/O 空间,可以进行读写访问。数据SRAM 可以通过5 种不同的寻址模式进行访问。AVR 存储器空间为线性的平面结构。AVR有一个灵活的中断模块。控制寄存器位于I/O空间。状态寄存器里有全局中断使能位。每个中断在中断向量表里都有独立的中断向量。各个中断的优先级与其在中断向量表的位置有关,中断向量地址越低,优先级越高。 4.3显示电路显示电路用8位共阳极数码管显示,多位数码管的各个位都可以显示数据,但以个时刻只能点亮一位,依次点亮多位数码管的各个位,由于人眼的视觉暂留效应,看起来就像多个位同时点亮。 数码管是一种把多个LED显示段集成在一起的显示设备。有两种类型,一种是共阳型,一种是共阴型。共阳型就是把多个LED显示段的阳极接在一起,又称为公共端。共阴型就是把多个LED显示段的阴极接在一起,即为公共端。阳极即为二极管的正极,又称为正极,阴极即为二极管的负极,又称为负极。通常的数码管又分为8段,即8个LED显示段,这是为工程应用方便如设计的,分别为A、B、C、D、E、F、G、DP,其中DP 是小数点位段。而多位数码管,除某一位的公共端会连接在一起,不同位的数码管的相同端也会连接在一起。即所有的A段都会连在一起,其它的段也是如此,这是实际最常用的用法。 数码管显示方法可分为静态显示和动态显示两种。静态显示就是数码管的8段输入及其公共端电平一直有效。动态显示的原理是,各个数码管的相同段连接在一起,共同占用8 位段引管线;每位数码管的阳极连在一起组成公共端。利用人眼的视觉暂留性,依次给出各个数码管公共端加有效信号,在此同时给出该数码管加有效的数据信号,当全段扫描速度大于视觉暂留速度时,显示就会清晰显示出来。 在此次设计中的数码管为共阳极的数码管,其对应的图如下: 当需要显示1时,可以将左图中的BC两段点亮,由于在应用中没有涉及到类似数字计算的小数点,所以DP端不接,而剩下七段代码从G到A依次为:0000110。 同理可以得出0~F常用的16进制的对应代码: 00111111 1 0000110 2 1011011 3 1001111 4 1100110 5 1101101 6 1111101 7 0000111 8 1111111 9 1101111 A1110111 B 1111100
C 0111001 D 1011110 E 1111001 F 1110001
显示电路如图4-3所示:
图4-3 多位数码管显示电路
4.4 温度传感器工作原理 DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。 DS18B20的性能特点如下: ·独特的单线接口仅需要一个端口引脚进行通信; ·实际应用中不需要外部任何元器件即可实现测温; ·可通过数据线供电,电压范围为3.0~5.5V; ·在DS18B20中的每个器件上都有独一无二的序列号; ·温度以9或12位数字量读出; ·报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件; ·负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能工作。
图4-4 DS18B20内部结构图
DS18B20采用3脚PR-35封装或8脚SOIC封装,其内部结构框图如图4-3所示。 64位ROM的位结构如图4所示。开始8位是产品类型的编号,接着是每个器件的惟一的序号,共有48位,最后8位是前56位的CRC检验码,这也是多个DS18B20可以采用一线进行通信的原因。非易失性温度报警触发器TH和TL,可通过软件写入户报警上下限。
MSB LSB MSB LSB MSB LSB 图4-5 64位ROM结构图 DS18B20温度传感器的内部存储器还包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。高速暂存RAM的结构为8字节的存储器,结构如图5所示。 头2个字节包含测量得的温度信息,第3和第4字节是TH和TL的拷贝,是易失的,每次上电复位时被刷新。第5个字节为配置寄存器[9],它的内容用于确定温度值的数字转换分辩率。 DS18B20工作时按此寄存器中的分辩率将温度转换为相应精度的数值。该字节各位的定义如图4-5所示。低5位一直为1,TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。 在DS18B20出厂时该位被设置为0,用户不要去改动,R1和R0决定温度转换的精度位数,即用来设置分辩率,定义方法见表1。
图4-6 高速暂存RAM结构图 图4-7 配置寄存器
表1 DS18B20分辩率的定义规定
由表1可见,DS18B20温度转换的时间比较长,而且设定的分辩率越高,所需要的温度数据转换时间就越长。因此,在实际应用中要将分辩率和转换时间权衡考虑。 高速暂存RAM的第6、7、8字节保留未用,表现为全逻辑1。转换完成后温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的第1、2字节。单片机可以通过单线接口读出该数据,读数据时低位在先,高位在后,数据格式以0.0625℃/LSB形式表示。温度值格式如图4-6所示。 当符号位S=0时,表示测得的温度值为正值,可以直接将二进制位转换为十进制;当符号位S=1时。表示测得的温度值为负值,要先将被补码变成原码,再计算十进制值。表2是一部分温度值对应的二进制温度数据。
23 | file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif | | | | | | |
LS字节
MS字节 图4-8温度数据值格式 DS18B20完成温度转换后,就把测得的温度值与RAM中的TH、TL字节内容作比较。若T>TH或T<TL,则将该器件内的报警标志位置位,并对主机发出的报警搜索命令作出响应。因此,可用多只DS18B20同时测量温度并进行报警搜索。 主机根据ROM的前56位来计算CRC值,并和存入DS18B20的CRC值作比较,以判断主机收到的ROM数据是否正确。 DS18B20的测量原理如图5.8所示。图中低温度系数晶振的振荡频率受温度的影响很小,用于产生固定频率的脉冲信号送给减法计数器1;高温度系数晶振随温度变化其振荡频率明显改变所产生的信号作为减法计数器2的脉冲输入。图中还隐含着计数门,当计数门打开时,DS18B20就对低温度系数振荡器产生的时钟脉冲进行计数, 表2 DS18B20温度与测得值对应表 进而完成温度测量。计数门的开启时间由高温度系数振荡器来决定,每次测量前,首先将-55℃所对应的一个基数分别置入减法计数器1、温度寄存器中,减法计数器1和温度寄存器被预置在-55℃所对应的一个基数值。 减法计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当减法计数器1的预置值减到0时,温度寄存器的值将加1,减法计数器1的预置值将重新被装入,减法计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到减法计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值就是所测温度值。图5.8中的斜率累加器用于补偿和修正测温过程中的非线形性,其输出用于修正减法计数器的预置值,只要计数门仍未关闭就重复上述过程,直到温度寄存器值达到被测温度值。 另外,由于DS18B20单线通信功能是分时完成的,它有严格的时隙概念,因此读写时序很重要。系统对DS18B20的各种操作必须按协议进行。操作协议为:初始化DS18B20(发复位脉冲)—>发ROM功能命令—>发存储器操作命令—>处理数据。 4.5DS18B20的其他介绍DS18B20的存储器包括高速暂存器RAM和可电擦除RAM,可电擦除RAM又包括温度触发器TH和TL,以及一个配置寄存器。存储器能完整的确定一线端口的通讯,数字开始用写寄存器的命令写进寄存器,接着也可以用读寄存器的命令来确认这些数字。当确认以后就可以用复制寄存器的命令来将这些数字转移到可电擦除RAM中。当修改过寄存器中的数时,这个过程能确保数字的完整性。 高速暂存器RAM是由8个字节的存储器组成;第一和第二个字节是温度的显示位。第三和第四个字节是复制TH和TL,同时第三和第四个字节的数字可以更新;第五个字节是复制配置寄存器,同时第五个字节的数字可以更新;六、七、八三个字节是计算机自身使用。用读寄存器的命令能读出第九个字节,这个字节是对前面的八个字节进行校验 DS18B20采用一线通信接口。因为一线通信接口,必须在先完成ROM设定,否则记忆和控制功能将无法使用。主要首先提供以下功能命令之一:读ROM,ROM匹配,搜索ROM,跳过ROM,报警检查。这些指令操作作用在没有一个器件的64位光刻ROM序列号,可以在挂在一线上多个器件选定某一个器件,同时,总线也可以知道总线上挂有有多少,什么样的设备。 DS18B20可以采用两种方式供电,一种是采用电源供电方式,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源。另一种是寄生电源供电方式。单片机端口接单线总线,为保证在有效的DS18B20时钟周期内提供足够的电流,可用一个MOSFET管来完成对总线的上拉。DS18B20可以使用外部电源VDD,也可以使用内部的寄生电源。当VDD端口接3.0V—5.5V的电压时是使用外部电源;当VDD端口接地时使用了内部的寄生电源。无论是内部寄生电源还是外部供电,I/O口线要接5KΩ左右的上拉电阻。 当DS18B20处于存储器操作和温度A/D转换操作时,总线上必须有强的上拉,上拉开启时间最大为10μs。采用寄生电源供电方式时VDD和GND端均接地。由于单线制只有一根线,因此发送接口必须是三态的。 由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89C2051单片机来说,硬件上并不支持单总线协议。因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。 由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。 DS18B20的复位时序 DS18B20的读时序分为读0时序和读1时序两个过程。 对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60μs才能完成。DS18B20的写时序 对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。 对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60μs,保证DS18B20能够在15μs到45μs之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15μs之内就得释放单总线。 4.6 按键电路的设计 按键电路将按键的一段与单片机I/O口链接,一段与地链接,当按键按下时可以由单片机内的程序检测到。按键采用普通的按钮按键。 4.7 蜂鸣器报警电路当所测温度超出上、下限温度极限值时,为实现报警功能,设计了蜂鸣器报警电路。由单片机ATmega16的PB3引脚连接BELL,协调DS18B20实现系统的报警功能。蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此需要一定的电流才能驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。如图所示,蜂鸣器的正极接到VCC(+5V)电源上面,蜂鸣器的负极接地,三极管的基级B经过限流电阻R1后由单片机的PB3引脚控制,当PB3输出高电平时,三极管截止,没有电流流过线圈,蜂鸣器不发声;当PB3输出低电平时,三极管导通,这样蜂鸣器的电流形成回路,发出声音。因此,我们可以通过程序控制PB3引脚的电平来使蜂鸣器发出声音和关闭。报警电路如图4-9所示。 蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器的分类 蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 压电式蜂鸣器 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。有的压电式蜂鸣器外壳上还装有发光二极管。 多谐振荡器由晶体管或集成电路构成。当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。 压电蜂鸣片由锆钛酸铅或铌镁酸铅压电陶瓷材料制成。在陶瓷片的两面镀上银电极,经极化和老化处理后,再与黄铜片或不锈钢片粘在一起。
图4-9 报警电路
4.8 供电电路在高精度数字温度计的设计中,单片机ATmega16的工作电压为4.5- 5.5V,数字温度传感器TMP101的电源电压范围为2.7V ~5.5V。所以整个测温系统的供电电源由USB接口提供5V电压,不仅符合要求,而且节省了资源,没必要再另外设计电源,只需要在下载程序时连接计算机就可提供所需电压,很方便。 5 系统软件设计系统程序主要包括主程序、读出温度子程序、温度转换命令子程序、计算温度子程序、显示数据刷新子程序等等。系统程序采用单片机C语言编写。程序简洁,可靠性高,可维护性好。
5.1读出温度子程序读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,检验有错时不进行温度数据的改写。其程序流程图如图5-1所示。
图5-1 读出温度子程序流程图
5.2 温度转换命令子程序温度转换命令子程序主要是发温度转换开始命令,当采用12位分辨率时转换时间约为750ms,在本程序设计中采用1s显示程序延时法等待转换的完成。
5.3计算温度子程序计算温度子程序将RAM[11]取值进行BCD码的转换运算,并进行温度值正负的判定,其程序流程图如图5-2所示。
图5-2 计算温度子程序流程图
5.4显示数据刷新子程序显示数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操作,当最高显示位为0时将符号显示位移入一下位,其程序流程图如图5-3所示。
图5-3 显示数据刷新子程序 5.5 DS18B20的各个ROM命令Read ROM [33H] 这个命令允许总线控制器读到DS18B20的8位系列编码、惟一的序列号和8位CRC码。只有在总线上存在单只DS18B20的时候才能使用这个命令。如果总线上有不止一个从机,当所有从机试图同时传送信号时就会发生数据冲突(漏极开路连在一起形成相“与”的效果)。 Math ROM [55H] 这个是匹配ROM命令,后跟64位ROM序列,让总线控制器在多点总线上定位一只特定的DS18B20。只有和64位ROM序列完全匹配的DS18B20才能响应随后的存储器操作。所有和64位ROM不匹配的从机都将等待复位脉冲。这条命令在总线有单个或多个器件时都可以使用。 Skip ROM [OCCH] 这条命令允许总线控制器不用提供64位ROM编码就使用存储器操作命令,在单点总线情况下,可以节省时间。如果总线上不止一个从机,在Skip ROM命令之后 跟着发一条读命令,由于多个从机同时传送信号。总线上就会发生数据冲突(漏极开路下拉效果相“与”)。 Search ROM [0F0H] 当一个系统初次启动时,总线控制器可能并不知道单线总线上有多少器件或它们的64位ROM编码。搜索ROM命令允许总线控制器用排除法识别总线上的所有从机的64位编码。 Alarm Search [0ECH] 这条命令的流程和SearchROM相同。然而,只有在最近一次测量后遇到符合报警条件的情况,DS18B20才会响应这条命令。报警条件定义为温度高于TH或低于TL。只要DS18B20不掉电,报警状态将一直保持,直到再一次测得的温度值达不到报警条件。 Write Scratchpad [4EH] 这个命令向DS18B20的暂存器TH和TL中写入数据。可以在任何时刻发出复位命令来中止写入。 Read Scratchpad [0BEH] 这个命令读到暂存器的内容。读取从第1个字节开始,一直进行下去,直到第9(CRC)字节读完。如果不想读完所有字节,控制器可以在任何时间发出复位命令来路中止读取。 Copy Scratchpad[48H] 这个命令暂存器的内容拷贝到DS18B20的EEROM存储器里,即把温度报警触发字节存入非易失性存储器里。如果总线控制器在这条命令之后跟着发出读时间隙,而DS18B20又忙于把暂存器拷贝到EEROM存储器,DS18B20就会输出一个0,如果拷贝结束的话,DS18B20则输出1。如果使用寄生电源,总线控制器必须在这条命令发出后立即启动强上拉并最少保持10ms。 Convert T [44H] 这条命令启动一次温度转换而无需其它数据。温度转换命令执行,而后DS18B20保持等待状态。如果总线控制器在这条命令之后跟着发出时间隙,而DS18B20又忙于做时间转换的话,DS18B20将总线上输出0,若温度转换完成,则输出1。如果使用寄生电源,总线控制器必须在发出这条命令后立即启动强上拉,并保持500ms以上时间。 RecallEE[0B8H] 这条命令把报警触发器里的值拷贝回暂存器,这种拷贝操作在DS18B20上电时自动执行,这样器件一上电暂存器里马上就存在有效的数据了。若在这条命令发出之后发出读数据隙,器件会输出温度转换忙的标识:0为忙,1为完成。 Read PowerSupply [0B4H] 若把这条命令发给DS18B20后发出读时间隙,器件会返回它的电源模式:0为寄生电源,1为外部电源。
5.6温度数据的计算方法从DS18B20读到出的二进制值必须先转换成二进制值,才能用于字符的显示。因为DS18B20的转换精度为9~12位可选的。为了提高精度采用12位。在采用12位转换精度时,温度寄存器里的值是以0.0625为步进的,即温度值为温度寄存器里的二进制值乘以0.0625,就是实际的十进制温度值。通过观察表5.2可以发现一个十进制值和二进制值之间有很明显的关系,就是把二进制的高字节的低半字节和低字节的高半字节组成一个字节,这个字节的二进制值化为十进制值后,就是温度值的百、十、个位值,而剩下的低字节的低半字节化成十进制后,就是温度值的小数部分。小数部分因为是半个字节,所以二进制值范围是0~F,转换成十进制小数值就是0.0625的倍数(0~15)。这样需要4位的数码管来显示小数部分,实际应用不必这么精度,采用1位数码管来显示小数,可以精确到0.1℃。下表3就是二进制和十进制的近似对应关系表。 表3小数部分二进制和十进制的近似对应关系表
5.7 DS18B20的时序图DS18B20的初始化: (1) 先将数据线置高电平“1”。 (2) 延时(该时间要求的不是很严格,但是尽可能的短一点) (3) 数据线拉到低电平“0”。 (4) 延时750微秒(该时间的时间范围可以从480到960微秒)。 (5) 数据线拉到高电平“1”。 (6) 延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。 (7) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。 (8) 将数据线再次拉高到高电平“1”后结束。图5-4为DS18B20的初始化操作时序。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image025.jpg
图5-4 DS18B20的初始化操作时序
DS18B20的写操作: (1) 数据线先置低电平“0”。 (2) 延时确定的时间为15微秒。 (3) 按从低位到高位的顺序发送字节(一次只发送一位)。 (4) 延时时间为45微秒。 (5) 将数据线拉到高电平。 (6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。 (7) 最后将数据线拉高。
DS18B20的读操作: (1)将数据线拉高“1”。 (2)延时2微秒。 (3)将数据线拉低“0”。 (4)延时15微秒。 (5)将数据线拉高“1”。 (6)延时15微秒。 (7)读数据线的状态得到1个状态位,并进行数据处理。 (8)延时30微秒。
图5-5为DS18B20的1-Wire操作时序。
图5-5 DS18B20的1-Wire操作时序
5.8整体程序主程序的功能是判读按键号数,判断当前模式,根据不同模式做不同的工作。如负责温度的实时显示、读出并处理DS18B20的测量温度值,报警上下限的调整,将采集到得温度存入MEGA16的E2PROM中等。打开程序首先进行初始化,初始化包括变量初始化和端口初始化。初始化结束后将调用显示函数显示初始值。当有按键按下时程序会对按下的按键进行判断,返回按下按键的号码。当按下的按键为1号按键时,程序进行模式切换,模式加1。当按下的按键为2号按键时,模式0下为读温度。模式1下为读出存储温度。模式2下为报警功能开关。模式3下为温度上下限的切换。当按下的按键为3号键时:模式0为存储温度。模式1和2为空按键,模式3为上下限加1。当按下的按键为4号键时,模式0,1,2都为空按键,模式3为上下限减1。 程序使用单片机C语言编写,对于ATmega16的程序设计,由于所需实现的功能较复杂,采用C语言的形式。编程软件将使用IAR AVR软件。该软件是ATmega系列单片机程序设计的常用工具,既可用汇编,也支持C语言编译。同时具有完善的调试功能。 6 系统调试与运行6.1电路板的制作在Protel DXP[12]的环境下,根据原理图创建网络表,再导入网络表的设计规则,自动生成PCB板布线图。然后将布线图打印到转印纸上,通过转印机将转印纸上的图转印到覆铜板上,经过三氯化铁的腐蚀,即可生成电路板。 6.2 电路板的焊接在焊接之前,以硬件电路原理图为参照物,先对电路板进行仔细的检查,防止断线、错线的产生;同时对所用的元器件进行测量,防止有损坏的元器件被使用。在焊接时,应分块焊接,及时测量,保证每个模块均能正常工作,提高电路板制作的成功率。 6.3 调试及性能分析系统的调试以程序为主。软件调试可以先编写显示程序并进行硬件的性检验,然后分别进行主程序、读出温度子程序、温度转换命令子程序、计算温度子程序、显示数据刷新等子程序的编程及调试,由于DS18B20与单片机采用串行数据传送,因此,对DS18B20进行读写编程时必须严格地保证读写时序,否则将无法读取测量结果。本程序采用单片机C语言编写,用EWAVR-KS4编译器编程调试。软件调试到能显示温度值,而且在有温度变化时显示温度能改变就基本完成。 性能测试可用制作的温度计和已有的成品温度计来同时测量比较,由于DS18B20的精度很高,所以误指标可限制在0.1℃以内,另外-55~+125℃的测量范围使得该温度计完全适合一般的应用场合,其低电压供电特性可做成用电池供电的手持电子温度计。 DS18B20温度计还可以在高低温报警、远距离多点测量控制等方面进行应用开发,但在实际设计中应注意以下问题: (1)DS18B20工作时电流高达1.5mA,总线上挂接点数较多且同时进行转换时,要考虑增加总线驱动,可用单片机端口在温度转换时导通一个MOSFET供电。 (2)连接DS18B20的总线电缆是有长度限制的,因此在用DS18B20进行长距离测温系统设计时,要充分考虑总线分布电容和阻抗匹配等问题。 (3)在DS18B20测温度程序设计中,向DS18B20发出温度转换命令后,程序总要等待DS18B20的返回信号,一旦某个DS18B20接触不好或断线,当程序读该DS18B20时,将没有返回信号,程序进入死循环,这一点在进行DS18B20硬件连接和软件设计时要给予一定的重视。 7结论本设计方案达到了任务书的要求,实现了高精度数字温度计的设计,实现了较为精确的测温功能: (1)对被测对象的测温结果精度可以达到0.1℃,突出了本设计的特点; (2)所测温度值的范围在-55℃~+99℃,符合指定工作温度范围; (3)由蜂鸣器报警电路控制的报警功能也调试实现,并在LED上正确显示了温度值; 本设计中的数字温度计直接测温的方式,该温度计的灵敏度高、反应时间短、抗干扰能力强,而且具有测量范围大、读数方便等优点。在接通电源时,数码管上显示的数字如果出现不清晰或者出现抖动,这是由于电源电压不稳定或是接触不良所引起的,可以使用接滤波电容的方法来解决上述现象。该系统所用的IC很少,所以成本较低,器件均为常用元件,有很高的工程应用价值。如稍加改动程序,可将本系统做成带有控制功能的温控系统。 由于时间紧迫以及本人知识水平和技术水平有限,设计当中还有许多不足之处,程序的编写也还不够简洁明了,希望在以后的学习中能学到更多的知识,提高自己的技术水平,使自己的设计更好,更优秀。 file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image031.jpg
8程序
#include<reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit DATA = P1^1; //DS18B20接入口 uchar codetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴极字型码 int temp; //温度值 int ss; //中间的一个变量 int dd; int j; uchar data b;//定时器中断次数 uchar data buf[4];//字型显示中间变量 int alarmH=320; //默认报警值 int alarmL=100; //定义开关的接入口 sbit k1=P2^5;//+ sbit k2=P2^6;//- sbit k3=P2^7;//确认 sbit k4=P2^4; //切换 sbit bell=P1^0; //蜂鸣器 sbit HLight=P1^2; //正温指示灯 sbit LLight=P1^3; //负温度指示灯 sbit warn=P1^4; //报警指示灯 sbit Red=P1^6; //温度上限设置指示灯 sbit Green=P1^7; //温度下限设置指示灯 bit set=0; //初始化 bit Flag=0; //设置标志 int n; //函数的声明区 void key_to1(); void key_to2(); void delay(uint); void key(); void Show(); //函数的定义区 /*延时子函数*/ void delay(uint num) { while(num--) ; }
//DS18b20温度传感器所需函数,分为初始化,读写字节,读取温度4个函数 Init_DS18B20(void) //传感器初始化 { uchar x=0; DATA = 1; //DQ复位 delay(10); //稍做延时 DATA = 0; //单片机将DQ拉低 delay(80); //精确延时 大于 480us //450 DATA = 1; //拉高总线 delay(20); x=DATA; //稍做延时后如果x=0则初始化成功 x=1则初始化失败 delay(30); } ReadOneChar(void) //读一个字节 { uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { DATA = 0; // 给脉冲信号 dat>>=1; DATA = 1; // 给脉冲信号 if(DATA) dat|=0x80; delay(8); } return(dat); } WriteOneChar(unsigned char dat) //写一个字节 { uchar i=0; for (i=8; i>0; i--) { DATA = 0; DATA = dat&0x01; delay(10); DATA = 1; dat>>=1; } delay(8); } int ReadTemperature(void) //读取温度 { uchar a=0; uchar b=0; int t=0; float tt=0; Init_DS18B20(); WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 a=ReadOneChar();//低位 b=ReadOneChar();//高位 t=b; t<<=8; t=t|a; tt=t*0.0625; t= tt*10+0.5; return(t); } void display00() //*********显示负值子函数 { dd=-(temp-1); buf[1]=dd/100; buf[2]=dd/100; buf[3]=dd%100/10; buf[0]=dd%10; //动态显示 for(j=0;j<5;j++) { P2=0xff; // 初始灯为灭的 P0=0x00; P2=0xfd; //显示小数点 P0=0x80; //显示小数点 delay(100); P2=0xff; // 初始灯为灭的 P0=0x00; P2=0xf7; //片选LCD1 P0=0x40; delay(100); P2=0xff; P0=0x00; P2=0xfb; //片选LCD2 P0=table[buf[2]]; delay(100); P2=0xff; P0=0x00; P2=0Xfd;//片选LCD3 P0=table[buf[3]]; delay(100); P2=0xff; P0=0x00; P2=0Xfe; P0=table[buf[0]]; //片选LCD4 delay(100); P2=0xff; } } //显示正值子函数 void display() { buf[1]=temp/1000;//显示百位 buf[2]=temp/100%10;//显示十位 buf[3]=temp%100/10;//显示个位 buf[0]=temp%10; //小数位 for(j=0;j<3;j++) { P2=0xff; // 初始灯为灭的 P0=0x00; P2=0xfd; //显示小数点 P0=0x80; //显示小数点 delay(300); P2=0xff; // 初始灯为灭的 P0=0x00; P2=0xf7; //片选LCD1 P0=table[buf[1]]; delay(300); P2=0xff; P0=0x00; P2=0xfb; //片选LCD2 P0=table[buf[2]]; delay(300); P2=0xff; P0=0x00; P2=0Xfd; //片选LCD3 P0=table[buf[3]]; delay(300); P2=0xff; P0=0x00; P2=0Xfe; P0=table[buf[0]]; //片选LCD4 delay(300); P2=0xff; } } void key() //按键扫描子程序 { if(k1!=1) { delay(20); if(k1!=1) { while(k1!=1) { key_to1(); for(n=0;n<8;n++) Show(); } } } if(k2!=1) { delay(20); if(k2!=1) { while(k2!=1) { key_to2(); for(n=0;n<8;n++) Show(); }
} } if(k3!=1) { TR0=1; //复位,开定时 temp=ReadTemperature(); } if(k4!=1) { delay(20); if(k4!=1) { while(k4!=1); set=!set; if(set==0) { Red=0;Green=1;} else { Green=0;Red=1;} } } } void key_to1() { TR0=0; //关定时器 temp+=10; if(temp>=1100) {temp=-550;} if(set==0) {alarmH=temp;} else {alarmL=temp;} } void key_to2() { TR0=0; //关定时器 temp-=10; if(temp<=-550) {temp=1100;} if(set==0) { alarmH=temp;} else { alarmL=temp;} }
void alarm(void) { if(temp>alarmH||temp<alarmL) { //bell=1; //delay(50); //bell=0; Flag=1; }else {Flag=0;} }
logo()//开机的Logo { P0=0x40;
P2=0xf7; delay(50); P2=0xfb; delay(50); P2=0Xfd; delay(50); P2=0Xfe; delay(50); P1 = 0xff; //关闭显示 }
void Show() //显示函数,分别表示温度正负值 { if(temp>=0) {HLight=1;LLight=0;display();} if(temp<0) {HLight=0;LLight=1;display00();} } void main() { TCON=0x01; //定时器T0工作在01模式下 TMOD=0X01; TH0=0XD8;//装入初值 TL0=0XF0; EA=1; //开总中断 ET0=1; //开T0中断 TR0=1; //T0开始运行计数 EX0=1; //开外部中断0
for(n=0;n<500;n++)//显示启动LOGo"- - - -" {bell=1;warn=1;logo();} Red=0; while(1) { key(); ss=ReadTemperature(); Show(); alarm(); //报警函数 if(Flag==1) {bell=!bell; warn=!warn;} //蜂鸣器滴滴响 else {bell=1; warn=1;} } } voidtime0(void) interrupt 1 using 1 //每隔10ms执行一次此子程序 { TH0=0X56; TL0=0XDC; temp=ss; }
|