为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

基于单片机的双路温控装置论文

2020-03-09 1页 doc 277KB 2阅读

用户头像

is_842972

暂无简介

举报
基于单片机的双路温控装置论文1  绪论 本文系统地介绍了基于DS18B20的双路温度测控系统的组成、设计方案、电路原理、程序设计以及系统仿真过程。DS18B20双路温度控制系统是以AT89C52单片机作为控制核心,智能温度传感器DS18B20,时钟芯片DS1302和存储器24C32为控制对象,用LM032L液晶显示,运用C语言实现系统的各种功能。设计完成了读DS18B20的ROM序列号电路和双路温度选择检测及分屏显示电路。借助仿真工具Proteus和单片机编程软件Keil实现了系统软、硬件的交互仿真,并结合液晶显示器LM032L、DS18B20、DS1...
基于单片机的双路温控装置论文
1  绪论 本文系统地介绍了基于DS18B20的双路温度测控系统的组成、设计、电路原理、程序设计以及系统仿真过程。DS18B20双路温度控制系统是以AT89C52单片机作为控制核心,智能温度传感器DS18B20,时钟芯片DS1302和存储器24C32为控制对象,用LM032L液晶显示,运用C语言实现系统的各种功能。设计完成了读DS18B20的ROM序列号电路和双路温度选择检测及分屏显示电路。借助仿真工具Proteus和单片机编程软件Keil实现了系统软、硬件的交互仿真,并结合液晶显示器LM032L、DS18B20、DS1302、24C32等进行了调试,实现了课题设计目的。 单片机系统通过配置显示模块,可以实时显示双路温度和时间日期,通过键盘调出存储在24C32A的时间及与其对应的当时的温度信息,该设计可为温度用户提供实时可靠的采集及控制系统,实现温度和通风的控制,并有高温报警功能。 1.1  课题背景及意义 近年来,温度测控领域发展迅速,并随着数字技术的发展,温度的测控芯片也相应的登上了历史的舞台,能够在工业、农业等各个领域中得到广泛使用。在人类的生活环境中,温度扮演了极其重要的角色。无论你生活在哪里,无论从事什么工作,无时无刻不在与温度打着交道。现代社会随着电子技术的发展,特别是随着大规模集成电路的出现,给我们的生活带来了根本性的变化,如果说微型计算机的出现使现代的科学研究得到了质的飞跃,那么可编程控制器的出现则给现代工业监测控制领域带来了一次新的技术革命。在现代社会中,温度控制不仅仅应用在工厂生产方面,其作用也体现到了各个方方面面。本课题主要涉及传感器技术、单片机系统以及LCD这三方面的应用,下面就这三方面的概念、发展和应用分别进行介绍[1]。 21世纪科学技术的发展日新月异,科技的不断进步带动了测量技术的发展,现代控制设备的性能和结构也发生了巨大的变化,我们已经进入了飞速发展的信息时代,测控技术也成为当今科技的主流之一,被广泛地应用于生产、生活的各个领域。对于本次设计,其目的在于: (1)本课题综合了现代测控、电子信息、计算机技术专业领域方方面面的知识,具有综合性、科学性、代表性,可全面检验和促进学生的理论素养和工作能力。 (2)本课题的研究可以使学生更好地掌握基于单片机应用系统的与设计,培养创新意识、协作精神和理论联系实际的学风,提高电子产品研发素质、增强针对实际应用进行控制系统设计制作的能力。 (3)掌握一个显示屏和一个温度传感器的原理、性能、使用特点和方法,利用单片机对系统进行编程。 1.2  温度传感器国内外现状及水平 传感器属于信息技术前沿的尖端产品,尤其是温度传感器被广泛用于工业生产究和生活领域,数量高居各种传感器之首。温度传感器的发展大致经历了一下三个阶段:传统的分离式温度传感器(含敏感元件)、模拟集成温度传感器/控制器和数字温度传感器。目前,国际上新型温度传感器正由模拟式向数字式、由集成化向智能化、网络化的方向发展,同时具有抑制串模干扰能力强、分辨力高、线性度好、成本低等优点。 数字式温度传感器就是能把温度物理量,通过温度敏感元件和相应电路转换成方便计算机、PLC、智能仪表等数据采集设备直接读取得数字量的传感器。数字式温度传感器的接口形式有RS232数据格式接口;RS485数据格式接口、一总线数据格式接口、CAN总线数据格式接口、ZIGBEE数据格式接口、TCP/IP数据格式接口等。在信息化数字化程度越来越高的今天,担当信息处理与交换重任的机房是整个信息网络工程的数据传输中心、数据处理中心和数据交换中心[2]。为保证机房设备正常运行及工作人员有一个良好的工作环境,对机房温度的监测是必不可少的,合理正常的温度环境是机房设备正常运行的重要保障。温度监测除用于机房监测外,还可以广泛应用于其他方面,如生物制药、无菌室、洁净厂房、电信银行、图书馆、档案馆、文物馆、智能楼宇等各行各业需要温度监测的场所和领域。伴随着我国经济的高速发展,国内在科技和生产各领域都取得了飞速的发展和进步,发展以温度传感器为载体的温度测量技术具有重大意义[3]。 1.3  课题设计任务 (1)本设计要求系统测量双路的温度同时显示时间及日期,测量精度1℃测量范围为-55℃~100℃。采用液晶显示温度值,显示格式为:第一行显示两个温度的整数部分,温度符号显示;第二行显示时间数据,数据不断刷新。 (2)本设计温度控制作用:当温度超过上限时系统自动通风,当温度超过下限时加热装置加热,当温度超过报警温度时蜂鸣器自动响,设计中用绿灯亮表示通风,用红灯亮表示正在加热。 (3)本设计要求系统仿真,程序调试使用的是Keil软件,仿真用的是ISIS仿真软件。 本设计的难点主要是软件方面,其中软件开发的难点在于DS18B20的序列号读出和液晶温度符号的显示以及温度的精度显示如何实现,如果DS18B20的序列号读出不正确,将无法正确的匹配和读出的温度值;温度符号的显示需要对LM032L的CGROM进行读写。温度显示的精度的实现需要编程人员对程序熟悉。 要完成这个课题要做以下几点工作: (1)熟悉单片机系统包括外围电路,单片机的引脚定义及作用,知道各引脚的使用方法。熟悉各个硬件的原理及功能,并知道怎么和单片机连接,比如DS18B20、24C32和DS1302。 (2)由于设计要求仿真,必须学会软件编程和仿真调试,熟练使用Keil软件,Keil软件是目前最流行开发MCS-51系列单片机的软件。并且必须在Proteus中完成仿真,完成电路图的连接,加载程序最后仿真出结果。 单片机选用市场上常见的美国ATMEL公司的AT89C52作为控制元件,温度传感器选用DS18B20数字温度传感器,它的输入/输山采用数字量,以单总线技术,接收单片机发送的命令,根据DSl8B20内部的进行相应的处理,将转换的温度以串口发送给单片机。主机按照通信协议用一个I/O口模拟DS18B20的时序,发送命令(初始化命令、ROM命令、RAM命令)给DS18B20,转换完成之后读取温度值,在内部进行相应的数值处理,用液晶显示屏LM032L显示各点的温度,液晶显示双路的实时温度值和时间日期显示,从而实现了对双路温度的实时监控。 考虑到DS18B20温度传感器已广泛地应用在单片机电路设计中,可以很容易直接读取被测温度值,电路简单,精度高,软硬件都易实现,而且使用单片机的接口便于系统的再扩展,满足设计要求。 2  总体方案论证 本章从系统方案等一些方面来进行论证。使用单片机作为控制核心,采用两个温度传感器对双路温度进行检测,以液晶显示屏显示检测温度,通过4×4矩阵键盘模块选择时间对与其对应的温度进行显示。设计完成了双路温度测量及显示,时间的显示,以及自动温度控制和报警,并存储温度信息。总体方案如图2.1所示。 图2.1  总体方案 2.1  设计方案论证 温度监控系统可以根据采用的温度传感器的不同进行如下分类。 (1)热敏电阻 以温度变化导致阻值的变化为工作原理的热敏电阻,因其具有成本低、体积小、简单、可靠、响应速度快、容易使用等特点。热敏电阻的电阻温度系数较高,室温通常也较高,因此其自身发热较小,信号调节较为简单。但热敏电阻也存在缺点,如互换性差、温度与输出阻值之间呈非线性关系。 (2)数字式温度传感器 数字式温度传感器的种类也不少,但用于测控系统的温度传感器主要是Dallas的DS18X20系列温度传感器,其温度检测范围为-55℃~﹢125℃,检测精度为±0.5℃。DS18X20采用1-WireTM接口,封装形式有PR-35和SSOP-16两种,测控系统中采用的是PR-35封装。DS18X20采用9个位表示测温点的温度值,每个DS18X20内部都设置有一个单一的序列号,因此可以使多个DS18X20共存于同一根数据传输线上。DS18X20内部分为4个部分:64位序列号;保存临时数据的8字节片内RAM;保存永久数据的2字节EEPROM;温度传感器[4]。 采用数字式温度传感器的测控系统的结构与采用热敏电阻的测控系统的结构大致相同,只是用测控单元替代了智能分机、扩充接线器替代了温度分线器。测控单元与智能分机的区别在于没有使用将温度信号数字化的A/D转换电路,取而代之的是1-WireTM总线与上层通信总线之间的通信转换电路,如果系统选用了数字式温度传感器则测控单元将完全由数字电路组成,而智能分机是由数字电路和模拟电路两部分构成的,这将使测控单元电路的设计更为容易。 采用DS18X20温度传感器的测控系统的测温电缆与热敏电阻测温电缆大不相同,该测温电缆最多只需3根导线即可连接多个DS18X20温度传感器。最为简洁的结构是利用DS18X20可以通过数据线供电的特点,在测温电缆中只放置两根平行的细钢丝绳即可连接多个DS18X20温度传感器,这样不仅使测温电缆的制造简便、制造成本下降,而且提高了测温电缆的抗拉强度、便于温度传感器的更换。正是这些特点使得采用DS18X20温度传感器的测控系统更适用于复杂的多点测温的应用环境,可以解决在不需重新安装测温电缆的情况下更换测温电缆内部的温度传感器以及改变温度传感器相对位置。由于这种温度传感器的性价比高出热敏电阻许多,所以DS18X20温度传感器测控系统在应用时比热敏电阻测控系统更具有性能价格比的优势[5]。 (3)光纤传感器 光纤温度传感器是近几年发展的新技术,也是工业中用的最多的光纤传感器之一。目前研究的光纤温度传感器主要有辐射式温度传感器、半导体吸收式温度传感器、光纤热色传感器等。光纤温度传感器的精度更高,但成本太贵。 2.2  方案设计 方案一:该方案由单片机、模拟温度传感器AD590、运算放大器、A/D转换器、LCD显示电路、集成功率放大器、报警器组成。 该方案采用模拟温度传感器AD590作为测温元件,传感器测量的温度变化转换成电流的变化,再通过电路转换成电压的变化,使用运算放大器交给信号进行适当的放大,最后通过模数转换器将模拟信号转换成数据信号,传给单片机,单片机将温度值进行处理之后用LCD显示,当温度值超过设定值时开始报警。 方案二:该方案使用了AT89C52单片机作为控制核心,以智能温度传感器DS18B20为温度测量元件,采用2个温度传感器对双路温度进行检测,通过键盘模块对所需要调出的时间进行设置,并通过设定报警温度,超过其温度值就报警。显示电路采用LM032L模块,使用单片机直接驱动蜂鸣器构成报警电路。 方案一采用模拟温度传感器,转换结果需要经过运算放大器传给处理器。它控制虽然简单,但电路复杂,不容易实现对多点温度测量和监控。由于采用了多个分立元件和模数转换器,容易出现误差,测量结果不是很准确,因此本方案并不可取。 方案二采用智能温度传感器DS18B20,它直接输入数字量,精度高,电路简单,只需要模拟DS18B20的读写时序,根据DS18B20的协议读取转换的温度。此方案虽然程序设计复杂一些,但硬件电路简单,并且在课题外对DS18B20,字符型液晶显示有所了解,曾经在网上看过此类程序设计,而且我们已经使用开发工具Keil用C语言对系统进行了程序设计,用仿真软件Proteus对系统进行了仿真,达到了预期的效果。由此可见,此方案的可行性,体现了技术的先进性,经济上也没有任何问题。 另外,因为DS18B20单线通信功能是分时完成的,它有非常严格的时隙概念,因此读写时序就很重要了。系统对DS18B20的各种操作必须按照协议进行。操作协议为:首先开始初始化DS18B20(发复位脉冲),接着发ROM功能指令,再发存储器操作指令,最后处理数据。各种操作的时序图与DS18B20相同。 根据DS18B20的电气特性,我们可以采取以下方法使用DS18B20进行双路测温。 单端口单总线的双路测温法:所有的DS18B20相互并联后其数据线连接到微处理器的某个I/O端口线上,其显著的特点是只占用微处理器的一个端口。因为每个DS18B20内部均有且只有一个唯一的64位序列号,在系统安装工作之前先将主机与DS18B20逐个挂接,分别读出其序列号并存储在主机的EEPORM中,微处理器根据序列号就可以对同一条总线上的2支DS18B20进行识别与控制,分别读取它们的温度。DS18B20与单片机的连接如图2.2所示。 图2.2  DS18B20与单片机的连接 单片机选用市场上常见的美国ATMEL公司的AT89C52作为控制元件,温度传感器选用DS18B20数字温度传感器,它的输入/输山采用数字量,以单总线技术,接收单片机发送的命令,根据DS18B20内部的协议进行相应的处理,将转换的温度以串口发送给单片机。主机按照通信协议用一个I/O口模拟DS18B20的时序,发送命令包括初始化命令、ROM命令、RAM命令给DS18B20,转换完成之后读取温度值,在内部进行相应的数值处理,用液晶显示屏LM032L显示双路的温度,液晶显示完双路测量温度,时间,以及自动温度控制和报警,并存储温度信息。 考虑到DS18B20温度传感器已广泛地应用于单片机系统设计中,可以很简单直接读取被测温度值,电路相对简单,精度高,软硬件都容易实现,而且使用单片机的接口便于系统的再扩展,满足了设计要求。 由以上两种方案,很容易就可以看出,采用方案二,电路比较简单,费用较低,可靠性高,软件的设计也比较简单。 DS18B20的测温原理:低温度系数晶振的振荡频率受温度的影响很小,用于产生固定频率的脉冲信号送给减法计数器1,高温度系数晶振随温度变化其震荡频率明显改变,所产生的信号作为减法计数器2的脉冲输入,其中还隐含着计数门,当计数门打开时,DS18B20就对低温度系数振荡器产生的时钟脉冲后进行计数,进而完成温度测量。计数门的开启时间由高温度系数振荡器来决定,每次测量前,首先将-55℃所对应的基数分别置入减法计数器1和温度寄存器中,减法计数器1和温度寄存器被预置在-55℃所对应的一个基数值。减法计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当减法计数器1的预置值减到0时温度寄存器的值将加1,减法计数器1的预置将重新被装入,减法计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到减法计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。其中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正减法计数器的预置值,只要计数门仍未关闭就重复上述过程,直至温度寄存器值达到被测温度值,这就是DS18B20的测温原理[6]。 3  硬件电路设计 硬件电路分为三部分:信号采集电路,控制电路和显示电路。 3.1  单片机系统简介 3.1.1  单片机系统设计 AT89C52是一种带8K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory),其低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器的制造技术制造,与工业标准MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C52是一种高效的微控制器,为很多嵌入式控制系统提供了一种灵活性高并且价廉的方案[7]。 AT89C52管脚说明如下: VCC:供电电压。 GND:接地。 P0口:P0口作为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,定义为高阻输入。P0能用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写1时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址1时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。 P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入1后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。 P3口也可作为AT89C52的一些特殊功能口如下所示: P3.0口管脚的备选功能:RXD(串行输入口); P3.1口管脚的备选功能:TXD(串行输出口); P3.2口管脚的备选功能:INT0(外部中断0); P3.3口管脚的备选功能:INT1(外部中断1); P3.4口管脚的备选功能:T0(记时器0外部输入); P3.5口管脚的备选功能:T1(记时器1外部输入); P3.6口管脚的备选功能:WR(外部数据存储器写选通); P3.7口管脚的备选功能:RD(外部数据存储器读选通)。 P3口同时为闪烁编程和编程校验接收一些控制信号。 3.2  DS18B20温度传感器和单片机接口技术 3.2.1  DSl8B20简介及原理 DS18B20简介:DS18B20温度传感器是美国DALLAS半导体公司继DS18B20之后最新推出的只用改进型智能温度传感器。DS18B20采用3脚PR35封装或8SOIC 封装,其内部结构框图如3.1所示。 图3.1  DS18B20的内部结构图 与传统的热敏电阻相比,它能够直接读出被测温度并且可根据要求通过简单的编程实现9位~12位的数字直读方式。可以分别存93.75ms和750ms内完成9位和12位的数字量,并且从DS18B20读出的信息或写入DS18B20的信息仅需要一根口线(单线接口)读写,温度变换功率来源于DS18B20数据总线,总线本身也可以向所挂接DS18B20供电,而无需额外电源。因而使用可使系统结构趋简单,可靠性高。它在测温精度,转换时时间,传输距离,分辨率几方面较DS1820有了很大的改进,给用户带来了更加方便的使用和更令人满意的效果。 DS18B20其内部结构主要有4部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20的管脚排列如图3.2所示。 图3.2  DS18B20的管脚 DS18B20的引脚说明如下: GND :地。      DQ :数据I/O。    VDD :电源。      NC :空脚。 Proteus中的DS18B20如图3.3所示。 图3.3  Proteus中的DS18B20 64位激光ROM开始8位是产品类型的编号,接着是每个器件的惟一的序号共有48位,最后8位是前56位的CRC校验码,这也是多个DS18B20可以采用一线进行通信的原因。64位激光ROM的结构组成如下所示:8位CRC编号;48位序列号;8位产品系列编码。 当DS18B20在接收到温度转换命令后,开始启动转换。转换完成后的值就以16位带符号扩展到二进制补码形式储存在高速暂存存储器的第l,2字节。单片机通过单线接口读到该数据,读取时低位在前面,高位在后,数据的格式以0.0625℃/LSB形式表示。对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变换为原码,再计算十进制值。部分温度转换如表3.1所示。 表3.1  部分温度转换值 温度 输入(2进制) 输出(16进制) +125℃ 0000 0111 1101 0000 07D0H +85℃ 0000 0101 0101 0000 0550H +25.0625℃ 0000 0001 1001 0001 0191H +10.125℃ 0000 0000 1010 0010 00A2H +0.5℃ 0000 0000 0000 1000 0008H 0℃ 0000 0000 0000 0000 0000H -0.5℃ 1111 1111 1111 1000 FFF8H -10.125℃ 1111 1111 0101 1110 FF5EH -25.0625℃ 1111 1111 0101 1110 EE6FH -55℃ 1110 1110 0110 1111 FE90H       在DS18B20完成温度变换之后,温度值与贮存TH和TL内的触发值相比较因为这些寄存器仅仅是8位,所以0.5℃位在比较时被忽略。TH或TL的最高有较位直接对应于16位温度奇存器的符号位。如果温度测量的结果高于TH或者低于TL,那么器件内报警标志将置位。每次温度测量更新此标志。只要报警标志置位,DS18B20将对报警搜索命令做出响应。这允许并联连接许多DS18B20,同时进行温度测量。如果某处温度超过极限,那么可以识别出正在报警的器件并立即将其读出而不必读出非报警的器件[8]。 3.2.2  DS18B20与单片机接口电路 如图3.4所示,为单片机与DS18B20的接口电路。DS18B20只有三个引脚,一个接地,一个接电源,一个数字输入输出引脚接单片机的P2.6口。 图3.4  DS18B20与单片机接口电路  DS18B20虽然具有测温系统简单,测温精度高、连接方便、占用I/O 口线少等优点,但实际应用中也应注意以下2个问题: (1)在实际使用中发现,应使电源电压保持在5V左右,如果电压过低,会使测得的温度与实际温度出现偏高现象,使温度输出定格在85℃。 (2)连接DS18B20的总线电缆长度是有限制的。当采用普通信号电缆传输长度又超过50m时,读取的测温数据容易发生错误,当采用双绞线带屏蔽电缆作为总线电缆时,正常通讯距离可达150m,当采用每米胶合次数更多的双绞线带屏蔽电缆时,正常通讯距离可以进一步加长。这种情况主要由总线分布电容使信号波形产生畸变造成的。因此,进行长距离测量时要充分考虑总线分布电容及阻抗匹配问题。 3.3  液晶显示器和单片机接口技术 3.3.1  LM032L显示器简介 LM032L字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵LCD,目前常用16×1,16×2,20×2和40×2行等的模块。显示字符时,由于LM032L内带字符发生器的控制器,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。 3.3.2  LM032L的基本参数及引脚功能 LM032L分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如图3.5所示。 图3.5  LM032L结构图 LM032L主要技术参数:  容量:20×2个字符。 芯片工作电压:4.5V~5.5V。 工作电流:2.0mA(5.0V)。 模块最佳工作电压:5.0V。 字符尺寸:2.95 mm×4.35 mm (W×H)。 引脚功能说明: LM032L采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表3.2所示。 表3.2  引脚接口说明表 编号 符号 引脚说明 编号 符号 引脚说明 1 VSS 电源地 9 D2 数据 2 VDD 电源正极 10 D3 数据 3 VL 液晶显示偏压 11 D4 数据 4 RS 数据/命令选择 12 D5 数据 5 R/W 读/写选择 13 D6 数据 6 E 使能信号 14 D7 数据 7 D0 数据 15 BLA 背光源正极 8 D1 数据 16 BLK 背光源负极             第1脚:VSS为地电源。 第2脚:VDD接5V正电源。 第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生鬼影,使用时可以通过一个10k的电位器调整对比度。 第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。 第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。 第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。 第7~14脚:D0~D7为8位双向数据线。 第15脚:背光源正极。 第16脚:背光源负极。 3.3.3  控制指令说明 LM032L液晶模块内部的控制器共有11条控制指令,如表3.3所示。 表3.3  控制命令表 指令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0 清显示 0 0 0 0 0 0 0 0 0 1 光标返回 0 0 0 0 0 0 0 0 1 * 置输入模式 0 0 0 0 0 0 0 1 I/D S 显示开/关控制 0 0 0 0 0 0 1 D C B 光标或字符移位 0 0 0 0 0 1 S/C R/L * * 置功能 0 0 0 0 1 DL N F * * 置字符发生存贮器地址 0 0 0 1 字符发生存贮器地址 置数据存贮器地址 0 0 1 显示数据存贮器地址 读忙标志或地址 0 1 BF 计数器地址 写数到CGRAM或DDRAM 1 0 要写的数据内容 从CGRAM或DDRAM读数 1 1 读出的数据内容                       LM032L液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。(说明:1为高电平、0为低电平) 指令1:清显示,指令码01H,光标复位到地址00H位置。 指令2:光标复位,光标返回到地址00H。 指令3:光标和显示模式设置。I/D:光标移动方向,高电平右移,低电平左移。S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。 指令4:显示开关控制。D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示。C:控制光标的开与关,高电平表示有光标,低电平表示无光标。B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。 指令5:光标或显示移位。S/C:高电平时移动显示的文字,低电平时移动光标。 指令6:功能设置命令。DL:高电平时为4位总线,低电平时为8位总线。N:低电平时为单行显示,高电平时双行显示。F: 低电平时显示5×7的点阵字符,高电平时显示5×10的点阵字符。 指令7:字符发生器RAM地址设置。 指令8:DDRAM地址设置。 指令9:读忙信号和光标地址。BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。 指令10:写数据。 指令11:读数据[9]。 3.3.4  LM032L与单片机接口电路 本系统的显示部分采用LM032L字符显示模块,与采用数码管相比,硬件连接和软件调试上都由优势。只要把要显示的内容放进液晶模块的显示存储器里面就可以直观的显示出指定的内容,操作方便。 系统显示电路由单片机AT89C52、字符液晶显示器LM032L和1k×8的排组构成。单片机实现对LCD命令和显示数据的读写控制功能,P1口作数据口,与LM032L的D0~D7相接,在P1口与D0~D7数据线之间分别接8个上拉电阻,以确保电路能够正常显示。AT89C52的P1口作为LCD的控制线,P2.0~P2.2分别接LM032L的RS、RW和E端;LM032L的其它三个控制端V 和V 、V 分别接电源和地。系统显示电路组成如图3.6所示。 图3.6  LM032L与单片机的连接 3.4  时钟芯片DS1302简介 DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小于31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.5 V~5.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。DS1302用于数据,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。DS1302的引脚如图3.7所示。 图3.7  DS1302的引脚 DS1302各引脚的功能为: Vcc1:主电源;Vcc2:备份电源。当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。 SCLK:串行时钟,输入,控制数据的输入与输出。 I/O:三线接口时的双向数据线。 RST:输入信号,在读、写数据期间,必须为高。该引脚有两个功能:第一,RST开始控制字访问移位寄存器的控制逻辑;其次,RST提供结束单字节或多字节数据传输的方法。DS1302与单片机的连接如图3.8所示。 图3.8  DS1302与单片机的连接 DS1302的工作原理:DS1302工作时为了对任何数据传送进行初始化,需要将复位脚(RST)置为高电平且将8位地址和命令信息装入移位寄存器。数据在时钟(SCLK)的上升沿串行输入,前8位指定访问地址,命令字装入移位寄存器后,在之后的时钟周期,读操作时输出数据,写操作时输出数据。时钟脉冲的个数在单字节方式下为8+8(8位地址+8位数据),在多字节方式下为8加最多可达248的数据[10]。 DS1302内部的RAM分为两类,一类是单个RAM单元,共31个,每个单元为一个8位的字节,其命令控制字为COH~FDH,其中奇数为读操作,偶数为写操作;再一类为突发方式下的RAM,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)[11]。 我们现在已经知道了控制寄存器和RAM的逻辑地址,接着就需要知道如何通过外部接口来访问这些资源。单片机是通过简单的同步串行通讯与DS1302通讯的,每次通讯都必须由单片机发起,无论是读还是写操作,单片机都必须先向DS1302写入一个命令帧,这个帧的格式如表1所示,最高位BIT7固定为1,BIT6决定操作是针对RAM还是时钟寄存器,接着的5个BIT是RAM或时钟寄存器在DS1302的内部地址,最后一个BIT表示这次操作是读操作抑或是写操作。 物理上,DS1302的通讯接口由3个口线组成,即RST,SCLK,I/O。其中RST从低电平变成高电平启动一次数据传输过程,SCLK是时钟线,I/O是数据线。具体的读写时序参考时序图,但是请注意,无论是哪种同步通讯类型的串行接口,都是对时钟信号敏感的,而且一般数据写入有效是在上升沿,读出有效是在下降沿(DS1302正是如此的,但是在芯片手册里没有明确说明),如果不是特别确定,则把程序设计成这样:平时SCLK保持低电平,在时钟变动前设置数据,在时钟变动后读取数据,即数据操作总是在SCLK保持为低电平的时候,相邻的操作之间间隔有一个上升沿和一个下降沿[12]。DS1302的命令字结构如图3.9所示。 图3.9  DS1302的命令字结构 3.5  24C32简介 概述:24C32是一个32K位串行CMOS E2PROM 内部含有4096个字节,每字节为8位,其先进CMOS技术实质上减少了器件的功耗,24C32有一个32字节页写缓冲器,该器件通过 I2C 总线接口进行操作。以下是对各个管脚的名称简单描述[13]。 A0 ,A1 ,A2:器件地址选择。 SDA:串行数据/地址。 SCK:串行时钟。 WP:写保护。 Vcc:﹢1.8V~﹢6.0V 工作电压。 Vss:地。 24C32的引脚图如图3.10所示。 图3.10  24C32的引脚图 以下是对各个管脚的功能简单描述: SCK:串行时钟。 24C32串行时钟输入管脚用于产生器件所有数据发送或接收的时钟,这是一个输入管脚。 SDA:串行数据/地址。 双向串行数据/地址管脚用于器件所有数据的发送或接收,SDA是一个开漏输出管脚,可与其它开漏输出或集电极开路输出进行线或Wire-OR。 A0 ,A1 ,A2:器件地址输入端。 这些管脚为硬连线或者不连接,在硬件上与24C16兼容,对于单总线系统最多可寻址8个,24C32器件参阅器件寻址,当这些引脚没有连接时其默认值为0。 WP:写保护。 当WP脚连接到Vcc所有内存变成写保护,只能读,当WP引脚连接到Vss或悬空,允许器件进行读/写操作。 I2C总线协议的描述及定义如下: (1) 只有在总线空闲时才允许启动数据传送。 (2) 在数据传送过程中当时钟线为高电平时,数据线必须保持稳定状态,不允许有跳变。时钟线为高电平时,数据线的任何电平变化将被看作总线的起始或停止信号。 起始信号:时钟线保持高电平期间,数据线电平从高到低的跳变作为I2C总线的起始信号。 停止信号:时钟线保持高电平期间,数据线电平从低到高的跳变作为I2C总线的停止信号[14]。   24C32与单片机连接如图3.11所示。 图3.11  24C32与单片机连接 3.6  键盘电路设计 根据本设计需要,本系统采用4×4键盘实现对功能和数字键的设定。自定义键盘定义如下:0到9之间的10个数字键定义为普通的数字键,×键定义为时间调整打开键,即按×键进入时间调整设定。÷键定义为时间位切换键,并且按年、月、日、时、分、秒,依次向右移位,比如当对年调整结束要对月进行调整时,按一下÷键就对月开始调整,再按一下÷键则对日进行调整,依此类推。+键定义为时间调整结束后,显示当前时间记录下的两个温度值。=键定义为返回到原来的状态,即时间和两个温度值同时显示的状态。 键盘与单片机接口电路如图3.12所示。 图3.12  键盘与单片机接口电路 3.7  报警电路设计 本系统采用单片机与蜂鸣器相连来显示当前系统所处的状态来报警。P3.5口与蜂鸣器相连,在P3.5与蜂鸣器中间接一个5.1k的电阻起到防止电流过大,进而保护器件的作用。 报警电路说明:当DS18B20所测得的温度超过报警上限时,这里即超过50℃,蜂鸣器报警,否则蜂鸣器不报警。报警电路如图3.13所示。 图3.13  报警电路 3.8  控制部分 硬件电路中单片机起控制作用,它相当于人的大脑;DS18B20进行温度采集,把采集到的室内温度送到单片机中,单片机进行判断,根据判断的结果控制相应引脚输出高电平或低电平,从而控制继电器线圈中能否有电流经过,达到控制电风扇转动或停止的目的,继电器用来实现对电风扇和加热装置的自动控制。 在系统中,单片机通过检测DS18B20采集的温度来作出相应处理,当温度高于某一设定值时,P3.0输出低电平,继电器线圈得电,其对应常开触点闭合,电风扇电路导通,电风扇转动;当温度低于设定温度值时,单片机P3.0引脚输出高电平,继电器线圈中没有电流通过,常开触点保持断开,电风扇电路不通电,电风扇不能运行,从而实现了电风扇的自动起停。为了仿真的便利考虑,本设计用LED绿灯表示风扇,LED绿灯亮表示风扇通电转动,LED绿灯不亮表示风扇电路不通电,风扇不能运行。单片机控制的通风电路如图3.14所示。 图3.14  单片机控制的通风电路 同样当温度低于某一设定值时,P3.1输出低电平,继电器线圈得电,其对应常开触点闭合,加热电路通电,开始工作加热。当温度高于设定温度值时,单片机P3.1引脚输出高电平,继电器线圈中没有电流通过,常开触点保持断开,加热电路没通电,加热电路不工作。同样处于便利考虑,用LED红灯表示加热电路。单片机控制的加热电路如图3.15所示。 图3.15  单片机控制的加热电路 4  系统软件设计 这部分主要对主程序和各子程序做介绍。 4.1  读DS18B20的序列号 程序中主要对DS18B20的初始化子程序,然后读出DS18B20的64位序列号存入到40H~47H中,然后将40H内容送入P0口,显示出40H中的二进制数,记录下来后分别把41H~47H的内容送入P0口显示并记录。2个DS18B20的序列号分别为: (1)28H 30H C5H B8H 00H 00H 00H 8EH (2)28H 31H C5H B8H 00H 00H 00H B9H 4.2  主程序设计 系统主流程图如图4.1所示,整个软件包括温度采集和数据传输两个主要部分组成。主要完成LCD、中断、DS1302和DS18B20的初始化,并对测温精度设置。 图4.1  系统主程序流程图        4.3  DS18B20子程序的设计 先对DS18B20初始化,再进行DS18B20的匹配操作,然后跳过所有的DS18B20,对所有的DS18B20进行温度转换,延时1s,初始化DS18B20,此后发出匹配命令,写入64位的ROM序列号,总线上只有与此序列号相同的DS18B20才会作出反应,选中次DS18B20,然后对该DS18B20进行读操作,把温度值存放在指定的两个地址中,接下来写入第二个DS18B20的序列号,把其温度值发在指定的地址。DS18B20 子程序流程图如图4.2所示。 图4.2  DS18B20 子程序流程图 DS18B20子程序: sbit ds=P2^6;    //传感器IO口 uchar code num1[]={0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e}; uchar code num2[]={0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9}; void jisuan(int i)          //数据计算函数 {int a,b,c,k; uchar x;    if(wdxz==0)x=0;if(wdxz==1)x=8;if(i<0){ i=(~i)+1;a=(((i%1000)%100)%10);b=((((i+a)/10)%100)%10);c=(((i+a+b*10)/100)%10);k=10; } else {a=(((i%1000)%100)%10);b=((((i-a)/10)%100)%10);c=(((i-a-b*10)/100)%10);k=(i-a-b*10-c*100)/1000;} show(k,0+x); show(c,1+x);show(b,2+x); show(12,3+x);show(a,4+x); } void yaoqiu1()    //传感器设置,读取温度值    { uchar i;reset();delays(200); fasong(0x55);if(wdxz==0) for(i=0;i<8;i++) fasong(num1[i]); if(wdxz==1) for(i=0;i<8;i++) fasong(num2[i]); fasong(0xbe); } int zhi()          //对获取值进行处理  发送至计算函数 {unsigned char i,j;int k,f,c,d; yaoqiu1();i=dedao();j=dedao(); f=j;f<<=8;f|=i;k=f;k=k*0.625; jisuan(k); if(wdxz==0)wdxz=1;else wdxz=0; return(k); } 4.4  24C32子程序的设计 I2C驱动,从地址A0,输入存地址高八位,输入存地址低八位,写入数据。从地址A1,输入读取地址高八位,读取地址第八位,输出数据。24C32子程序流程图如图4.3所示。 图4.3  24C32子程序流程图 24C32子程序: sbit sda=P3^6;sbit scl=P3^7; uchar readbyte()                      //读取一个字节 {uchar i,dat;for(i=0;i<8;i++) {scl=1;dat<<=1;if(sda==1)dat|=0x01;scl=0; } return dat; } void sendbyte(uchar dat)                //发送一个字节 {uchar i;for(i=0;i<8;i++) {if((dat&0x80)==0x80)sda=1; else sda=0;nop;scl=1;nop; nop;scl=0;dat<<=1; } } void  sendsave(uint address,uchar dat)    //向某地址发送一个字节 {start();sendbyte(0xa0); ask();sendbyte(address/256); ask();sendbyte(address%256); ask();sendbyte(dat); ask();stop(); delayx(5); } uchar revsave(uint address)              //读取某地址的内容 { uchar dat;start();sendbyte(0xa0);ask();sendbyte(address/256); ask(); sendbyte(address%256);ask();start();sendbyte(0xa1);ask(); dat=readbyte(); stop();return dat; } 5  仿真结果 这部分主要对使用Keil软件进行编程与调试做介绍。 5.1  软件编程与调试简介 Keil软件是美国Keil Software 公司出品的51 系列兼容单片机C语言和汇编语言软件开发系统,而且是目前最流行开发MCS-51系列单片机的软件。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部份组合在一起。运行Keil软件需要Pentium或以上的CPU,16MB或更多RAM、20M以上空闲的硬盘空间、WIN98、NT、WIN2000、WINXP等操作系统[15]。 在Keil软件中编程的步骤如下: (1)先建一个新的工程,保存到一个位置。 (2)选择处理器,这里选择AT89C52。 (3)接下来会问是否把Startup Code加入到工程,选否即可,工程就建完了。 (4)新建一个文档用来编辑程序。 (5)编辑完存为.asm(汇编源文件)。 (6)接下来把保存的.asm文件加入到工程里。 (7)下面进行工程配置。点击Project菜单下的Options for Target ‘Target 1’。 (8)在弹出对话框的Target 项里输入晶振为12MHz,然后勾上Use On-chip ROM。 (9)在Output项里勾上Create HEX File。这就是产生要烧写的.hex文件。 (10)然后点击Project菜单里的build target或Rebuild all target files以编译要烧写的.hex文件。 (11)编译完会在下面Output Window里显示编译成功与否的信息和错误提示。如果出现错误,双击错误提示处即可找到错误程序语句。 5.2  系统软件仿真 在编辑环境中双击AT89C52,在弹出的对话框中将编译生成可执行文件1. hex。 加载进芯片中,设单片机的时钟工作频率为12MHz。点击全速运行按钮,将出现如下仿真结果:在系统的启动过程之中,液晶第一行将会显示传感器所测得的两个温度信息,第二行将会时间日期信息。仿真运行结果如图5.1所示。 图5.1  仿真运行结果 按下×键仿真可以对时间进行设定,设定时间时仿真如图5.2所示。 图5.2  设定时间时仿真 按下+键就调出某一时间记录的双路温度,某一时间双路温度如图5.3所示。 图5.3  某一时间双路温度 当温度超过40℃时,系统自动通风,在仿真中绿灯亮表示正通风,绿灯亮如图5.4所示。 图5.4  绿灯亮 当温度低于0℃时,系统自动加热,在仿真时用红灯表示加热装置,当红灯亮时表示正在加热。红灯亮如图5.5所示。 图5.5  红灯亮 结束语 本文介绍了用DS18B20采集温度,用单片机AT89C52控制LM032L显示屏显示并实现温度的自动控制和报警。系统分析各单元电路的设计,以及各电路与单片机的接口技术。着重分析系统软件的设计过程,使用汇编语言进行程序没计。本文是采用模块化的方式进行叙述,对各模块的设计进行了比较详细地阐述。本次设计的基于DS18B20的双路温度控制系统是一个分布式的温度测量系统,它可以远程对温度实现测量和监控,广泛应用于电力工业、煤矿、森林、火灾、高层建筑等场合。 本文从系统方案等一些方面来进行论证。使用单片机作为控制核心,采用两个个温度传感器对双路温度进行检测,以液晶显示屏显示检测温度,通过4×4矩阵键盘模块选择时间对与其对应的温度进行显示。设计完成了双路温度测量及显示,时间的显示,以及自动温度控制和报警,并存储温度信息。通过这次毕业设计,我更加深刻地认识到只有将书本与具体的实践相结合,才会有真正的收获,才能巩固自己的所学,认识到自己的不足。通过查阅资料和利用工具,以及熟练地使用Pruteus仿真软件和Keil开发工具,终于最后完成了本设计。解决了几个难点,比如DS18B20的序列号读出和液晶温度符号的显示以及温度的精度显示如何实现。 致  谢 毕业设计是每个大学生必须面临的一项综合素质的考验,如果说在过去四年里,我们的学习是一个知识的积累过程,那么现在的毕业设计就是对过去所学知识的综合运用,是对理论进行深化和重新认识的时间活动。在这近三个月的毕业设计中,学习能力得到了提高。我们有艰辛的付出,当然更多的是丰收的喜悦。知识固然得到了巩固和提高,但我相信在实践中的切身体会将会使我在以后的工作和学习中终身受用。 在此非常感谢苏卫民教授对我的指导,也感谢辅导老师和同学对我设计中遇到困难的帮助。 我还要特别感谢我的父母,多年来正是他们无私的奉献与无条件的支持才使得我得以完成学业。目前除了学习成绩尚可外无以为报,希望以后的学习、工作和生活能使父母宽慰。 参 考 文 献 [1] 求是科技. 8051单片机系列C语言程序设计完全手册[M]. 北京:人民邮电出版社,2006. [2] 毛永红. 基于串口方式的PC机与单片机的多机通信[J]. 长治学院学报,2008, 25(2): 46~48. [3] 来清民. 传感器与单片机接口及实例[M]. 北京:北京航空航天大学出版社,2008.  [4] 谢宜仁,谢东辰,李杰,等. 单片机硬件接口电路及实例解析[M]. 北京:电子工业出版社,2009. [5] 戴佳,戴卫恒. 51单片机C语言应用程序设计实例精讲[M]. 北京:电子工业出版社,2009. [6] 张毅刚. MCS-51单片机应用设计[M]. 哈尔滨:哈尔滨工业大学出版社,2004. [7] 李瑜芳. 传感器原理及其应用[M]. 成都:电子科技大学出版社,2008. [8] 张培仁. MCS-51单片机原理与应用[M]. 北京:清华大学出版社,2003. [9] 李叶紫. MCS-51单片机应用教程[M]. 北京:清华大学出版社,2004. [10] 陈忠平. 单片机原理及接口[M]. 北京:清华大学出版社,2006. [11] 马忠梅. 单片机的C语言应用程序设计[M]. 北京:北京航空航天大学出版社,2003. [12] 霍孟友. 单片机原理与应用学习概要及题解[M]. 北京:机械工业出版社,2005. [13] 王超. Multisim10仿真软件在单片机实践教学中的应用[J]. 山东轻工业学院学报,2010,24(3): 64~66. [14] 周润景. 基于PROTEUS的电路及单片机系统设计与仿真[M]. 北京:北京航天航空大学出版社,2006. [15] 辉讲平,周国雄. 基于Proteus的单片机系统设计与仿真实例[M]. 北京:机械工业出版社,2009. 附录A  整体电路图 附录B 程序清单 主程序: #include                              /*头文件*/ #include"lcd1602.h" #include"b20.h" #include"c32.h" #define uchar unsigned char #define uint unsigned int uchar temp1,temp2,temp3,temp4,temp5,temp6,n=0,a1=1,a2=1,a3=0,a4=3,a5=2,a6=4,a7=1,a8=4,enter=0; bit clear=0; sbit dsio=P2^3; sbit dsclk=P2^4; sbit dsrst=P2^5; sbit led1=P3^0; sbit led2=P3^1; sbit speaker=P3^5; void dssendbyte(uchar byte)                /*DS1302发送一个字节*/ { uchar i; dsclk=0; nop; nop; for(i=0;i<8;i++) { dsio=byte&0x01; dsclk=1; nop; nop; dsclk=0; byte>>=1; } } void dssendteam(uchar cmd,uchar dat)              /*DS1302发送多个字节*/ { dsrst=0; dsclk=0; dsrst=1; nop; nop; dssendbyte(cmd); dssendbyte(dat);                dsclk=1; dsrst=0; } uchar dsrevbyte()                            /*DS1302接收一个字节*/ {    uchar i,dat; nop; nop; for(i=0;i<8;i++) { dat>>=1; if(dsio==1)dat|=0x80; dsclk=1; nop; nop; dsclk=0; nop;nop; } return(dat); } uchar dsrev(uchar cmd)                            /*DS1302接收多个字节*/ {uchar dat; dsrst=0; dsclk=0; dsrst=1; nop; nop; dssendbyte(cmd); dsio=1; dat=dsrevbyte(); dsclk=1; dsrst=0; return(dat); } void dsint()                            /*DS1302初始化*/ { dssendteam(0x8e,0x00); dssendteam(0x80,((20/10)<<4|(59%10))); dssendteam(0x82,((59/10)<<4|(59%10))); dssendteam(0x84,((13/10)<<4|(13%10))); dssendteam(0x86,((24/10)<<4|(24%10))); dssendteam(0x88,((3/10)<<4|(3%10))); dssendteam(0x8a,((4/10)<<4|(4%10))); dssendteam(0x8c,((11/10)<<4|(11%10))); dssendteam(0x90,0xa5); dssendteam(0x8e,0x80); } void dsnian()                            /*读取年*/ { uchar i,j; temp1=dsrev(0x8d); i=((temp1&0x70)>>4); j=temp1&0x0f; show(i,2+0x40); show(j,3+0x40); } void dsyue()                            /*读取月*/ { uchar i,j; temp2=dsrev(0x89); i=((temp2&0x70)>>4); j=temp2&0x0f; show(i,5+0x40); show(j,6+0x40); } void dsri()                            /*读取日*/ { uchar i,j; temp3=dsrev(0x87); i=((temp3&0x70)>>4); j=temp3&0x0f; show(i,8+0x40); show(j,9+0x40); } void dsshi()                            /*读取小时*/ { uchar i,j; temp4=dsrev(0x85); i=((temp4&0x70)>>4); j=temp4&0x0f; show(i,11+0x40); show(j,12+0x40); } void dsfen()                            /*读取分*/ { uchar i,j; temp5=dsrev(0x83); i=((temp5&0x70)>>4); j=temp5&0x0f; show(i,14+0x40); show(j,15+0x40); } void dsmiao()                            /*读取秒*/ { uchar i,j; temp6=dsrev(0x81); i=((temp6&0x70)>>4); j=temp6&0x0f; show(i,17+0x40); show(j,18+0x40); } /*************************************/ void keys()interrupt 0                                /*4×4键盘中断程序*/ { uchar temp,f,g; long int panduan; EA=0; P0=0xff; P0=0xf0; temp=P0; if(temp!=0xf0) { delayx(10); if(temp!=0xf0) { P0=0xfe; temp=P0; switch(temp) { case(0xee):f=7;g=1;break; case(0xde):f=8;g=1;break; case(0xbe):f=9;g=1;break; case(0x7e):if(n==8)n=1;else n++;delayx(300);break; } P0=0xfd; temp=P0; switch(temp) { case(0xed):f=4;g=1;break; case(0xdd):f=5;g=1;break; case(0xbd):f=6;g=1;break; case(0x7d):enter=1;n=1;clear=1;break; } P0=0xfb; temp=P0; switch(temp) { case(0xeb):f=1;g=1;break; case(0xdb):f=2;g=1;break; case(0xbb):f=3;g=1;break; case(0x7b):break; } P0=0xf7; temp=P0; switch(temp) { case(0xe7):break; case(0xd7):f=0;g=1;break; case(0xb7):enter=0;clear=1;break; case(0x77):enter=2;clear=1;break; } } } if(g==1){if(enter==1){ switch(n) { case(1):a1=f;break; case(2):a2=f;break; case(3):a3=f;break; case(4):a4=f;break; case(5):a5=f;break; case(6):a6=f;break; case(7):a7=f;break; case(8):a8=f;break; default:break;    }      } g=0;  } EA=1;P0=0xf0; } void time0()interrupt 1 {speaker=(~speaker);  TL0=0x00; TH0=0xf3;} void main()                            /*主函数*/ { uchar flag=0,dl,temp,dat1,dat2; uint i=0,j=0; uint wd1,wd2,dat3,dat4; led1=1; led2=1; TMOD=0x11; TL0=0x00; TH0=0xf3; ET0=1; EX0=1; IT0=1; EA=1; lcdint(); delayx(10); dsint(); yaoqiu1(); i=dedao(); j=dedao(); P0=0xf0; yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); yaoqiu(); zhi(); writecom(0x01);delayx(5); show2(); for(j=0;j<=4000;j++) {sendsave(j,0);} writecom(0x01);delayx(5); while(1) {    if(enter==0){  if(clear==1){writecom(0x01);delayx(5);clear=0;} show(2,0x40); show(0,0x41); show(10,0x44); show(10,0x47); show(11,13+0x40); show(11,16+0x40); yaoqiu(); wd1=zhi(); yaoqiu(); wd2=zhi(); if((wd1&0x8000)==0x8000)led1=0;else led1=1; if(((wd1&0x8000)!=0x8000)&&(wd1>=400))led2=0;else led2=1; if(((wd1&0x8000)!=0x8000)&&(wd1>=500))TR0=1;else TR0=0; dsnian(); dsyue(); dsri(); dsshi(); dsfen(); dsmiao(); } if(enter==1){ if(clear==1){writecom(0x01);delayx(5);clear=0;} show1(); show(a1,0+0x40); show(a2,1+0x40); show(10,2+0x40); show(a3,3+0x40); show(a4,4+0x40); show(10,5+0x40); show(a5,6+0x40); show(a6,7+0x40); show(13,8+0x40); show(a7,9+0x40); show(a8,10+0x40); delayx(200); if(n<=2)show(13,n-1+0x40); if((n>2)&&n<=4)show(13,n+0x40); if((n>4)&&n<=6)show(13,n+1+0x40); if(n>6)show(13,n+2+0x40); delayx(200); } if(enter==2) { if(clear==1){writecom(0x01);delayx(5);clear=0;} for(j=1;j<=4000;j+=8    ) {  uint search; search=j; temp=revsave(j); temp&=0x7f; if(temp!=((a1<<4)+a2))continue; j++; temp=revsave(j); temp&=0x7f; if(temp!=((a3<<4)+a4)){j=search;continue;    } j++; temp=revsave(j); temp&=0x7f; if(temp!=((a5<<4)+a6)){j=search;continue;    } j++; temp=revsave(j); temp&=0x7f; if(temp!=((a7<<4)+a8)){j=search;continue;    } j++; dat1=revsave(j); j++; dat2=revsave(j); dat3=dat1*256+dat2; j++; dat1=revsave(j); j++; dat2=revsave(j); dat4=dat1*256+dat2; wdxz=0;jisuan(dat3); wdxz=1;jisuan(dat4); break; } while(enter==2); } /*********************************************************/ if(((temp5&0x7f)==0)&&((temp6&0x7f)==0)&&(flag==0)) {    if(i>=4000)i=0;    i++; sendsave(i,temp1);i++; sendsave(i,temp2);i++; sendsave(i,temp3);i++; sendsave(i,temp4);i++; sendsave(i,wd1/256);i++; sendsave(i,wd1%256);i++; sendsave(i,wd2/256);i++; sendsave(i,wd2%256); //    sendsave(9,0x11); //    sendsave(10,0x11); //    sendsave(11,0x11); //    sendsave(12,0x11); //    sendsave(13,0x00); //    sendsave(14,0x14); //    sendsave(15,0x00); //    sendsave(16,0x14); flag=1;} if((temp6&0x7f)==10)flag=0; } } ========================================================== LCD 1602 显示子程序: #include #include #define uchar unsigned char #define uint unsigned int #define nop _nop_() sbit RS=P2^0; sbit RW=P2^1; sbit E=P2^2; sbit BF=P1^7; void delayms()                            /*延时*/ { uchar i,j; for(i=0;i<10;i++) for(j=0;j<33;j++); } void delayx(uint n)                            /*延时*/ { uint i; for(i=0;i #include  /*abs头文件*/ sbit ds=P2^6;    /*传感器IO口*/ uchar code num1[]={0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e}; uchar code num2[]={0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9}; uchar wdxz=0; void delay(int n)    /*通用延时1*/ { int i; for(i=0;i>1); delays(5); } return(v);; } void fasong(unsigned char dat)      /*向传感器发送数据*/ {  unsigned char i,j,g; for(i=0;i<=7;i++) { j=dat&0x01; dat>>=1; if(j){ds=0;g++;g--;ds=1;delays(5);} else{ds=0;delays(5);ds=1;}} ds=1; } void jisuan(int i)          /*数据计算函数*/ {int a,b,c,k; uchar x;    if(wdxz==0)x=0;if(wdxz==1)x=8;if(i<0){ i=(~i)+1;a=(((i%1000)%100)%10);b=((((i+a)/10)%100)%10);c=(((i+a+b*10)/100)%10);k=10; } else {a=(((i%1000)%100)%10);b=((((i-a)/10)%100)%10);c=(((i-a-b*10)/100)%10);k=(i-a-b*10-c*100)/1000;} show(k,0+x); show(c,1+x);show(b,2+x); show(12,3+x);show(a,4+x); } void yaoqiu()      /*传感器设置,无64位效验码,温度转换*/    { uchar i; reset(); delays(200); fasong(0x55);if(wdxz==0) for(i=0;i<8;i++) fasong(num1[i]); if(wdxz==1) for(i=0;i<8;i++) fasong(num2[i]); fasong(0x44); } void yaoqiu1()    /*传感器设置,读取温度值    */ { uchar i; reset(); delays(200); fasong(0x55);if(wdxz==0) for(i=0;i<8;i++) fasong(num1[i]); if(wdxz==1) for(i=0;i<8;i++) fasong(num2[i]); fasong(0xbe); } int zhi()          /*对获取值进行处理  发送至计算函数*/ { unsigned char i,j; int k,f,c,d; yaoqiu1(); i=dedao(); j=dedao(); f=j;f<<=8; f|=i; k=f; k=k*0.625; jisuan(k); if(wdxz==0)wdxz=1;else wdxz=0; return(k); } ========================================================== 24C32子程序: #include #include #define uchar unsigned char #define uint unsigned int #define nop _nop_() sbit sda=P3^6; sbit scl=P3^7; void start()            /*I2C起始信号*/ { sda=1; scl=1; nop; nop; nop; nop; nop; sda=0; nop; nop; nop; nop; nop; scl=0; } void stop()                /*I2C终止信号*/ { sda=0; scl=1; nop; nop; nop; nop; nop; sda=1; nop; nop; nop; nop; nop; sda=0; scl=0; } bit ask()              /*I2C应答信号*/ { bit askcda; sda=1; nop; nop; scl=1; nop; nop; nop; nop; nop; askcda=sda; scl=0; return askcda; } uchar readbyte()          /*读取一个字节*/ { uchar i,dat; for(i=0;i<8;i++) { scl=1; dat<<=1; if(sda==1)dat|=0x01; scl=0; } return dat; } void sendbyte(uchar dat)                  /*发送一个字节*/ { uchar i; for(i=0;i<8;i++) {    if((dat&0x80)==0x80)sda=1; else sda=0; nop; scl=1; nop; nop; scl=0; dat<<=1; } } void  sendsave(uint address,uchar dat)        /*向某地址发送一个字节*/ { start(); sendbyte(0xa0); ask(); sendbyte(address/256); ask(); sendbyte(address%256); ask(); sendbyte(dat); ask(); stop(); delayx(5); } uchar revsave(uint address)          /*读取某地址的内容*/ { uchar dat; start(); sendbyte(0xa0); ask(); sendbyte(address/256); ask(); sendbyte(address%256); ask(); start(); sendbyte(0xa1); ask(); dat=readbyte(); stop(); return dat; }
/
本文档为【基于单片机的双路温控装置论文】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索