《单片机原理及应用》
课程设计报告书
机电与控制工程学院
年 月 日
填 写 说 明
1、正文部分:
(1) 标题与正文格式定义标准如下:
一级标题:1.标题1
二级标题:1.1标题2
三级标题:1.1.1标题3
四级标题:1.1.1.1标题4
(2)表格:尽可能采用三线表。
(3)图形:直接插入的插图应有图标、图号,不能直接插入的图应留出插图空位。图中文字、符号书写要清楚,并与正文一致。
(4)文字表述:要求层次清楚,语言流畅,语句通顺,无语法和逻辑错误,无错字、别字、漏字。文字的表述应当以科学语言描述研究过程和研究结果,不要以口语化的方式表达,报告中科技术语和名词应符合规定的通用词语,并使用法定计量单位和标准符号。
2、参考文献:
(1)数量要求:参考文献只选择最主要的列入,应不低于5种。
(2)种类要求:参考文献的引用,可以是著作[M]、论文[J]、专利文献[P]、会议论文等。
(3)文献著录格式及示例。参考文献用宋体五号字。
[1] 作者. 书名[M]. 版次. 出版地: 出版者, 出版年: 起止页码 (著作图书文献)
[2] 作者. 文章名[J]. 学术刊物名称. 年. 卷(期): 起止页码 (学术刊物文献)
示例: [1]王社国,赵建光。基于ARM的嵌入式语音识别系统研究 [J]。微计算机信息,2007,2-2:149-150.
3、附录或附件:(可选项)
重要的测试结果、图表、设计图纸、源程序代码、大量的公式、符号、照片等不宜放入正文中的可以附录形式出现。
4、如果需要可另行附页粘贴。
任 务 书
1. 设计要求
利用数字温度传感器DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号,计算后在LED数码管上显示相应的温度值。其温度测量范围为?55℃~125℃,精确到0.5℃。数字温度计所测量的温度采用数字显示,控制器使用单片机AT89C51,测温传感器使用DS18B20,用3位共阳极LED数码管以串口传送数据,实现温度显示。
2. 原理
从温度传感器DS18B20可以很容易直接读取被测温度值,进行转换即满足设计要求。
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字读数方式。
DS18B20的性能如下。
n 独特的单线接口仅需要一个端口引脚进行通信。
n 多个DS18B20可以并联在串行传输的数据线上,实现多点组网功能。无须外部器件。
n 可通过数据线供电,电压范围为3.0~5.5V。
n 零待机功耗。
n 温度以9或12位的数字读数方式。
n 用户可定义报警设置。
n 报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件。
n 负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。
目 录
1、绪论…………………………………………………………………… 5
2、方案论证(规划、选定)…………………………………………… 5
3、方案说明(设计)…………………………………………………… 7
4、硬件方案设计………………………………………………………… 10
5、软件方案设计………………………………………………………… 17
6、调试…………………………………………………………………… 20
7、技术小结(结束语)………………………………………………… 20
8、参考文献……………………………………………………………… 21
9、附录(源程序代码、电路图等)…………………………………………21
1、绪论
随着国民经济的发展,人们需要对各中加热炉、热处理炉、反应炉和锅炉中温度进行监测和控制。采用单片机来对他们控制不仅具有控制方便,简单和灵活性大等优点,而且可以大幅度提高被控温度的技术指标,从而能够大大的提高产品的质量和数量。
在日常生活及工业生产过程中,经常要用到温度的检测及控制,温度是生产过程和科学实验中普遍而且重要的物理参数之一。在生产过程中,为了高效地进行生产,必须对它的主要参数,如温度、压力、流量等进行有效的控制。温度控制在生产过程中占有相当大的比例。温度测量是温度控制的基础,技术已经比较成熟。传统的测温元件有热电偶和二电阻。而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,这些方法相对比较复杂,需要比较多的外部硬件支持。我们用一种相对比较简单的方式来测量。
我们采用美国DALLAS半导体公司继DS18B20之后推出的一种改进型智能温度传感器DS18B20作为检测元件,温度范围为-55~125 ºC,最高分辨率可达0.0625 ºC。DS18B20可以直接读出北侧温度值,而且采用三线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点。
本文介绍一种基于AT89C51单片机的一种温度测量及报警电路,该电路采用DS18B20作为温度监测元件,测量范围0℃-~+100℃,使用LED模块显示,能设置温度报警上下限。正文着重给出了软硬件系统的各部分电路,介绍了集成温度传感器DS18B20的原理,AT89C51单片机功能和应用。该电路设计新颖、功能强大、结构简单。
2、方案论证
该系统主要由温度测量和数据采集两部分电路组成,实现的方法有很多种,下面将列出两种在日常生活中和工农业生产中经常用到的实现方案。
2.1方案一
采用热电偶温差电路测温,温度检测部分可以使用低温热偶,热电偶由两个焊接在一起的异金属导线所组成,热电偶产生的热电势由两种金属的接触电势和单一导体的温差电势组成。通过将参考结点保持在已知温度并测量该电压,便可推断出检测结点的温度。数据采集部分则使用带有A/D 通道的单片机,在将随被测温度变化的电压或电流采集过来,进行A/D 转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来。热电偶的优点是工作温度范围非常宽,且体积小,但是它们也存在着输出电压小、容易遭受来自导线环路的噪声影响以及漂移较高的缺点,并且这种设计需要用到A/D 转换电路,感温电路比较麻烦。
系统主要包括对A/D0809 的数据采集,自动手动工作方式检测,温度的显示等,这几项功能的信号通过输入输出电路经单片机处理。此外还有复位电路,晶振电路,启动电路等。故现场输入硬件有手动复位键、A/D 转换芯片,处理芯片为51 芯片,执行机构有4 位数码管、报警器等。【1】
系统框图如图 3-1所示。
图 3-1 热电偶温差电路测温系统框图
2.2方案二
采用数字温度芯片DS18B20 测量温度,输出信号全数字化。便于单片机处理及控制,省去传统的测温方法的很多外围电路。且该芯片的物理化学性很稳定,它能用做工业测温元件,此元件线形较好。在0—100 摄氏度时,最大线形偏差小于1 摄氏度。DS18B20 的最大特点之一采用了单总线的数据传输,由数字温度计DS18B20和微控制器AT89S51构成的温度测量装置,它直接输出温度的数字信号,可直接与计算机连接。这样,测温系统的结构就比较简单,体积也不大。采用51 单片机控制,软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制,而且体积小,硬件实现简单,安装方便。既可以单独对多DS18B20控制工作,还可以与PC 机通信上传数据,另外AT89S51 在工业控制上也有着广泛的应用,编程技术及外围功能电路的配合使用都很成熟。【1】
该系统利用AT89S51芯片控制温度传感器DS18B20进行实时温度检测并显示,能够实现快速测量环境温度,并可以根据需要设定上下限报警温度。该系统扩展性非常强,它可以在设计中加入时钟芯片DS1302以获取时间数据,在数据处理同时显示时间,并可以利用AT24C16芯片作为存储器件,以此来对某些时间点的温度数据进行存储,利用键盘来进行调时和温度查询,获得的数据可以通过MAX232芯片与计算机的RS232接口进行串口通信,方便的采集和整理时间温度数据。
2.3方案选定
从以上两种方案,容易看出方案一的测温装置可测温度范围宽、体积小,但是线性误差较大。方案二的测温装置电路简单、精确度较高、实现方便、软件设计也比较简单,故本次设计采用了方案二。
3、方案说明
3.1系统设计原理
利用温度传感器DS18B20可以直接读取被测温度值,进行转换的特性,模拟温度值经过DS18B20处理后转换为数字值,然后送到单片机中进行数据处理,并与设置的温度报警限比较,超过限度后通过扬声器报警。同时处理后的数据送到LED中显示。
3.2系统组成
本课题以是80C51单片机为核心设计的一种数字温度控制系统,系统整体硬件电路包括,传感器数据采集电路,温度显示电路,上下限报警调整电路,单片机主板电路等组成。
系统框图主要由主控制器、单片机复位、报警按键设置、时钟振荡、LED显示、温度传感器组成。
系统框图如图3-2所示。
图3-2 系统基本方框图
3.2.1主控制器
单片机AT89C51具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用系统可用二节电池供电。
3.2.2显示电路
显示电路采用LED液晶显示数码管,从P3口RXD,TXD串口输出段码。显示电路是使用的串口显示,这种显示最大的优点就是使用口资源比较少,只用p3口的RXD,和TXD,串口的发送和接收,四只数码管采用74LS164右移寄存器驱动,显示比较清晰。
3.2.3温度传感器
温度传感器采用美国DALLAS半导体公司生产的DS18B20温度传感器。DS18B20输出信号全数字化。便于单片机处理及控制,在0—100 摄氏度时,最大线形偏差小于1 摄氏度,采用单总线的数据传输,可直接与计算机连接。
用AT89S51芯片控制温度传感器DS18B20进行实时温度检测并显示,能够实现快速测量环境温度,并可以根据需要设定上下限报警温度。获得的数据可以通过MAX232芯片与计算机的RS232接口进行串口通信,方便的采集和整理时间温度数据。
3.3 DS18B20温度传感器与单片机的接口电路
DS18B20可以采用两种方式供电,一种是采用电源供电方式,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源。另一种是寄生电源供电方式,如图3-3 所示单片机端口接单线总线,为保证在有效的DS18B20时钟周期内提供足够的电流,可用一个MOSFET管来完成对总线的上拉。
当DS18B20处于写存储器操作和温度A/D转换操作时,总线上必须有强的上拉,上拉开启时间最大为10us。采用寄生电源供电方式时VDD端接地。由于单线制只有一根线,因此发送接口必须是三态的。
图3-1 DS18B20与单片机的接口电路
4、硬件方案设计
4.1 80C51单片机介绍
80C51有40个引脚,4个8位并行I/O口,1个全双工异步串行口,同时内含5个中断源,2个优先级,2个16位定时/计数器。80C51的存储器系统由4K的程序存储器(掩膜ROM),和128B的数据存储器(RAM)组成。其基本组成框图见图4-1。
图4-1 80C51单片机结构图
1. 一个8 位的微处理器(CPU)。
2. 片内数据存储器RAM(128B),用以存放可以读/写的数据,如运算的中间结果、最终结果以及欲显示的数据等,SST89 系列单片机最多提供1K 的RAM。
3. 片内程序存储器ROM(4KB),用以存放程序、一些原始数据和表格。但也有一些单片机内部不带ROM/EPROM,如8031,8032,80C31 等。目前单片机的发展趋势是将RAM 和ROM 都集成在单片机里面,这样既方便了用户进行设计又提高了系统的抗干扰性。SST 公司推出的89 系列单片机分别集成了16K、32K、64K Flash 存储器,可供用户根据需要选用。
4. 四个8 位并行I/O 接口P0~P3,每个口既可以用作输入,也可以用作输出。
5. 两个定时器/计数器,每个定时器/计数器都可以设置成计数方式,用以对外部事件进行计数,也可以设置成定时方式,并可以根据计数或定时的结果实现计算机控制。为方便设计串行通信,目前的52 系列单片机都会提供3 个16 位定时器/计数器。
6. 五个中断源的中断控制系统。现在新推出的单片机都不只5 个中断源,例如SST89E58RD 就有9 个中断源。
7. 一个全双工UART(通用异步接收发送器)的串行I/O 口,用于实现单片机之间或单机与微机之间的串行通信。
8. 片内振荡器和时钟产生电路,但石英晶体和微调电容需要外接。最高允许振荡频率为12MHz。SST89V58RD 最高允许振荡频率达40MHz,因而大大的提高了指令的执行速度。
4.1.2 80C51单片机管脚图
图4-2 80C51单片机管脚图
部分引脚说明:
1. 电源类引脚
Vcc(40脚):芯片工作电源的输入端,+5V。
Vss(20脚):电源的接地端。
2. 时钟电路引脚
XTAL1(19 脚):接外部晶体和微调电容的另一端;在片内它是振荡电路反相放大器的输入端。在采用外部时钟时,该引脚必须接地。
XTAL2(18 脚):接外部晶体和微调电容的一端;在8051 片内它是振荡电路反相放大器的输出端。若需采用外部时钟电路时,该引脚输入外部时钟脉冲。
3. 控制信号引脚
RST/VPD(9 脚):RST 是复位信号输入端,高电平有效。
RST 引脚的第二功能是VPD,即接入RST 端,为RAM 提供备用电源,以保证存储在RAM 中的信息不丢失,从而合复位后能继续正常运行。
ALE/PROG(30 脚):地址锁存允许信号端。当8051 上电正常工作后,ALE 引脚不断向外输出正脉冲信号,此频率为振荡器频率fOSC 的1/6。CPU 访问片外存储器时,ALE 输出信号作为锁存低8 位地址的控制信号。平时不访问片外存储器时,ALE 端也以振荡频率的1/6 固定输出正脉冲,因而ALE 信号可以用作对外输出时钟或定时信号。ALE 端的负载驱动能力为8 个LS 型TTL(低功耗甚高速TTL)负载。
此引脚的第二功能PROG 在对片内带有4KB EPROM 的8751 编程写入(固化程序)时,作为编程脉冲输入端。
PSEN(29 脚):程序存储允许输出信号端。在访问片外程序存储器时,此端定时输出负脉冲作为读片外存储器的选通信号。PSEN 端有效,即允许读出EPROM/ROM 中的指令码。PSEN 端同样可驱动8 个LS 型TTL 负载。
EA/Vpp(31 脚):外部程序存储器地址允许输入端/固化编程电压输入端。当EA 引脚接高电平时,CPU只访问片内EPROM/ROM并执行内部程序存储器中的指令,但当PC(程序计数器)的值超过0FFFH(对8751/8051 为4K)时,将自动转去执行片外程序存储器内的程序。当输入信号EA 引脚接低电平(接地)时,CPU 只访问外部EPROM/ROM 并执行外部程序存储器中的指令,而不管是否有片内程序存储器。
此引脚的第二功能是Vpp 是对8751 片内EPROM固化编程时,作为施加较高编程电压(一般12V~21V)的输入端。
4. 并行I/0口
P0口(P0.0~P0.7,39~32 脚):P0口是一个漏极开路的8 位准双向I/O口。作为漏极开路的输出端口,每位能驱动8 个LS 型TTL 负载。当P0 口作为输入口使用时,应先向口锁存器(地址80H)写入全1,此时P0 口的全部引脚浮空,可作为高阻抗输入。在CPU 访问片外存储器时,P0口分时提供低8 位地址和8 位数据的复用总线。在此期间,P0口内部上拉电阻有效。
P1口(P1.0~P1.7,1~8 脚):P1口是一个带内部上拉电阻的8 位准双向I/O口。P1口每位能驱动4 个LS 型TTL 负载。在P1口作为输入口使用时,应先向P1口锁存地址(90H)写入全1,此时P1口引脚由内部上拉电阻拉成高电平。
P2口(P2.0~P2.7,21~28 脚):P2口是一个带内部上拉电阻的8 位准双向I/O口。P口每位能驱动4个LS 型TTL 负载。在访问片外EPROM/RAM 时,它输出高8 位地址。
P3口(P3.0~P3.7,10~17 脚):P3口是一个带内部上拉电阻的8 位准双向I/O口。P3口每位能驱动4个LS型TTL负载。P3口与其它I/O 端口有很大的区别,它的每个引脚都有第二功能,如下:
P3.0:(RXD)串行数据接收。
P3.1:(RXD)串行数据发送。
P3.2:(INT0#)外部中断0输入。
P3.3:(INT1#)外部中断1输入。
P3.4:(T0)定时/计数器0的外部计数输入。
P3.5:(T1)定时/计数器1的外部计数输入。
P3.6:(WR#)外部数据存储器写选通。
P3.7:(RD#)外部数据存储器读选通。
4.1.3 80C51单片机的中断系统
80C51系列单片机的中断系统有5个中断源,2个优先级,可以实现二级中断服务嵌套。由片内特殊功能寄存器中的中断允许寄存器IE控制CPU是否响应中断请求;由中断优先级寄存器IP安排各中断源的优先级;同一优先级内各中断同时提出中断请求时,由内部的查询逻辑确定其响应次序。
4.1.4 80C51单片机的定时/计数器
在单片机应用系统中,常常会有定时控制需求,如定时输出、定时检测、定时扫描等;也经常要对外部事件进行计数。80C51单片机内集成有两个可编程的定时/计数器:T0和T1,它们既可以工作于定时模式,也可以工作于外部事件计数模式,此外,T1还可以作为串行口的波特率发生器。
4.2 芯片DS18B20的说明
4.2.1 DS18B20 的主要特性
(1)适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电
(2)独特的单线接口方式,DS18B20 在与微处理器连接时仅需要一条口线即可实现微处理与DS18B20 的双向通讯
(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,同事科传送SRC检验码,菊友极强的抗干扰校正能力。
(9)负压特性:电源极性接反时芯片不会因发热而烧毁,但不会正常工作。
4.3 液晶显示器1602LCD的说明
4.3.1接口信号说明:
4.3.2控制命令表:
4.3.3液晶显示简介
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,下图是1602的内部显址。
图4—1
① 液晶显示原理
液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。
②液晶显示器的分类
液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。除了黑白显示外,液晶显示器还有多灰度有彩色显示等。如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。
③字符的显示
用LCD显示一个字符时比较复杂,因为一个字符由6×8或8×8点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。这样一来就组成某个字符。但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。
5、软件方案设计
5.1 程序流程图
图5-1 总流程图
5.2 读出温度子程序
读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,校验有错时不进行温度数据的改写。如图5-2示
5-2读出温度子程序流程图
5.3温度转换命令子程序
温度转换命令子程序主要是发温度转换开始命令,当采用12位分辨率时转换时间约为750ms,在本程序设计中采用1s显示程序延时法等待转换的完成。如图5-3所示:
5.4 计算温度子程序
计算温度子程序将RAM中读取值进行BCD码的转换运算,并进行温度值正负的判定,如图5-4所示。
图5-4计算温度子程序流程图
5.5 显示数据刷新子程序
显示数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操作,当最高显示位为0时将符号显示位移入下一位。
图5—5
6、调试
6.1、软件仿真
通过查找众多资料,终于确定了整个设计方案,即使用80c51单片机和DS18B20作为本设计的核心芯片。有了以上资料和基本电路图,经过一段时间的看图分析,终于弄明白了大概的数字温度计原理,这才开始软件仿真。
6.2.硬件调试
买回所需元器件后,我便开始了焊接。因为有了以前多个课程设计的基础,我的焊接技术还算不错,经过差不多整整一天时间的焊接,实物的雏形基本形成。接下来是程序的烧写,通过Keil C51编程软件将程序烧写进单片机,但结果不如人意,没有显示灯能亮,更无法实现充电功能。我对其进行硬件方面的检查,如焊点的漏焊虚焊,又对程序进行了分析,但最终没能解决问题,本次课程设计基本以失败告终。相信给我更多的时间和精力,我能把它做好。
7、技术小结
本次课设的任务是采用AT89C51单片机作控制器,温度传感器选用DS18B20来设计数字温度计,系统由3个模块组成:主控制器、测温电路及显示电路。主控制器由单片AT89C2051实现,测温电路由温度传感器DS18B20实现,显示电路由4位LED数码管直读显示。
通过本次课设使我学会了很多东西,通过自己找材料,向老师答疑,与同学讨论,自己修改,研究,最终完成本次课设。在这个过程中,不但使我对单片机课程所学的知识有了更深入的了解,而且还培养了我的自学能力。有些不懂的问题通过向老师请教得到解决,使我受益匪浅。课设的过程是艰辛的,但是收获是巨大的。首先,我再一次的加深巩固了对已有的知识的理解及认识;其次,我第一次将课本知识运用到了实际设计,使得所学知识在更深的层次上得到了加深。再次,因为这次课程设计的确在某些方面存有一定难度,这对我来讲都是一种锻炼,培养了我自学、查阅搜集资料的能力;再有,计算操作工程中,我们曾经面临过失败、品味过茫然,但是最终我还是坚持下来了,这就是我意志、耐力和新年上的胜利,在今后的日子里,它必将成为我的宝贵财富。
8、参考文献
1、 杨素行著.模拟电子技术基础(第二版) .北京:高等教育出版社,2006.
2、 阎石著.数字电子技术基础(第五版) .北京:高等教育出版社,2006.
3 、李全利,仲伟峰,徐军著.单片机原理及应用.北京:清华大学社,2006.
4 、何立民著.单片机高级教程.北京:北京航空航天大学出版社,2000.
5、 杨路明著.C语言程序设计教程(第2版) .北京:北京邮电大学出版社,2005.
6、 马忠梅,籍顺心,张凯等著.单片机的C语言应用程序设计(第4版) .北京:北京航天航空大学出版社,2007.
7、白驹珩,雷晓平著.单片计算机及其应用.成都:电子科技大学出版社,1997.
8、谭浩强著.程序设计与开发技术.北京:清华大学出版社,1991.
9、 钟富昭著.8051单片机典型模块设计与应用.北京:人民邮电出版,2007.
10、 于永,戴佳,常江著.51单片机C语言常用模块与综合系统设计实例精讲.北京:电子工业出版社,2007.
11、梁翎著.C语言程序设计实用技巧与程序实例.上海:上海科普出版社,1998.
9.附录
9.1附录一:程序清单
#include <AT89X51.H>
#include <intrins.h>
#include<absacc.h>
#define uint unsigned int
#define unchar unsigned char
unchar templ,temph,i,y,z,n;
unchar a,b;//LCD的变量
unchar sign=0;//标志变量
bit k; //判断正负变量
sbit dq=P3^5;
sbit rs=P2^0;//LCD显示的定义取值
sbit rw=P2^1;
sbit e=P2^2;
sbit bf=P0^7;
sbit DQ=P2^5;
//键盘定义
sbit read=P3^0;
sbit incH=P3^2;
sbit desH=P3^3;
sbit reset=P3^4;
//蜂鸣器
sbit BUZZER=P2^6;
float t4,t5,t6,t7,tt;//温度转换的变量
uint tp;
unchar temperature,Htemp,Ltemp;
unchar D1,D2,D3;
uint D4,D5,D6,D9,D7,D8;
unchar code dis1[]={"0123456789"};
unchar code dis2[]={"temp:"};
unchar code dis3[]={"WARN"};
unchar code dis4[]={"Htemp:"};
unchar code dis5[]={"working"};
unchar code dis6[]={"Ltemp:"};
bit flag_1820_1;
bit flag_1820_2;
void delay_ms(unsigned char time);
void ledshow(void);
void keypress(void);
void init(void);
void gettemp();
void init1820(void);
void write1820(unchar);
unsigned char read1820(void);
void delay_us(unchar);
void delay3(unchar);
/* 延时*/
void delay(uint t)
{ uint i;
while(t--)
{ for(i=0;i<125;i++)
{}
}
}
//LCD显示函数
void delay1(unchar time)
{ unchar n;
n=0;
while(n<time)
{n++;}
return;
}
void delay3(unchar x)
{ for(y=x;y>0;y--)
for(z=x;z>0;z--);
}
unchar testBF()
{ bit result;
rs=0;rw=1;e=1;
_nop_();_nop_();_nop_();_nop_();
result=bf;e=0;
return result;
}
void writecmd(unchar ZL)
{ while(testBF()==1);
rs=0;rw=0;e=0;
_nop_();_nop_();
P0=ZL;e=1;
_nop_();_nop_();_nop_();_nop_();
e=0;
}
void pos(unchar pos)
{ writecmd(pos|0x80);
}
void writedate(unchar date)
{while(testBF()==1);
rs=1;rw=0;e=0;
_nop_();_nop_();
P0=date;e=1;
_nop_();_nop_();_nop_();_nop_();
e=0;
}
void init()
{ delay3(20);
writecmd(0x38);
delay3(30);
writecmd(0x0d);
delay3(30);
writecmd(0x06);
delay3(30);
writecmd(0x01);
delay3(30);
}
//键盘程序
//主程序
void main(void)
{
TMOD=0x01;
TH0=50000/256;
TL0=50000%256;
Htemp=124;Ltemp=-24;
P3=0xFF;
init();
if(sign==0)
{EA=1;TR0=1;ET0=1;
EX0=0; //关闭外部中断0
EX1=0; //关闭外部中断1
while(1)
{
if(read==0)
{
delay3(2000);
if(read==0)
{sign++;}
}
}
}
if(sign==1)
{
BUZZER=1; //关闭蜂鸣器
EX0=1; //开启外部中断0
EX1=1; //开启外部中断1
init();
pos(0);
for(i=0;i<6;)
{ writedate(dis4[i]);i++;
}
D6=Htemp%10;
D7=Htemp%100/10;
D8=Htemp/100;
pos(0x6);
writedate(dis1[D8]);
writedate(dis1[D7]); }
if(sign==2)
{BUZZER=1; //关闭蜂鸣器
EX0=1; //开启外部中断0
EX1=1; //开启外部中断1
init();
pos(0);
for(i=0;i<6;)
{ writedate(dis6[i]);i++;}
D6=Htemp%10;
D7=Htemp%100/10;
D8=Htemp/100;
pos(0x6);
writedate(dis1[D8]);
writedate(dis1[D7]);
writedate(dis1[D6]);
}
if(sign>2)
{ sign=0;}
}
//中断程序
void int0(void) interrupt 0
{
EX0=0; //关外部中断0
if(desH==0&&sign==1)
{
Htemp--;
if(Htemp<Ltemp)
Htemp=Ltemp;
}
else if(desH==0&&sign==2)
{
Ltemp--;
}
}
/*****外部中断1服务程序*****/
void int1(void) interrupt 2
{
EX1=0; //关外部中断1
if(incH==0&&sign==1)
{
Htemp++;
}
else if(incH==0&&sign==2)
{
Ltemp++;
if(Ltemp>Htemp)
Ltemp=Htemp;
}
}
//定时器T0服务程序
void isr_t0(void) interrupt 1
{ TH0=50000/256;
TL0=50000%256;
TMOD=0x10;
TH1=50000/256;
TL1=50000%256;
gettemp();
delay(50);
if (tp<Htemp)
{ BUZZER=1;
pos(0x04);
for(i=0;i<7;)
{
writedate(dis5[i]);
i++;
}
pos(0x40);
for(i=0;i<5;)
{writedate(dis2[i]);
i++;}
D1=(unchar)(tp%10);
D2=(unchar)(tp%100/10);
D3=(unchar)(tp/100);
D4=(uint)(tt*10);
D5=((uint)(tt*100))%10;
if(k==1)
{pos(0x46);
writedate('-');}
else
{pos(0x46);
writedate();}
pos(0x47);
writedate(dis1[D3]);
writedate(dis1[D2]);
writedate(dis1[D1]);
writedate('.');
writedate(dis1[D4]);
writedate(dis1[D5]);
writedate(0xdf);
writedate('C');
}
else
{ init();
pos(0x04);
for(i=0;i<4;)
{
writedate(dis3[i]);
i++;}
BUZZER=0;
}
}
//DS18B20读取温度
void gettemp()
{
init1820();
write1820(0xcc);
write1820(0x44);
init1820();
write1820(0xcc);
write1820(0xbe);
templ=read1820();//低8位(其中的第四位是小数点后的)
temph=read1820();//高8位(其中前五位是符号值)
z=temph;//把符号位留下判断正负
k=(bit)(z>>7);
if(k==1) //负数就取反加一
{ templ=~templ;
templ=templ+1;
temph=~temph;
}
else
{templ=templ;
temph=temph;}
n=templ;
y=n&0x01;
t7=y*0.0625;
n>>=1;
y=n&0x01;//小数点最后的数
t4=y* 0.125;
n>>=1;
y=n&0x01;
t5=y* 0.25;
n>>=1;
y=n&0x01;
t6=y*0.5;
tt=t4+t5+t6+t7;
init1820();
tp=temph*256+templ;
temperature=tp;
tp=tp>>4;
}
//1820初始化
void init1820()
{
DQ = 1; _nop_();
DQ = 0;
delay_us(125); //延时510us,
delay_us(125);
DQ = 1;
delay_us(15);
while(DQ)
{ _nop_(); }
delay_us(60);
DQ = 1;
}
//******write********
void write1820(unchar a)
{
unchar i;
for(i=0;i<8;i++)
{if(a & 0x01) //低位在前;
{DQ = 0;
_nop_();_nop_();_nop_();
DQ = 1; }
else
DQ = 0;
_nop_();_nop_();_nop_();
delay_us(30);
DQ = 1;
_nop_();
a >>= 1;
}
}
//*******read************
unsigned char read1820(void)
{
unsigned char i;
unsigned char tmp=0;
DQ = 1; _nop_();
for(i=0;i<8;i++)
{
tmp >>= 1;
DQ = 0;
_nop_();
DQ = 1;
delay_us(2);
_nop_();
if(DQ)
tmp |= 0x80;
delay_us(30);
DQ = 1; _nop_();
}
return tmp; }
void delay_us(unchar a)
{
while(--a);
}
void delay_ms(unchar a)
{
unchar i,j;
for(i=0;i<a;i++)
for(j=0;j<200;j++)
{
_nop_();
_nop_();
}
}
9.2 附录二:电路图