搜档网
当前位置:搜档网 › 太阳能热水器论文

太阳能热水器论文

doc文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。
教学单位 学生学号
孝感学院 061234142
本科毕业论文(设计) 本科毕业论文(设计)


太阳能热水器控制器设计
学生姓名 专业名称 指导教师
2010 年 4
月 26 日
太阳能热水器控制系统设计
摘要:该设计以单片机 AT89S52 为核心,结合单线数字温度传感器 DS18B20 与 液晶显示器 12864,设计一种数字化、智能化的太阳能热水器控制系统。该系统 由主控芯片模块、DS18B20 温度检测模块、LCD 显示模块、水位检测模块、键 盘控制模块、报警模块和电磁阀控制模块组成。给出了各个模块地结构及其工作 原理、系统硬件原理图、程序流程图和部分源程序,并结合理论设计进行实物制 作。此系统解除了热水器上水时需人工守候和过量溢水的问题,达到了省时、环 保、节水的目的。该系统与传统的机械式控制系统相比较,具有结构简单,抗干 扰能力强,使用方便等特点。 关键词:单片机 AT89S52; 温度传感器 DS18B20; 智能控制
Solar water heater control system
Abstract:This design takes monolithic integrated circuit AT89S52 as the core, : combining the single digital temperature sensor DS18B20 and LCD 12864, to design a kind of digital, intelligent control system of solar energy water heater.The system consists of main chip module, DS18B20 temperature detection module, LCD display module, the water level detection module, keyboard control module, alarm module and solenoid valve control module. Given to the structure of each module and its working principle, system hardware, schematics, process flow charts, and some source code, and theoretical design of physical production. The system needs to lift the water heater in Sheung Shui and excessive artificial overflow problem waiting to reach a time-saving, environmental protection, water conservation purposes. The system with the traditional mechanical control systems compared to simple structure, strong anti-interference ability, easy to use and so on. Keywords:Microcontroller AT89S52;Transducer DS18B20;Intelligence control
I


1 引言 引言…… 1 2 系统设计要求和方案论证 …… 1 2.1 系统的设计要求 …… 2 2.2 系统设计方案与比较 ……2 3 系统硬件电路设计 …… 3 3.1 主控芯片 AT89S52 单片机 …… 3 3.2 温度检测模块 …… 7 3.3 LCD 液晶显示模块 …… 11 3.4 水位检测模块 …… 16 3.4.1 ADC0809 芯片 …… 16 3.4.2 水位接口电路…… 19 3.5 键盘控制模块 …… 20 3.6 报警模块 …… 20 3.7 电磁阀控制模块 …… 21 3.8 整体电路图 …… 22 4 系统软件设计 …… 23 5 系统硬件调试 …… 24 5.1 自动与手动上水测试 …… 25 5.2 水温和

水位显示测试 …… 25 6 结束语 结束语…… 25 [参考文献] …… 27 参考文献] 附 录…… 28 致 谢…… 44
II
1 引言
由于近年来常规能源的紧缺, 开发和利用太阳能这样的绿色能源有着重要的 意义, 它既是可再生能源, 也不会污染环境。 太阳能热水器也是其中的一大产业, 太阳能热水器时存在的问题:不可缺水,空晒情况下上水会爆炸;春、秋天,水 温升高蒸发,造成热能损失;冬天水温不够,须用电等等。现在人们对家用电器 的要求越来 趋向数字化、自动化、智能化。采用太阳能热水器水温水位测控系 统,能解决上述问题。使用户省心,使用方便,智能操控,用户不必作任何操作。 随着中国经济的快速发展,国内对能源的需求成几何倍数上升。从国际能源 环境来看, 形式并不乐观, 世界能源危机日趋严重, 所以中国经济要想继续高速、 健康的发展,摆脱能源这一“瓶颈”已经变得刻不容缓。太阳能这一取之不尽、 用之不完的新型环保可再生能源必然会成为承担这一重任的首选, 所以我国太阳 能热转换产业的发展前景是非常广阔的,绿色能源代替传统能源,将成为建设和 谐社会的必经之路! 本系统是针对上述问题设计的温度控制系统,由 AT89S52 单片机和一些外 围设备,充分运用软件和硬件结合的方法实现了当前水位高度显示、水箱温度显 示,以及当水位下降到最低刻度线时自动上水三种主要功能。本系统可使用在水 池,锅炉,水塔等装置上,当水位下降到一定刻度值且大于最低水位值时,可由 人工使用按键来控制水泵立即上水,直至水位到达最高刻度。当水位下降到报警 刻度时,系统可通过自动上水使水位保持在一定的水位高度。每次上水的最大水 位值也可根据环境需要由人工自由设置,上水过程的自动控制省去人工守候环 节,节省了大量的人力,带来了工作效益。 从未来的发展来看,以投资少、无污染、节约能源、多功能、智能化为设计 目标,将会带来客观的经济效益。
2 系统设计要求和方案论证
设计要求是一个设计必须要求达到的目标或完成的目标, 而设计方案是一个
1
设计实现的重要途径,同样必不可少。 2.1 系统的设计要求 设计的系统可以实现当前水位高度、水箱温度的显示,以及当水位下降到报 警刻度时,系统可通过自动上水使水位保持在一定的水位高度。而且还可以人工 手动控制上水,每次上水的最大水位值也可根据环境需要由人工自由设置。 2.2 系统设计方案与比较 方案一:采用半导体逻辑器件构成的控制器,主要应用定时器构成。在此控 制方案里,定时器和加减

计数
器共同构成水位显示器。由于水温的变化具有未知 性,在水温检测电路里,利用热敏电阻测量的水温信号是模拟量,需要经过模/ 数转换成半导体逻辑器件能够识别的数字信号。这类控制电路过于庞大复杂,操 作也不方便,成本也较高。 方案二:采用可编程逻辑器件。结果简单的 PLC 控制成为首选。由于控制 电路简单,检测电路要求也不高,所以必然造成接口资源和内部资源的浪费,显 然不够经济。 方案三: 采用单片机为核心控制器的电路。 单片机电路结构简单、 成本低廉, 可靠性高,便于实现各个控制功能。水位由设置在水箱内的四个浮子式微动开关 获得的电信号检测,通过单片机处理送达显示电路显示当前水位。由于实际操作 的原因,本设计水位检测用滑动变阻器来代替,通过组织的改变来实现水位的改 变。然后通过模/数转换把信号输入到单片机,获得当前水位显示。水温检测由 单片机根据温度传感器(DS18B20)的操作指令和时序,读取温度,并送达显示 电路显示当前水温。本设计用三个按键来控制上水的水量。 从结构、经济、可操作性等方面来看,方案三都是最佳选择。方案三以单片 机 AT89S52 为核心控制器件,结合单线数字温度传感器 DS18B20 与液晶显示器 12864 和 DAC0809 等芯片,设计一种太阳能热水器智能控制系统。该系统原理 框图如图 1 所示。
2
键盘控制模块
温度检测模块
LCD 显示模块
单片机 AT89S52
水位检测模块
电磁阀控制模块
蜂鸣报警模块
图 1 系统原理框图 用户在使用热水器后,当水箱中水位下降到一定刻度值时,可通过人工使用 按键方法来控制电磁阀立即上水,水位达到的最高刻度也可以由按键设定。当水 位下降到低于刻度线 5L 时,单片机接受此信号并开始执行指令,报警电路工作, 同时电磁阀打开,水位不断升高,当达到最高水位 30L 时便给单片机发出中断请 求,此时电磁阀关闭,停止工作。设置的三个按键也可以实现人工上水的功能。 在上水过程中, 显示器 LCD 既可以显示水箱的水位值又可显示水箱内水的当 前温度,不仅直观方便,而且精确度高,实用性强。此系统解决了热水器上水时 需人工守候和过量溢水的问题,达到了省时、环保、节水的目的。加设的缺水报 警系统和液晶显示部分,使整个系统更实用,更趋向数字化、智能化。
3 系统硬件电路设计
该系统由主控芯片模块 AT89S52、DS18B20 温度检测模块、LCD 液晶显示 模块、水位检测模块、键盘控制模块、报警模块和电磁阀开关模块组成。下面分 别对各个模块作具体介绍。 3.1 主控芯片 AT89S

52 单片机[2]
AT89S52 是一种低功耗、高性能 CMOS 8 位微控制器,具有 8K 在系统可编
3
程 Flash 存储器。 使用 Atmel 公司高密度非易失性存储器技术制造, 与工业 80C51 产品指令和引脚完全兼容。片上 Flash 允许程序存储器在系统可编程,亦适于常 规编程器。在单芯片上,拥有灵巧的 8 位 CPU 和在系统可编程 Flash,使得 AT89S52 为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。 AT89S52 具有以下标准功能:8K 字节 Flash,256 字节 RAM,32 位 I/O 口 线,看门狗定时器,2 个数据指针,三个 16 位定时器/计数器,一个 6 向量 2 级 中断结构,全双工串行口,片内晶振及时钟电路。另外,AT89S52 可降至 8Hz 静态逻辑操作,支持 2 种软件可选择节点模式。空闲模式下,CPU 停止工作, 允许 RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM 内 容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为 止。 AT89S52 单片机采用 40 条引脚,双列直排的封装形式。在单片机的 40 条引 脚中,有 2 条专用于主电源的引脚,2 条外接晶振的引脚,4 条控制和其它电源 复用的引脚,32 条 I/O 引脚。图 2 是 AT89S52 引脚图。
图 2 AT89S52 单片机引脚图 下面分别具体说明这些引脚的名称和功能。 (1) 主电源引脚 Vcc 和 GND Vcc:接+5V 电源。 GND:接地。 (2) 时钟电路引脚 XTAL1 和 XTAL2 XTAL1:接外部晶振的一端。在单片机内部,它是反相放大器的输入端。该 放大器构成了片内振荡器。
4
XTAL2:接外部晶振的另一端。在单片机内部,接至上述振荡器的反相放大 器的输出端,振荡器的频率是晶体振荡频率。 在本设计中,XTAL1 和 XTAL2 端外接石英晶体作为定时元件,内部反相放 大器自激振荡,产生时钟。石英晶体的振荡频率为 12MHz,其原理图如图 3 所 示:
图 3 晶体振荡电路 (3) 控制信号引脚 RST、 ALE / PROG 、 PSEN 和 EA /Vpp RST:单片机上电后,只要在该引脚输入 24 个振荡周期宽度以上的高电平 就会使单片机复位。图 4 是复位电路图。在通电瞬间,电容 C 通过电阻 R 充电, RST 端出现正脉冲,用以复位。关于参数的选定,应保证复位高电平持续时间大 于 2 个机器周期。当采用晶振为 12MHz 时,可取C=10uF,R=10K 。
VCC
C R
10u 10k
图 4 复位电路图
ALE / PROG :地址锁存使能输出/编程脉冲输入端。当 CPU 在访问外部程
序存储器时,ALE 的输出作为外部锁存地址的低位字节的控制信号;当不访问 外部存储器程序期间,ALE 端仍以 1/6 的时钟振荡频率固定地输出脉冲。因此, 它可用作对外输出地时钟或用于定时。
PSEN :

外部程序存储
器读选通信号。CPU 在访问外部程序存储器期间,每
5
个机器周期中,PSEN 信号两次有效。 但在此期间, 每当访问外部数据存储器时, 这两次有效的 PSEN 信号不出现。 PSEN 端可以驱动 8 个负载 LSTTL。
EA /Vpp:外部访问允许/编程电源输入端。当 EA 输入高电平时,CPU 执行
程序,在低 4KB(0000H~0FFFH)地址范围内,访问片内程序存储器;在程序 将自动转向执行片外程序存储器的程序。 EA 当 计数器 PC 的值超过 4KB 地址时, 输入低电平时,CPU 仅访问片外程序存储器。 (4) 输入/输出(I/O)引脚 P0、P1、P2 和 P3 P0.0~P0.7:P0 口是一个 8 位漏极开路的双向 I/O 口。作为输出口,每位能 驱动 8 个 TTL 逻辑电平。对 P0 端口写“1”时,引脚用作高阻抗输入。当访问外 部程序和数据存储器时,P0 口也被作为低 8 位地址/数据复用。在这种模式下, P0 具有内部上拉电阻。在 flash 编程时,P0 口也用来接收指令字节;在程序校验 时,输出指令字节。程序校验时,需要外部上拉电阻。 P1.0~P1.7:P1 口是一个具有内部上拉电阻的 8 位双向 I/O 口,p1 输出缓 冲器能驱动 4 个 TTL 逻辑电平。 P1 端口写“1”时, 对 内部上拉电阻把端口拉高, 此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的 原因,将输出电流(IIL) 。此外,P1.0 和 P1.2 分别作定时器/计数器 2 的外部计 数输入(P1.0/T2)和时器/计数器 2 的触发输入。在 flash 编程和校验时,P1 口 接收低 8 位地址字节。 P2.0~P2.7:P2 口是一个 8 位准双向 I/O 口。在 CPU 访问外部存储器时, 它输出高 8 位地址。在对 EPROM 编程和程序验证时,它输入高 8 位地址。P2 口能驱动 4 个 LSTTL 负载。 P3.0~P3.7:P3 口是一个 8 位准双向 I/O 口。它是一个复用功能口。作为第 一功能使用时,为普通 I/O 口,其功能和操作方法与 P1 口相同。作为第二功能 使用时,各引脚的定义如表 1 所示。P3 口的每一条引脚均可独立定义为第一功 能的输入输出或第二功能。 实际在使用中, 总是先按需要优先选用它的第二功能, 剩下不用的才作为第一功能口线使用。P3 口能驱动 4 个 LSTTL 负载。
6
表 1 P3 各口线的第二功能表 口线 P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7 第二功能 RXD(串行输入) TXD(串行输出) INT0(外部中断 0) INT1(外部中断 1) T0(定时器 0 的外部输入) T1(定时器 1 的外部输入) WR(外部数据存储器写选通道) RD(外部数据存储器读选通道)
3.2 温度检测模块 传感器属于信息技术的前沿尖端产品, 尤其是温度传感器被广泛用于工农业 生产、科学研究和生活

等领域,数量高居各种传感器之首
。近百年来,温度传感 器的发展大致经历了以下三个阶段: 1) ( 传统的分立式温度传感器 (含敏感元件) ; (2)模拟集成温度传感器/控制器; (3)智能温度传感器。目前,国际上新 型温度传感器正从模拟式向数字式、由集成式向智能化、网络化的方向发展。 温度传感器的主要特点是功能单一、测温误差小、价格低廉、响应速度快、 传输距离远、体积小、微功耗等,适合远距离测温、控制,不需要进行非线性校 准,外围电路简单。太阳能热水器温度传感器有很多种,本设计可选用具有负温 度系数的热敏电阻来测水温,热敏电阻与普通电阻不同,它具有负的温度特性, 当温度升高时,电阻值减小,它的应用是为了感知温度。由于取材原因,本设计 选用了型号为 DS18B20 的温度传感器,因为它独特的单线接口,且具有精准度 高、抗干扰能力强等优点,实验中用它来代替温度传感器。 DS18B20 的简介[14][15] Dallas 半导体公司的数字化温度传感器 DS18B20 是世界上第一片支持“一线 总线”接口的温度传感器,在其内部使用了在板(ON-BOARD)专利技术。全部
7
传感元件及转换电路集成在形如一只三级管的集成电路内。DS18B20 具有微型 化、低功耗、高性能、抗干扰能力强、可组网等优点,测温分辨率高,为 9~12 位,精度为 0.5℃。DS18B20 可直接将温度转化成串行数字信号,因此特别适合 和单片机配合使用,直接读取温度数据。DS18B20 温度与数字对应表如表 2 所 示。目前 DS18B20 数字温度传感器已经广泛应用于恒温室、粮库、计算机机房 温度监控及其他各种温度测控系统中。 表 2 DS18B20 温度与数字对应表 温度 ℃ +125 +85 +25.0625 +10.125 +0.5 0 -0.5 -10.125 -25.0625 -55 数据输出(二进制) 0000 0111 1101 0000 0000 0101 0101 0000 0000 0001 1001 0001 0000 0000 1010 0010 0000 0000 0000 1000 0000 0000 0000 0000 1111 1111 1111 1000 1111 1111 0101 1110 1111 1110 0110 1111 1111 1100 1001 0000 数据输出(十六进制) 07D0h 0550h 0191h 00A2h 0008h 0000h FFF8h FF5Eh FE6Eh FC90h
(1) DS18B20 的引脚图和封装如图 5 所示
图 5 DS18B20 的引脚图和封装
8
(2) DS18B20 的引脚介绍 DQ 为数字信号输入/输入端 GND 为电源地 VDD 为外接供电电源输入端(在寄生电源接线方式时接地) (3) DS18B20 的主要特性 独特的单线接口仅需一个端口引脚 进行通讯 每个器件有唯一的 64 位的序列号存 储在内部存储器中 简单的多点分布式测温应用 可通过数据线供电。供电范围为 3.0V~5.5V 测温范围为-55~+125℃(-67~+257℉) ,在-10~+85℃范围内精 确度为±5℃ 温度计分辨率可以

被使用者选择为 9~12 位 最多在 750ms 内将温度转换为 12
位数字 用户可定义的非易失性温度报警设置 报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件 应用包括温度控制、工业系统、消费品、温度计或任何热感测系统 (4) DS18B20 内部结构主要由四部分组成: 位光刻 ROM、 64 温度传感器、 非挥发的温度报警触发器 TH 和 TL、配置寄存器。DS18B20 的内部结构如图 6 所示
图 6 DS18B20 的内部结构框图
9
DS18B20 使用一根单线端口进行通讯。 在单线端口的条件下, 要先建立 ROM 操作协议,才能进行存储和控制操作。光刻 ROM 中的 64 位序列号是出厂前就 被光刻好的,是 DS18B20 的地址序列号,使每个 DS18B20 都有各不相同,这样 就可以在一根总线上挂多个 DS18B20 了。 其中的温度传感器完成对温度的测量。 内 部 的 存 储 器 , 包 括 一 个 高 速 暂 存 RAM 和 一 个 非 易 失 性 的 可 电 擦 除 的 EEPRAM,后者存放高温度和低温度触发器 TH,TL 和结构寄存器。配置存储器 则主要用来设置它的工作模式和分辨率。 DS18B20 测温原理如图 7 所示。图中低温度系数晶振的振荡频率受温度影 响很小,用于产生固定频率的脉冲信号送给计数器 1。高温度系数晶振随温度变 化其振荡率明显改变,所产生的信号作为计数器 2 的脉冲输入。计数器 1 和温度 寄存器被预置在-55℃所对应的一个基数值。 计数器 1 对低温度系数晶振产生的 温度寄存器的值将加 1, 脉冲信号进行减法计数, 当计数器 1 的预置值减到 0 时, 计数器 1 的预置将重新被装入, 计数器 1 重新开始对低温度系数晶振产生的脉冲 信号进行计数,如此循环直到计数器 2 计数到 0 时,停止温度寄存器值的累加, 此时温度寄存器中的数值即为所测温度。 7 中的斜率累加器用于补偿和修正测 图 温过程中的非线性,其输出用于修正计数器 1 的预置值。
斜率累加器 预置 比较
低温度系数晶振
计数器 1
预置
=0
温度寄存器
高温度系数晶振
计数器 2
=0
图 7 DS18B20 的工作原理 DS18B20 工作主程序流程图如图 8 所示。
10
开始
DS18B20 复位
读取温度
数据转换
显示
结束
图 8 DS18B20 主程序流程图 DS18B20 单线通信功能是分时完成的,它有严格的时隙概念。因此系统对 DS18B20 的各种操作必须按协议进行。操作协议为:初始化 DS18B20(发复位 脉冲)→发 ROM 功能命令→发存储器作命令→处理数据。 DS18B20 可编程温度传感器采用 3 脚 PR-35 封装,其中 GND 为接地线, DQ 为数据输入输出接口,通过一个较小阻值的上拉电阻与单片机相连。VCC 为 电源接口,既可由数据线提供

电源,又可由外部提供电源,范
围可为 3.0~5.5V, 本系统使用外部电源供电。 3.3 LCD 液晶显示模块[9] 液晶屏显示模块与数码管相比,它显得更为专业、漂亮。液晶显示屏以其微 功耗、体积小、显示内容丰富、超薄轻巧、使用方便等诸多优点,在通讯、仪器 仪表、电子设备、家用电器等低功耗应用系统中得到越来越广泛的应用,使这些 电子设备的人机界面变得越来越直观形象,目前已广泛应用于电子表、计数器、 IC 卡电话机、液晶电视机、便携式电脑、掌上型电子玩具、复印机、传真机等 许多方面。 12864 液晶是指这种液晶有 64 行,每行有 128 个点。要显示一个完整的汉 字,需要 16*16 的点阵,即要显示一个汉字需要 16 行,每行有 16 个点.而显示 一个字符只需要 8*8 点阵(或者 5*7 点阵)等。这样 12864 液晶可以显示 4 行汉
11
字,每行能显示 8 个汉字。如果显示字符的话,每行能显示 16 个字符。 本实验采用 TS12864-3 型液晶,这种液晶自带汉字库,可直接显示汉字,采 用的驱动电路是 ST7290。其管脚说明如表 3 所示。 管脚说明 表 3 TS-12864-3管脚说明 管脚 管脚号 1 2 3 16 18 4 5 6 7 8 9 10 11 具体指令介绍: 1、清除显示 CODE: RW L RS DB7 L L DB6 L DB5 L DB4 L DB3 L DB2 L DB1 L DB0 L 管脚符号 GND VDD NC RS WR E DB0~DB7 PSB RST LED+ LED管脚功能描述 电源地 电源电压+5V 无连接 高:数据/低:指令 高:读/低:写 使能端 数据线 控制模式 系统复位 背光电源,+5V 背光电源,0V
功能:清除显示屏幕,把 DDRAM 位址计数器调整为“00H”。 2、地址归位 CODE RW L RS DB7 L L DB6 L DB5 L DB4 L DB3 L DB2 L DB1 H DB0 XL
功能:把 DDRAM 位址计数器调整为“00H”,游标回原点,该功能不影响显示 DDRAM。 3、地址归位 CODE RW RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
12
L
L
L
L
L
L
L
H
I/D
S
功能:把 DDRAM 位址计数器调整为“00H”,游标回原点,该功能不影响显示 DDRAM 功能;执行该命令后,所设置的行将显示在屏幕的第一行。显示起始行 是由 Z 地址计数器控制的,该命令自动将 A0-A5位地址送入 Z 地址计数器,起 始地址可以是0-63范围内任意一行。Z 地址计数器具有循环计数功能,用于显示 行扫描同步,当扫描完一行后自动加一。 4、显示状态 开/关 CODE RW L RS DB7 L L DB6 L DB5 L DB4 L DB3 H DB2 D DB1 C DB0 B
功能:D=1:整体显示 ON 5、游标或显示移位控制 CODE RW L RS DB7 L L
C=1:游标 ON
B=1:游标位置 ON
DB6 L
DB5 L
DB4 H
DB3 S/C
DB2 R/L
DB1 X
DB0 X
功能:设定游标的移动与显示的移动控制位,这个指令并不改变 DDRAM 的内 容。 6、功能设定 CODE RW L RS DB7 L L DB6 L DB5 H DB4 DL DB3 X DB2 0 RE 功能:D

L=1(必须设为1) 作 7、设定 CGRAM 位址 CODE RW L RS DB7 L L DB6 H DB5 DB4 DB3 AC3 DB2 AC2 DB1 AC1 DB0 AC0 RE=1:扩充之立即加动作 RE=0:基本指令集动 DB1 X DB0 X
AC5 AC4
功能:设定 CGRAM 位址到位址计数器(AC). 8、设定 DDRAM 位址 CODE RW L RS DB7 L H DB6 AC6 DB5 DB4 DB3 AC3 DB2 AC2 DB1 AC1 DB0 AC0
AC5 AC4
功能:设定 DDRAM 位址到位址计数器(AC).
13
9、读取忙碌状态(BF)和位址 CODE RW L RS DB7 H BF DB6 AC6 DB5 DB4 DB3 AC3 DB2 AC2 DB1 AC1 DB0 AC0
AC5 AC4
功能:读取忙碌状态(BF)可以确认内部动作是否完成,同时可以读出位址计 数器(AC)的值。 10、写资料到 RAM CODE RW H RS DB7 L D7 DB6 D6 DB5 D5 DB4 D4 DB3 D3 DB2 D2 DB1 D1 DB0 D0
功能:写入资料到内部的 RAM(DDRAM/CGRAM/TRAM/GDRAM) 。 11、读出 RAM 的值 CODE RW H RS DB7 H D7 DB6 D6 DB5 D5 DB4 D4 DB3 D3 DB2 D2 DB1 D1 DB0 D0
功能:从内部 RAM 读取资料(DDRAM/CGRAM/TRAM/GDRAM) 。 12、待命模式(12H) CODE: RW L RS DB7 L L DB6 L DB5 L DB4 L DB3 L DB2 L DB1 L DB0 H
功能:进入待命模式,执行其他命令都可终止待命模式。 13、卷动位址或 IRAM 位址选择(13H) CODE: RW L RS DB7 L L DB6 L DB5 L DB4 L DB3 L DB2 L DB1 H DB0 SR
功能:SR=1:允许输入卷动位址 14、反白选择(14H) CODE: RW L RS DB7 L L DB6 L
SR=0:允许输入 IRAM 位址
DB5 L
DB4 L
DB3 L
DB2 H
DB1 R1
DB0 R0
功能:选择4行中的任一行作反白显示,并可决定反白与否。 15、睡眠模式(015H) CODE: RW L RS DB7 L L DB6 L DB5 L DB4 L DB3 H DB2 SL DB1 X DB0 X
功能:SL=1:脱离睡眠模式
SL=0:进入睡眠模式
14
16、扩充功能设定(016H) CODE: RW L RS DB7 L L DB6 L DB5 H DB4 H DB3 X DB2 1 RE 功能:RE=1:扩充指令集动作 G=1:绘图显示 ON RE=0:基本指令集动作 G=0:绘图显示 OFF DB1 G DB0 L
17、设定 IRAM 位址或卷动位址(017H) ) CODE RW L RS DB7 L L DB6 H DB5 DB4 DB3 AC3 DB2 AC2 DB1 AC1 DB0 AC0
AC5 AC4
功能:SR=1:AC5-AC0为垂直卷动地址 18、设定绘图 RAM 位址(018H) CODE RW L RS DB7 L H DB6 AC6 DB5
SR=0:AC3-AC0为 ICON IRAM 地址
DB4
DB3 AC3
DB2 AC2
DB1 AC1
DB0 AC0
AC5 AC4
功能:设定 CGRAM 地址到地址计数器(AC) 。 液晶显示模块与单片机连接主要考虑以下三点: 1. 单片机若为 CMOS 芯片,则不用加总线驱动器等电平转换电路;若为 TTL 芯片则必须配电平转换电路。 2. 模块读/写控制线为单选,对读、写控制线分开的单片机,必须加读、写 信号转换电路。 3. 根据对模块确定的编码地址,选择对应的译码电路。 本系统的显示电路如图 9 所示:
15
图 9 显示电路 3.4 水位检测模块 水位检测模块中需要水位传感器将水位的变化信号传递给单片机, 通过
单片 机来控制电磁阀上水还是不上水

。由于各种原因,本设计用滑动变阻器来代替水 位检测器,通过阻值的变化来形象的代替水位的变化。因为阻值的变化是模拟信 号,而输入单片机的信号是数字信号,因此就要用到 A/D 转换,将模拟信号转 换为数字信号输入到单片机中,实现水位的控制。 3.4.1 ADC0809 芯片 本设计用到的 A/D 转换芯片是 ADC0809。ADC0809 是采样分辨率为 8 位 的、以逐次逼近原理进行模/数转换的器件。其内部有一个 8 通道多路开关, 它可以根据地址码锁存译码后的信号,只选通 8 路模拟输入信号中的一个 进行 A/D 转换。图 10 为 ADC0809 的引脚图。
16
图 10 ADC0809 的引脚图 ADC0809 的内部逻辑结构如图 11 所示。由图可见,ADC0809 由 8 位模拟 开关、SAR8 位逐次逼近式 A/D 转换器、地址锁存器、控制和时序电路及输出锁 存器组成。
图 11 ADC0809 的结构框图 对 ADC0809 主要信号引脚的功能说明如下: IN7~IN0:模拟量输入通道。 ALE:地址锁存允许信号。对应 ALE 上跳沿,A、B、C 地址状态送入地址 锁存器中。 START:转换启动信号。START 上升沿时,复位 ADC0809;START 下降沿
17
时启动芯片,开始进行 A/D 转换;在 A/D 转换期间,START 应保持 低电平。 本信号有时简写为 ST。 A、B、C:地址线。 通道端口选择线,A 为低地址,C 为高地址,引脚图 中为 ADDA,ADDB 和 ADDC。 CLK:时钟信号。ADC0809 的内部没有时钟电路,所需时钟信号由外界提 供,因此有时钟信号引脚。通常使用频率为 500KHz 的时钟信号 EOC:转换结束信号。EOC=0,正在进行转换;EOC=1,转换结束。使用中该 状态信号即可作为查询的状态标志,又可作为中断请求信号使用。 D7~D0:数据输出线。为三态缓冲输出形式,可以和单片机的数据线直接 相连。D0 为最低位,D7 为最高 OE:输出允许信号。用于控制三态输出锁存器向单片机输出转换得到的数 据。OE=0,输出数据线呈高阻;OE=1,输出转换得到的数据。 Vcc:+5V 电源。 Vref——参考电源参考电压用来与输入的模拟信号进行比较,作为逐次逼近 的基准。其典型值为+5V(Vref(+)=+5V, Vref(-)=-5V). A/D 转换后得到的数据应及时传送给单片机进行处理。 数据传送的关键问题 是如何确认 A/D 转换的完成,因为只有确认完成后,才能进行传送。为此可采 用下述三种方式。 (1)定时传送方式 对于一种 A/D 转换来说,转换时间作为一项技术指标是已知的和固定的。 例如 ADC0809 转换时间为 128μs,相当于 6MHz 的 MCS-51 单片机共 64 个机器 周期。可据此设计一个延时子程序,A/D 转换启动后即调用此子程序,延迟时间 一到,转换肯定已经完成了,接着就可
进行数据传

送。 (2)查询方式 A/D 转换芯片由表明转换完成的状态信号, 例如 ADC0809 的 EOC 端。 因此 可以用查询方式,测试 EOC 的状态,即可确认转换是否完成,并接着进行数据 传送。 (3)中断方式 把表明转换完成的状态信号(EOC)作为中断请求信号,以中断方式进行数
18
据传送。 3.4.2 水位接口电路 由于在仿真软件中无法对真实水位进行仿真。 所以本设计用一个滑动变阻器 来代替水位传感器,阻值的变化代表水位的变化。水位接口电路如图 12 所示。
图 12 ADC0809 和单片机的连接图
19
3.5 键盘控制模块 在单片机应用系统中,通常应具有人机对话功能,能随时发出各种控制命令 和数据输入以及报告应用系统的运行状态与运行结果。 键盘是操作人员可以通过 按键输入数据和命令进行功能设置,它是本系统中不可缺少的输入设备。键盘由 一组按键开关所组成。按键开关所组成的键盘可以分为两种形式:独立式按键和 矩阵式按键。本设计由于按键较少,使用的是独立式按键。独立式按键电路配置 灵活,软件结构简单。当功能键不是很多时,采用该种方式比较合适。独立式按 键是指直接用 I/O 口线构成的单个按键电路。每个独立式按键单独占有一根 I/O 口线。每根 I/O 口线的工作状态不会影响其他 I/O 口线的工作状态。 本系统设计了 3 个键,所用的 3 个键采用直接式接法。3 个按键可设置 3 个 不同档的水位刻度:按键 K1 为 10L 水位,当按下 K1 时,电磁阀开始工作,水 箱开始上水,直至水位达到 10L 时,电磁阀关闭,停止上水;按键 K2 为 20L 水 位,当按下 K2 时,电磁阀开始工作,水箱开始上水,直至水位达到 20L 时,电 磁阀关闭,停止上水;按键 K3 为 30L 水位,当按下 K3 时,电磁阀开始工作, 水箱开始上水,直至水位达到 30L 时,电磁阀关闭,停止上水。 3.6 报警模块 本设计的报警模块是由单片机 I/O 口 P2.6 口输出低电平驱动蜂鸣器报警。 蜂鸣器是一种一体化结构的电子讯响器, 采用直流电压供电, 广泛应用于计算机、 打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产 品中作发声器件。蜂鸣器主要分压电式和电磁式两种类型,本设计中用到的就是 电磁式蜂鸣器。电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片以及外壳等 组成,接通电源后,振荡膜片在电磁线圈和磁铁的相互作用下,周期性地振动发 声。由于蜂鸣器通常工作电流比较大,而单片机 I/O 口输出地电流很小,基本上 驱动不了蜂鸣器,所以选用的 NPN 型三极管 9013 来驱动蜂鸣器。蜂鸣器报警电 路如图 13 所示:
20

蜂鸣器报警电路图 图 13 蜂鸣器报警电路图 3.7 电磁阀控制模块 电磁阀控制模块 控制 电磁阀是用来控制流体的自动化基础元件,属于执行器;并不限于液压,气 动。 电磁阀包括:线圈、磁铁和顶杆 当线圈通电时,便产生磁性,跟磁铁相互吸引,磁铁就会拉动顶杆。关闭电 源,磁铁和顶杆就复位了,这样电磁阀就完成了作功过程。这就是电磁阀的工作 原理。 电磁阀一般用于液压系统,来关闭和开通油路。实际上,根据流过介质的温 度,压力等情况,比如管道有压力和自流状态无压力。电磁阀的工作原理是不同 的。 比如在自流状态下需要零压启动的,就是通电后,线圈整个把闸体吸起来。 而有压力状态的电磁阀,则是线圈通电后吸出插在闸体上的一个销子,用流体自 身的压力把闸体顶起来。 这两种方式的不同之处是,自流状态的电磁阀,因为线圈要吸起整个闸体, 所以体积较大,而带压状态的电磁阀,只需要吸起销子,所以体积可以做得比较 小。 本设计的电磁阀起控制是否上水,其电路如图 14 所示。在系统中用晶体管 来驱动电磁阀,当晶体管基极输入高电平时,晶体管饱和导通,集电极变为低电 平,因此电磁阀闭合,开始工作;当晶体管基极输入低电平时,晶体管截止,电 磁阀断开,停止工作。其中二极管并联在线圈的两端,起保护作用。后接发光二 极管,显示电磁阀是否工作。 由于实际做实物中的各种原因, 本设计用发光二极管来代替电磁阀的工作状
21
态,灯亮就表明电磁阀打开,水箱上水中;灯灭就表明电磁阀关闭,水箱停止上 水。
图 14 电磁阀控制电路 3.8 整体电路图 根据系统的各模块电路而设计的整体电路如图 15 所示:
22
图 15 系统整体电路图
4 系统软件设计
主程序设计思想:软件采用模块化设计方式,将各个功能分成独立模块,有 系统和监控程序一起管理执行。本设计的软件包括主程序,键盘扫描子程序,显 示子程序,水位值设定子程序以及有关的 DS18B20 的程序。 主程序完成功能:系统对传感器 DS18B20、显示器 12864 进行初始化,并 且读取用户通过键盘设置的最高水位信息, 随之系统自动读取当前水位并将当前 水位与最高水位进行比较,最后系统执行相应功能,完成后等待下一次的启动命
23
令。当检测到水位低于报警刻度水位时,系统会启动报警电路工作,并且会自动 上水至最大水位刻度。程序清单见附录 1 本设计的系统整体流程图如图 16 所示:
开始
对 LCD 进行初始化
扫描键盘
执行键盘操作
显示温度、水位
NO 关闭电磁阀 水位是否低于

预设值
YES 打开电磁阀
图 16 系统总体流程图
5 系统硬件调试
我在实验板上进行了实物的制作。 由于各方面条件有限, 在进行实物制作时, 我用发光二级管来模拟电磁阀,用滑动变阻器来模拟水位的变化。发光二级管变 亮表示电磁阀打开, 水箱上水; 发光二级管变暗表示电磁阀关闭, 水箱停止上水。 实物做好后, 便开始进行硬件调试, 硬件调试是一个模块一个模块地进行的, 在每个模块成功的基础上,进行最后的联调。调试过程并非一帆风顺,其中出现 了很多问题,开始时液晶显示上没任何显示,我请教老师和同学,最后在他们的 帮助下发现单片机和液晶显示器接的排阻阻值有问题, 改正后终于可以正常显示
24
了。程序也是在老师和同学的帮助下慢慢调试出来的。最终整个系统实现了正常 的工作。系统实物连接图见附录 2。 5.1 自动与手动上水测试 自动上水: 当把滑动变阻器调到水位低于 5L 时,此时蜂鸣器开始报警,同时发光二级 管变亮,表明开始自动上水,直到水满,发光二级管变暗,停止上水。 手动上水: 当把 K1 按下,发光二级管变亮,开始上水,直到水位到达 10L,发光二级 管变暗,停止上水;当把 K2 按下,发光二级管变亮,开始上水,直到水位到达 20L,发光二级管变暗,停止上水;当把 K3 按下,发光二级管变亮,开始上水, 直到水位到达 30L,发光二级管变暗,停止上水。 5.2 水温和水位显示测试 当用手捏住温度传感器 DS18B20 时,可以看到显示器上面显示的温度会升 高,即表示系统可以正常显示水温的变化。当调节滑动变阻器时,可看到显示器 上显示水位在不断变化,从最低变到最高,即表示系统可正常显示水位的变化。
6 结束语
经过了两个多月的学习和制作,我终于完成了本设计论文和实物制作。从开 始接到论文题目到系统实物的实现,每走一步对我来说都是新的尝试和挑战,这 也是我在大学期间独立完成的最大的项目,在这段时间里,我学到了很多知识也 有很多感受。 这次完成论文的经历,使我深深地感受到了理论和实际结合的重要性。在整 个过程中,我的动手能力和专业知识的运用能力得到了加强,同时,也从中学习 到如何去思考和解决问题,以及如何灵活地改变方法去实现设计方案。通过此次 毕业设计,巩固了我的专业知识,增强了我的产品开发意识,使我在大学期间得 到了一次很好的锻炼机会。
25
本设计也可进一步改进,提高系统的功能,例如: (1) 加热控制功能。冬天可以使用,定时加热、温控加热等。 (2) 温控上水。水箱水温超过设定温度

而水箱未满时,自动进行上水, 直到水温降到设定水温或水箱水满时停止上水。
26
[参考文献] 参考文献]
[1]沙占友,王彦朋,孟志永等.单片机外围电路设计[M].北京:电子工业出版社,2003. [2]胡乾斌, 李光斌, 李玲等.单片机微型计算机原理与应用[M].武汉:华中科技大学出版社, 2005. [3]康华光主编.电子技术基础模拟部分[M].第四版.北京:高等教育出版社,1999. [4]曹汉芳主编.数字电路与逻辑设计[M].第四版.武汉:华中科技大学出版社,2004. [5]谢自美主编.电子线路设计·实验·测试[M].第二版.武汉:华中科技大学出版社,2000. [6]李刚。林凌,姜苇等.51 系列单片机系统设计与应用技巧[M].北京:北京航空航天大学出 版社,2004. [7]朱定华,刘玉.单片机原理及应用技术学习辅导[M].北京:电子工业出版社,2001. [8]梅丽凤,王艳秋等.单片机原理及接口技术[M].北京:清华大学出版社,2004. [9]陈明荧.8051 单片机课程设计实例教材[M].北京:清华大学出版社,2007. [10]范逸之.Visual Basic 与 RS232 串行通讯控制[M].北京:中国青年出版社,2007. [11]蔡美琴等.MCS-51 系列单片机系统及其应用[M].北京:高等教育出版社,1992. [12]先锋工作室.单片机程序设计实例[M].北京:清华大学出版社,2003. [13]Phil Feldman&Roger Jennings 著,江峡译.即学即用 Visual Basic[M].北京:电子工业 出版社,1996. [14]李小鹏.基于单片机的风扇自动控制系统:[D].孝感学院:叶建勇,2006. [15]陈亮.数字式恒温系统设计:[D].孝感学院:叶建勇,2006. [16]陈柄和.C 语言与 C++语言程序设计[M].北京:北京航空航天大学出版社,2004. [17]D Andresciani,F Curti,F atera,etal.Measurement of the group-delay difference between the principal ststes of polarization on a low-birefingence terrestrial fiber cable[J].Optics Letters,1987,12.P884-846. [18]Jung J H,Shine SY,Lee C H.Effects of pre-chirping on the repeaterless dispersion managed transmission system[J].Electron Lett,1996,32(9);831~83.
27
附录
附录 1 源程序清单
#include <reg51.h> #include #include #define uchar unsigned char /************* 12864LCD 引脚定义 *************/ #define LCD_data P0 //数据口 sbit LCD_RS = P2^0; //寄存器选择输入 sbit LCD_RW = P2^1; //液晶读/写控制 sbit LCD_EN = P2^2; //液晶使能控制 sbit LCD_PSB = P2^3; //串/并方式控制 sbit LCD_RST = P2^5; //液晶复位端口 sbit P33=P3^3; ////////// sbit ST=P3^0; sbit OE=P3^1; sbit EOC=P3^2; sbit LED=P3^7; sbit button1=P3^4; sbit button2=P3^5; sbit button3=P3^6; sbit BEEP=P2^7; #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; sbit DQ =P2^6; //定义通信端口 34 26 /*********************************************************/ uchar DIS1[] = {"30 L\0"}; uchar DIS2[] = {"18.2\0"}; uchar DIS3[] = {"Load..\0"}; uchar

DIS4[] = {"Water\0"}; uchar D
IS5[] = {"Full!\0"}; uchar DIS6[] = {" "}; uchar temp[3]; uchar js,getdata,bai,ge,shi,waterlevel; /*******************************************************************/ static unsigned char HT,LT; //定义用于存放温度值的高位 void delay2(unsigned int i) { while(i--); }
28
/*******************************************************************/ /* */ /* 延时函数 */ /* */ /*******************************************************************/ void delay(int ms) { while(ms--) { uchar i; for(i=0;i<250;i++) { _nop_(); _nop_(); _nop_(); _nop_(); } } } /*******************************************************************/ /* */ /* 延时函数 */ /* */ /*******************************************************************/ void delay1(int ms) { while(ms--) { uchar y; for(y=0;y<100;y++) ; } } //DB18B20 初始化函数 Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ 复位 delay2(8); //稍做延时 DQ = 0; //单片机将 DQ 拉低 delay2(80); //精确延时 大于 480us DQ = 1; //拉高总线 delay2(14); x=DQ; //稍做延时后 如果 x=0 则初始化成功 x=1 则初始化失败
29
delay2(20); } //读一个字节 ReadOneChar(void) { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; // 给脉冲信号 dat>>=1; // 逐位右移 DQ = 1; // 给脉冲信号 if(DQ) //DQ 为 1 时,表示收到高电平 1 dat|=0x80; // 把收到的高电平置给 DAT 的最高位 delay2(4); } return(dat); } //写一个字节 WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; //把要发送的高电平或者低电平给 DQ 发送出去 delay2(5); DQ = 1; dat>>=1; //逐位右移 } delay2(4); } //读取温度 void ReadTemperature() { unsigned char a=0; unsigned char b=0; Init_DS18B20(); //调用初始化函数 WriteOneChar(0xCC); // 跳过读序号列号的操作 //不需要验证序列号。 WriteOneChar(0x44); //发送温度转换命令 启动温度转换 Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE);
30
a=ReadOneChar(); //读取温度值低位 b=ReadOneChar(); //读取温度值高位 LT=a&0x0f; HT=b<<4; HT+=(a&0xF0)>>4; } /*******************************************************************/ /* */ /*检查 LCD 忙状态 */ /*lcd_busy 为 1 时,忙,等待。lcd-busy 为 0 时,闲,可写指令与数据。 */ /* */ /*******************************************************************/ bit lcd_busy() { bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; delayNOP(); result = (bit)(P0&0x80); ///////////// LCD_EN = 0; return(result); } /*******************************************************************/ /* */ /*写指令数据到 LCD */ /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */ /* */ /*******************************************************************/ void lcd_wcmd(uchar cmd) { while(lcd_

busy()); LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; _nop_(); _nop_(); P0 = cmd; ////////////// delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } /**
*****************************************************************/
31
/* */ /*写显示数据到 LCD */ /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */ /* */ /*******************************************************************/ void lcd_wdat(uchar dat) { while(lcd_busy()); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; ///////////// delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } /*******************************************************************/ /* */ /* LCD 初始化设定 */ /* */ /*******************************************************************/ void lcd_init() { LCD_PSB = 1; //并口方式 LCD_RST = 0; //液晶复位 delay(3); LCD_RST = 1; delay(3); lcd_wcmd(0x34); //扩充指令操作 delay(5); lcd_wcmd(0x30); //基本指令操作 delay(5); lcd_wcmd(0x0C); //显示开,关光标 delay(5); lcd_wcmd(0x01); //清除 LCD 的显示内容 delay(5); } /********************************************************** *函数名: ClearPic *功 能: 清除图像 *说 明: *输 入: *返 回: 无
32
**********************************************************/ void ClearPic(void) { uchar w,h; lcd_wcmd(0x34);//扩充指令集 lcd_wcmd(0x36);//绘图显示开 for(h=0;h<32;h++) //先画上半屏 32 行点阵 { lcd_wcmd(0x80+h);//Y 地址寄存器 lcd_wcmd(0x80); //X 地址(LCM 自动加 1) for(w=0;w<16;w++)// { lcd_wdat(0x00);//写入一个字节图形数据,k++指向下一个图形字节 } } for(h=0;h<32;h++) //画下半屏余下的点阵 { lcd_wcmd(0x80+h);//Y 地址寄存器 lcd_wcmd(0x88); //X 地址(LCM 自动加 1) for(w=0;w<16;w++)// { lcd_wdat(0x00);//写入一个字节图形数据,k++指向下一个图形字节 } } lcd_wcmd(0x30); //基本指令集 } uchar code Photo1[] ={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00, 0x0F,0xC0,0xC8,0x00,0x0F,0xC0,0xC8,0x00, 0x00,0x00,0xC8,0x00,0x00,0x00,0xE8,0x00, 0x0F,0xC0,0xC8,0x00,0x00,0x00,0xC8,0x00, 0x00,0x00,0xE8,0x00,0x0F,0xC0,0xC8,0x00, 0x00,0x00,0xC8,0x00,0x00,0x00,0xE8,0x00, 0x0F,0xC0,0xC8,0x00,0x0F,0xC0,0xC8,0x00, 0x00,0x00,0xC8,0x00,0x00,0x00,0x88,0x00, 0x0F,0xC3,0x06,0x00,0x00,0x02,0x02,0x00, 0x00,0x0C,0x01,0x80,0x00,0x0C,0x01,0x80, 0x00,0x0C,0x01,0x80,0x00,0x0C,0x01,0x80, 0x00,0x04,0x01,0x80,0x00,0x03,0xFE,0x00, 0x00,0x01,0xFC,0x00,0x00,0x00,0xF8,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
33
char code Photo2[] = { 0x1C,0x00,0x00,0x60,0x1C,0x00,0x00,0x60, 0x1C,0x00,0x00,0x60,0x0F,0x32,0x22,0xE0, 0x0F,0xFF,0xFE,0xE0,0x0E,0x00,0x00,0xE0, 0x0E,0x00,0x0C,0xC0,0x06,0x00,0x01,0xC0, 0x06,0x01,0xC1,0xC0,0x06,0x00,0x01,0xC0, 0x03,0x60,0x03,0x80,0x03,0x00,0x03,0x80, 0x03,0x00,0x03,0x80,0x03,0x87,0x03,0x80, 0x03,0x80,0x03,0x00,0x03,0x80,0x03,0x00, 0x03,0x80,0x33,0x00,0x01,0xD8,0x06,0x00, 0x01,0xC0,0x06,0x00,0x01,0xC0,0

xC6,0x00, 0x01,0xE0,0x06,0x00,0x00,0xE0,0x0E,0x00, 0x00,0xE0,0x0E,0x00,0x00,0xFF,0xFE,0x00, 0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; /********************************************************* * * * 图形显示 * * * *********************************************************/ void photodisplay1(uchar *DisplayPic1) { uchar i; unsigned char CurrentCol=0X80; //X 坐标,后写 X unsigned char CurrentRow=0X80; //Y 坐标,先写 Y unsigned char CurrentCol2=0X90; //X 坐标,后写 X unsigned char CurrentRow2=0X90; //Y 坐标,先写 Y lcd_wcmd(0x34); //写数据时,关闭图形显示 for(i=0;i<16;i++) { lcd_wcmd(CurrentRow+i); lcd_wcmd(CurrentCol+0); lcd_wdat(DisplayPic1[4*i]); lcd_wdat(DisplayPic1[4*i+1]); } for(i=0;i<16;i++) { lcd_wcmd(CurrentRow+i); lcd_wcmd(CurrentCol+1); lcd_wdat(DisplayPic1[4*i+2]);
34
lcd_wdat(DisplayPic1[4*i+3]); } for(i=0;i<16;i++) { lcd_wcmd(CurrentRow2+i); lcd_wcmd(CurrentCol2+0); lcd_wdat(DisplayPic1[64+4*i]); lcd_wdat(DisplayPic1[64+4*i+1]); } for(i=0;i<16;i++) { lcd_wcmd(CurrentRow2+i); lcd_wcmd(CurrentCol2+1); lcd_wdat(DisplayPic1[64+4*i+2]); lcd_wdat(DisplayPic1[64+4*i+3]); } lcd_wcmd(0x36); //写完数据,开图形显示 */ } void photodisplay2(uchar *DisplayPic1) { uchar i; unsigned char CurrentCol=0X88; unsigned char CurrentRow=0X88; unsigned char CurrentCol2=0X98; unsigned char CurrentRow2=0X98; lcd_wcmd(0x34); //写数据时,关闭图形显示 for(i=0;i<16;i++) { lcd_wcmd(CurrentRow+i); lcd_wcmd(CurrentCol); lcd_wdat(DisplayPic1[4*i]); lcd_wdat(DisplayPic1[4*i+1]); } for(i=0;i<16;i++) { lcd_wcmd(CurrentRow+i); lcd_wcmd(CurrentCol+1); lcd_wdat(DisplayPic1[4*i+2]); lcd_wdat(DisplayPic1[4*i+3]); } for(i=0;i<16;i++) { lcd_wcmd(CurrentRow2+i); lcd_wcmd(CurrentCol2);
//X 坐标,后写 X //Y 坐标,先写 Y //X 坐标,后写 X //Y 坐标,先写 Y
35
lcd_wdat(DisplayPic1[64+4*i]); lcd_wdat(DisplayPic1[64+4*i+1]); } for(i=0;i<16;i++) { lcd_wcmd(CurrentRow2+i); lcd_wcmd(CurrentCol2+1); lcd_wdat(DisplayPic1[64+4*i+2]); lcd_wdat(DisplayPic1[64+4*i+3]); } lcd_wcmd(0x36); //写完数据,开图形显示 */ } /********************************************************* * * * 清屏函数 * * * *********************************************************/ void clr_screen() { lcd_wcmd(0x34); //扩充指令操作 delay(5); lcd_wcmd(0x30); //基本指令操作 delay(5); lcd_wcmd(0x01); //清屏 delay(5); } void display_tempmain(void) //主程序温度显示函数 { uchar i,key; if(LT==2) LT=1; if(LT==3) LT=2; if(LT==4 | LT==5) LT=3; if(LT==6) LT=4; if(LT==7 | LT==8) LT=5; if(LT==9 | LT==10) LT=6; if(LT==11 | LT==12) LT=7; if(LT==13) LT=8; if(LT==14 | LT==15) LT=9; temp[0]=HT/10; temp[1]=HT%10; temp[2]=LT; for(i=0;i<=2;i++) { switch(temp[i]) //检测按键值,并译码
36
{
case 0: key='0'; case 1: key='

1'; case 2: key='2'; case 3: key='3'; case 4: key='4'; case 5: key='5'; case 6: key='6'; case 7: key='7'; case 8: key='8'; case 9: key='9'; default: key='0';
break; break; break; break; break; break; break; break; break; break; break;

//NONE
} if(i==0) DIS2[0]=key; if(i==1) DIS2[1]=key; if(i==2) DIS2[3]=key; } } /********************************************************* * * * AD 转换函数 * * *********************************************************/ void adtransfer(void) { uchar i,key; ST=1; ST=0; while(EOC==0); OE=1; getdata=P1; OE=0; getdata=getdata/8; if(getdata>30) getdata=30; getdata=getdata/1; shi=getdata/10; ge=getdata%10; temp[0]=shi; temp[1]=ge; for(i=0;i<=2;i++) { switch(temp[i]) //检测按键值,并译码 { case 0: key='0'; break; case 1: key='1'; break; case 2: key='2'; break;
*
37
case 3: key='3'; case 4: key='4'; case 5: key='5'; case 6: key='6'; case 7: key='7'; case 8: key='8'; case 9: key='9'; default: key='0'; } if(i==0) DIS1[0]=key; if(i==1) DIS1[1]=key; }
break; break; break; break; break; break; break; break;
//NONE
} /********************************************************* * * * 字函数 * * * *********************************************************/ void display_z1(void) { uchar i; lcd_wcmd(0x30); //LOAD.. lcd_wcmd(0x8d); for(i=0;i<16;i++) { if(DIS3[i]!='\0') { lcd_wdat(DIS3[i]); } else break; } } void display_z2(void) { uchar i; lcd_wcmd(0x30); //WATER down lcd_wcmd(0x9d); for(i=0;i<16;i++) { if(DIS4[i]!='\0') { lcd_wdat(DIS4[i]); }
38
else break; } } void display_z3(void) { uchar i; lcd_wcmd(0x30); lcd_wcmd(0x9d); for(i=0;i<16;i++) { if(DIS5[i]!='\0') { lcd_wdat(DIS5[i]); } else break; } } void display_z4(void) { uchar i; lcd_wcmd(0x30); lcd_wcmd(0x8d); for(i=0;i<16;i++) { if(DIS4[i]!='\0') { lcd_wdat(DIS4[i]); } else break; } } void display_z51(void) { uchar i; lcd_wcmd(0x30); lcd_wcmd(0x8d); for(i=0;i<6;i++) { lcd_wdat(DIS6[i]); } }
//FULL
//WATER up
//clear up
39
void display_z52(void) { uchar i; lcd_wcmd(0x30); //clear down lcd_wcmd(0x9d); for(i=0;i<6;i++) { lcd_wdat(DIS6[i]); } } /********************************************************* * * * 键盘函数 * * * *********************************************************/ uchar keyboard(void) { uchar i; i=4; button1=1; button2=1; button3=1; delay2(50); if(button1==0) { waterlevel=10; i=1; } if(button2==0) { waterlevel=20; i=2; } if(button3==0) { waterlevel=30; i=3; } return i; } /********************************************************* * * * 蜂鸣器函数 * * *
40
*********************************************************/ void beep(void) { unsigned char y; for (y=0;y<180;y++) { BEEP=!BEEP; //BEEP 取反 delay2(40); } BEEP=0; //关闭蜂鸣器 } /********************

************************************* * * * 主函数 * * * *********************************************************/ void main(void) { uchar i,mm,flag; lcd_init(); ClearPic(); photodisplay1(Photo1); photodisplay2(Photo2); delay(1000); TMOD=0x01; TH0=0xff; TL0=0xfe; IE=0x82; TR0=1; P33=0; EOC=1; OE=0; ST=0; bai=0; ge=0; shi=0; LED=1; waterlevel=10; BEEP=0; flag=0; while(1) //主循环 { ReadTemperature(); //读取温度值 display_tempmain(); /
/对读到的温度值进行处理
41
adtransfer(); lcd_wcmd(0x30); lcd_wcmd(0x92); for(i=0;i<16;i++) { if(DIS2[i]!='\0') { lcd_wdat(DIS2[i]); } else break; } lcd_wcmd(0x30); lcd_wcmd(0x9a); for(i=0;i<16;i++) { if(DIS1[i]!='\0') { lcd_wdat(DIS1[i]); } else break; } lcd_wcmd(0x30); //温度符号 lcd_wcmd(0x94); lcd_wdat(0xa1); lcd_wdat(0xe6); mm=keyboard(); if(mm!=4) flag=1; if(getdata<waterlevel && flag==1) { LED=0; display_z1(); display_z2(); } else if(getdata==30 ) { display_z4(); display_z3(); LED=1; } else if(flag==0) { display_z51(); display_z52(); LED=1; }
//////////
42
if(getdata>=waterlevel && flag==1) flag=0; if(getdata<5) { beep(); waterlevel=30; flag=1; } } } void timer0() interrupt 1 { TH0=(65536-200)/256; TL0=(65536-200)%256; P33=~P33; }
附录 2 系统整体实物图
43
44

1


相关主题