计控 粮仓温度自动检测系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算机控制系统题目:粮仓温度自动监测系统
系别:电气工程与自动化
专业:自动化
学号:
姓名:
粮仓温度自动检测系统
摘要
随着单片机技术的飞速发展,单片机在各个领域得到了广泛的应用。

粮食是人类生存的必需品,温度是保存好粮食的先决条件,储存大量的粮食对稳定国民经济的发展起到至关重要的作用。

粮库一般较大,测量点会很多。

粮仓温度测量方法以及相应的智能控制一直是粮食保存的一个重要问题。

本系统是以AT89C52单片机、DS18B20数值温度传感器为核心组成的粮仓温度控制系统。

该系统利用AT89C52单片机采集了各个点的温度,实现温度显示、报警等功能。

它以AT89C52单片机为主控制芯片,采用数字温度传感器DS18B20实现多路温度的检测,利用LCD1602液晶显示器形象直观的显示测出的温湿度值。

本文在确定法设计方案基础上,着重论述了系统的软硬件设计,并且描述了系统电路设计、硬件设计框图及所使用各种芯片功能和特性。

通过PROTEUS软件和KEIL C仿真出了该系统。

关键词:单片机,DS18B20,液晶显示,报警
目录
第1章绪论 (1)
1.1 选题的背景与意义 (1)
第2章系统总体设计 (2)
2.1 方案的选择 (2)
2.2 系统总体设计 (3)
第3章硬件设计 (5)
3.1 硬件选型 (5)
3.2 硬件电路设计 (6)
第4章软件设计 (13)
4.1 系统流程 (13)
4.2 软件设计....................................... 错误!未定义书签。

4.2.1软件语言的选择
4.2.2主程序
第5章仿真结果 (15)
5.1仿真软件Proteus简介 (15)
5.2仿真电路原理图及结果............................ 错误!未定义书签。

5.3 仿真结果分析 (17)
结论 (15)
参考文献 (19)
附录 (20)
第1章绪论
1.1选题的背景与意义
温度是科学技术中最基本的物理量之一,物理、化学、生物等学科都离不开温度。

在工业生产和实验研究中,像电力、化工、石油、冶金、航空航天、机械制造、粮食存储、酒类生产等领域内,温度常常是表征对象和过程状态的最重要的参数之一。

比如,发电厂锅炉的温度必须控制在一定的范围之内;许多化学反应的工艺过程必须在适当的温度下才能正常进行;炼油过程中,原油必须在不同的温度和压力条件下进行分馏才能得到汽油、柴油、煤油等产品。

没有合适的温度环境,许多电子设备就不能正常工作,粮仓的储粮就会变质霉烂,酒类的品质就没有保障。

因此,各行各业对温度控制的要求都越来越高。

可见,温度的测量和控制是非常重要的。

人们使用温度计来采集温度,通过人工操作加热、通风和降温设备来控制温度,这样不但控制精度低、实时性差,而且操作人员的劳动强度大。

即使有些用户采用半导体二极管作温度传感器,但由于其互换性差,效果也不理想。

在某些行业中对温度的要求较高,由于工作环境温度不合理而引发的事故时有发生。

对工业生产可靠进行造成影响,甚至操作人员的安全。

为了避免这些缺点,需要在某些特定的环境里安装数字温度测量及控制设备。

本设计由于采用了新型单片机对温度进行控制,以其测量精度高,操作简单。

可运行性强,价格低廉等优点,特别适用于生活,医疗,工业生产等方面的温度测量及控制。

第2章系统总体设计
2.1 方案的选择
本次使用AT89C52单片机作为控制核心,以智能温度传感器DS18B20为温湿度测量元件,进行多点温湿度监测,超过其温度上下限值就报警且打开电风扇。

显示电路采用LCD1602模块,使用单片机直接驱动发光二极管构成报警电路。

如图2.1所示。

图2.1温度测量系统方案框图
优点是:采用智能温度传感器DS18B20,它直接输入数字量,精度高,电路简单,只需要模拟DS18B20的读写时序,根据DS18B20的协议读取
转换的温度,体现了技术的先进性,性价比低。

2.2 系统总体设计
本设计以AT89S51为核心,控制整个系统。

适合在一定温度条件的环境下,电路中用到了继电器,通过单片机的弱点系统来控制与继电器项链的强电系统,从而保证强点系统控制的安全性。

系统的利用数字温度传感器DS18B20采集数据并送给单片机,单片机处理之后将采集的数据送给LCD1602显示一边操作人员直观的了解当前温度。

我们给系统正常工作设定为0℃-50℃,如果当前温度在这个温度设定范围内,则单片机控制继电器闭合,使继电器控制的负载回路导通,是系统正常工作;若当前温度不在这个范围内,则说明当前温度不满足工作需求,此时单片机控制蜂鸣器发出警报,并且控制继电器使负载停止工作。

并根据当前温度,若温度小于0℃,则启动加热装置,若温度高于50℃,则启动降温装置,直到达到系统温度,蜂鸣器停止报警,负载回路导通,重新开始工作。

从而达到一个自动控制的作用,整个系统形成一个闭环温度值,系统变化参数为温度的值,负载的工作取决于环境温度的变化,通过单片机弱电控制与继电器相连的强电系统,从而解决了强电系统直接控制对操作人员有一定危险性的特点。

电路各部分的主要功能电路功能如下图:
图2-2 电路主要功能组成图
温度采集功能:由温度传感器检测当前环境温度,并将温度传给单片机AT89S51。

温度显示功能:采集到的温度,能够直接显示在LCD1602上,于使用者的操作和观测。

温度报警功能:对采集到的温度自动判断并进行声音和光报警,起到提示的作用。

温度控制功能:由两部分组成,分别是加热和降温装置,实现智能全自动操作。

.
第3章硬件设计
3.1 硬件选型
单片机应用系统的硬件电路设计就是为本单片机温控系统选择合适的、最优的系统配置,即按照系统功能要求配置外围设备,如键盘、显示器、打印机、A/D转换器、设计合适的接口电路等。

系统设计应本着以下原则:
(1) 尽可能选择典型电路,并符合单片机常规用法。

(2) 硬件结构应结合应用软件方案一并考虑。

软件能实现的功能尽可能由软件实现,以简化硬件结构。

由软件实现的硬件功能,一般响应时间比硬件实现长,且占用CPU时间。

(3) 系统中的相关器件要尽可能做到性能匹配。

系统中所有芯片都应尽可能选择低功耗产品。

方案一:
采用数码管做显示,显示温度数据。

用74LS164驱动数码管,DS18B20采集温度数,24CXX系列作存储,利用单片机进行连接。

经过反复考虑,系统成功较高,时间反应速度缓慢,数码管和驱动部分占用硬件资源大,能量消耗大,不够理想,放弃此方案。

方案二:
采用AT89S51芯片,使用DALLAS公司的温度传感器DS18B20读取温度,芯片体积小,三个管脚,硬件连接简单,节省I/O口。

显示用LCD1602,减小了系统的能耗。

报警模块用三极管驱动蜂鸣器发出警报。

控制模块通过继电器弱电控制强电。

为了仿真,负载和加热模块接一个12V的灯泡,通过灯泡的亮灭来观察控制效果,直观又节约资源。

最后通过比较,选择了这个方案。

3.2 硬件电路设计
3.2.1 温度采集模块
DS18B20的测温原理如图3-1所示:
预置斜率累加器
比较器
低温度系数振荡器高温度系数振荡器减法计数器1
减到0
减法计数器2减到0
温度寄存器
预置
置1/清0
增加
停止
图3-1 DS18B20测温原理
从图3-1中可以看出,DS18B20主要由斜率累加器、温度系数振荡器、减法计数器、温度寄存器等部分组成。

斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正减法计数器的欲置值。

温度系数振荡器用
于产生减法计数脉冲信号,其中低温度系数振荡器受温度的影响很小,用于产生固定频率的脉冲信号送给减法计数器1,高温度系数振荡器随温度变化其振荡频率明显改变,所产生的信号作为减法计数器2的脉冲输入.减法计数器对脉冲信号进行减法计数。

温度寄存器暂存温度数值。

DS18B20与单片机接口电路
图3-2 DS18B20与单片机的连线图
3.2.2温度显示模块
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。

1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表3-5所示:
表3-1:引脚接口说明表
编符引脚说明编符引脚说明
1 VS电源地9 D
2 数据
2 VD电源正极10 D
3 数据
3 VL 液晶显示偏11 D
4 数据
4 RS 数据/命令选12 D
5 数据
5 R/读/写选择13 D
6 数据
6 E 使能信号14 D
7 数据
7 D0 数据15 BL背光源正极
8 D1 数据16 BL背光源负极
LCD1602与单片机连接图
图3-3 LCD1602与单片机连接图
3.2.3温度报警模块
报警电路原理
当环境温度不在设置温度范围内,需要发出警报,报警电路由PNP三极管和扬声器组成。

电路中刚才用PNP三极管,选用低功率三极管9012,当P1.0低电平,三极管集电极正偏,发射级反偏,三极管导通,驱动蜂鸣器报警。

报警电路与单片机连接图
图3-4 报警电路与单片机连接图
3.2.4温度控制模块
温度控制电路连接图
本设计中,采用NPN三极管驱动继电器,并且带有一发光二极管作为指示灯,系统中由于仿真的方便采用了12V的灯泡代替强电系统。

加热系统接在单片机P1.2口上,降温系统接到单片机P1.3口上。

温度控制模块
的电路图如图3-5
图3-5 温度控制电路连接图
3.2.5负载模块
负载模块的原理
电路的负载也是通过继电器用单片机的弱电控制强电。

本设计中采用NPN三极管驱动继电器,并且带有一负载工作的指示灯,系统中负载由于仿真方便采用了12V灯泡代替强电系统。

电路和单片机的P1.7脚相连,当高电平时,三极管饱和导通,+5V电源分压加到继电器线圈两端,继电器
吸合,同时状态指示的发光二极管也点亮,继电器的常开触点闭合,相当
于开关闭合。

当单片机的P1.7脚为低电平时,三极管截止,继电器线圈两端没有电位差,继电器衔铁释放,同时状态指示的发光二极管也熄灭,继电器的常开触点释放,相当于开关断开。

在三极管截止的瞬间,由于线圈中的电流不能突变为零,继电器线圈两端会产生一个较高电压的感应电动势,线圈产生的感应电动势则可以通过二极管释放,从而保护了三极管免被击穿,也消除了感应电动势对其他电路的干扰,这就是二极管的保护作用。

负载模块的电路图
图3-6 负载电路连接
第4章软件设计
4.1 系统流程
开始
系统初始化
DS18B20采集温度
启动温度转换并显示

温度是否超过上限

启动降温模块

温度是否低于下限

启动加热模块
启动负载模块
图4-1 主程序图
4.2 软件设计
4.2.1 软件语言的选择
单片机开发过程中往往使用汇编和C语言两种语言,就本设计而言我们用C语言。

具有如下优点:
∙更符合人类思维习惯,开发效率高、时间短。

∙模块化。

∙可移植性好。

总之,C语言既有高级语言的特点,又具有汇编语言的特点;既是一个成功的系统设计语言,又是一个使用的程序设计语言;既能用来编写不依赖计算机硬件的应用程序,又能用来编写各种系统程序。

综上所述,选择C语言作为软件设计的语言。

4.2.2主程序
主程序流程图如图4-1所示。

主程序主要完成以下几项任务:(1)初始化。

对内存中的工作参数进行初始化,显示系统初始化。

(2)读取温度。

(3)判断是否超过设定温度。

若超过温度上限则启动降温模块,若没有超过则继续进行判断。

(4)判断是否低于设定温度。

若低于温度下限则启动加热模块。

(5)若位于设定温度内,则启动负载模块。

第5章仿真结果
5.1 仿真软件Proteus简介
Proteus 软件是来自英国Labcenter electronics 公司的EDA 工具软件,Proteus 软件有近20年的历史,在全球广泛使用。

它除了具有和其它EDA 工具一样的原理布图、PCB 自动或人工布线及电路仿真的功能外,其革命性的功能是,它的电路仿真是交互的,可视化的,针对微处理器的应用,还可以直接在基于原理图的虚拟原型上编程,并实现软件源码级的实时调试,如有显示及输出,还能看到运行后输入输出的效果,配合系统配置的虚拟仪器如示波器、逻辑分析仪等,可以测量仿真的波形及记录仿真数据。

在不需要硬件设备投入的情况下Proteus 软件可以建立完整的电子学习设计开发环境,缩短研发周期,并且降低开发成本。

Proteus 组合了高级原理布图、混合模式SPICE 仿真,PCB 设计以及自动布线来实现一个完整的电子设计系统。

此系统受益于多年来的持续开发,被《电子世界》在其对PCB 设计系统的比较文章中评为最好产品—“The Route to PCB CAD”。

Proteus 产品系列也包含了我们革命性的VSM 技术,用户可以对基于微控制器的设计连同所有的周围电子器件一起仿真。

用户甚至可以实时采用诸如LED/LCD、键盘、RS232 终端等动态外设模型来对设计进行交互仿真。

图5-1为Proteus仿真界面:
图5-1 Proteus仿真界面
其功能模块:—个易用而又功能强大的ISIS 原理布图工具;PROSPICE 混合模型SPICE 仿真; ARESPCB 设计。

PROSPICE 仿真器的一个扩展PROTEUS VSM:便于包括所有相关的器件的基于微处理器设计的协同仿真。

此外,还可以结合微控制器软件使用动态的键盘,开关,按钮,LED 甚至LCD 显示CPU 模型。

5.2 仿真电路原理图及结果
利用Keil51及Proteus联合调试,将电路原理图仿真。

下图中DS18B20
采集的温度为90.6℃,仿真中降温模块灯泡工作,扬声器发出警报。

图5-2 仿真原理图及结果
5.3 仿真结果分析
从仿真的效果图看出,仿真是针对的其中的一种状态。

当温度传感器DS18B20采集到环境温度,并将温度传给单片机进行显示,由LC1602显示当前环境温度为90.6℃,由于程序中设定的额定温度为0℃-50℃,此时已经超出了要求的温度。

这是单片机驱动蜂鸣器报警,并通过弱电驱动强电,是继电器闭合,让降温模块工作。

为了仿真的明显,我们用灯泡代替。

可以明显的看到图中的小风扇那个灯泡处于工作状态,说明正在降温。

而负
载要等温度降到额定温度范围内才工作。

仿真结果说明设计的温度控制中降温部分已经工作,其他部分同理可以进行仿真和测试。

结论
在单片机自动控制已经广泛的应用于人们的生产和生活的今天,传统用模拟电路来控制温度的做法,已经逐渐被淘汰。

本设计是基于AT89S51单片机的温度测控与报警电路设计,最终让电路能够保证负载在特定的环境温度范围内正常的工作。

本设计查阅了大量的关于传感器、单片机及其接口电路、以及控制方面的理论,经过方案论证、系统的硬件和软件的设计、系统的调试等过程,最终实现了温度显示、温度报警、温度控制,能够做到智能温度控制。

在电路中使用单片机的弱电控制其他模块的强电,也避免强电和操作人员的直接接触,提高了电路的稳定和安全性。

本设计结构简单,成本低,稳定性高,具有实际应用价值。

本设计使用的是DS18B20数字温度传感器,若根据使用环境配上适当的温度传感器,这个电路便还可以实现很多领域的温度自动控制,同时还可以进行多点温度测控。

可以广泛地应用于多种场合,机房的温度、育婴房的温度、水温的控制等。

这对于提高系统的利用率,避免重复设计有很大作用。

在本设计的作用下,能够为负载提供一个良好的工作环境,使产品的数量和质量有很大的提高。

降低产品的生成成本或者提高使用率,从而使系统的使用者获得的利润提高了。

本设计温度控制器结构简单、测温准确,还可以将测得的温度通过单片机与通讯模块相连接,以手机短消息的方式发送给用户,
使用户能够随时对温度进行监控。

用户可灵活选择本设计的用途,其有很
强的使用价值。

参考文献
[1] 罗厚军,魏敏敏. 经典集成电路应用手册.福建:福建科学技术出版社,2006.
[2] 夏继强,邢春香. 单片机应用设计培训教程-实践篇.北京:北京航空航天大学出版社. 2008.
[3] 刘建辉,冀常鹏. 单片机智能控制技术.北京:国防工业出版社. 2007.
[4] 夏彬彬,任明会. PIC单片机常用模块与综合系统设计案例精讲.北京:电子工业出版社. 2009.
[5] 林凌,李刚. 实用电子技术1000问.北京:电子工业出版社. 2008.
[6]陈雷,雷宏洲.C/C++程序设计教程.清华大学出版社,2007年.
[7]蔡振江,马跃进,韩庆瑶等.单片机原理及应用[M] .北京:电子工业
出社,2007.
[8]赵景波,王劲松等.Protel电路设计.电子工业出版社,2007.
[9]郭强. 液晶显示应用技术[M] .北京:电子工业出版社,2003.
[10]沙占友.智能化集成温度传感器原理与应用[M] .北京:机械工业
出版社,2002.
[11]刘树棠,朱茂林,荣玖.基于运算放大器和模拟集成电路的电路设
计[M] .3 版. 西安:西安交通大学出版社,2004.
[12]周月霞,孙传友.DS18B20数字温度传感器的功能特性及其设计[J] .世界采矿快报.2000(9):329—330.
[13]J.C.Whitaker. Thermal Design of Electronic Equipment. CRC Press LLC. Lond on2001.
[14]A.P. Knyupfer .Dynamic error in analog-digital conversion[J] .Measurement Techniques. Volue 11,Number 9.1225~1229.
[15]Marius Grundmann.The Physics of
Semiconductors[M] .Springer Berlin Heidelberg.2006, 577~620.
附录
程序:
#include<reg52.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含
_nop_()函数定义的头文件
sbit RS=P2^6; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^5; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^7; //使能信号位,将E位定义为P2.2引脚
sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引
sbit k1=P2^0; //中断
sbit k2=P2^1;//移动键
sbit k3=P2^2;//加
sbit k4=P2^3; //减去
sbit k5=P3^7; //定时
sbit l1=P1^0; //中断
sbit l2=P1^1;//移动键
sbit l3=P1^2;//加
sbit l4=P1^3; //减去
sbit FM=P1^4;
unsigned char code
s[11]={'0','1','2','3','4','5','6','7','8','9', '-'}; //unsigned char code
digit[11]={"0123456789-"}; // unsigned char flag,tltemp;
char
num1=0,num2=0,sec=0,sec1=0,min =0,min1=0,h=0,h1=0,x=6,x1=6;
unsigned char
d=1,d1=1,m=9,m1=9,year=12,year1 =12;
char
a=0,b=0,c=0,e=0,k=0,ds=0,df=0,dm =0;
/***************************** ************************
函数功能:延时1ms
************************** *************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++)
;
}
/***************************** ************************
函数功能:延时若干毫秒
入口参数:n
************************** *************************/
void delay(unsigned int n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/***************************** ****************************** *************
以下是DS18B20的操作程序****************************** ****************************** ************/
sbit DQ=P3^7;
unsigned char time; //设置全局变量,专门用于严格延时
/***************************************************** 函数功能:将DS18B20传感器初始化,读取应答信号
出口参数:flag
************************** *************************/
bit Init_DS18B20(void)
{
bit flag; //储存
DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在
DQ = 1; //先将数据线拉高
for(time=0;time<2;time++) //略微延时约6微秒
;
DQ = 0; //再将数据线从高拉低,要求保持
480~960us
for(time=0;time<200;time++) //略微延时约600微秒
; //以向
DS18B20发出一持续480~960us的低电平复位脉冲
DQ = 1; //释放数据线(将数据线拉高)
for(time=0;time<10;time++)
; //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在)
for(time=0;time<200;time++) //延时足够长时间,等待存在脉冲输出完毕
;
return (flag); //返回检测成功标志
}
/************************* **************************** 函数功能:从DS18B20读取一个字节数据
出口参数:dat
************************** *************************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat; //储存读出的一个字节数据
for (i=0;i<8;i++)
{
DQ =1; // 先将数据线拉高
_nop_(); //等待一个机器周期
DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
_nop_(); //等待一个机器周期
DQ = 1; //将数据线"人为"拉高,为单片机检测
DS18B20的输出电平作准备
for(time=0;time<2;time++)
; //延时约6us,使主机在15us内采样
dat>>=1;
if(DQ==1)
dat|=0x80; //如果读到的数据是1,则将1存入dat
else
dat|=0x00;//如
果读到的数据是0,则将0存入dat
//将单片机检测到的电平信号DQ存入r[i]
for(time=0;time<8;time++)
;
//延时3us,两个读时序之间必须有大于1us的恢复期
}
return(dat); //返回读出的十六进制数据
}
/*************************
****************************
函数功能:向DS18B20写入一个字节数据
入口参数:dat
************************** *************************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=0; i<8; i++)
{
DQ =1; // 先将数据线拉高
_nop_(); //等待一个机器周期
DQ=0; //将数据线从高拉低时即启动写时序
DQ=dat&0x01; //利用与运算取出要写的某位二进制数据,
//并将其送到数据线上等待
DS18B20采样
for(time=0;time<10;time++)
;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
DQ=1; //释放数据线for(time=0;time<1;time++)
;//延时3us,两个写时序间至少需要1us的恢复期
dat>>=1; //将dat中的各二进制位数据右移1位
}
for(time=0;time<4;time++)
; //稍作延时,给硬件一点反应时间
}
/************************* **************************** 函数功能:做好读温度的准备
************************** *************************/
void ReadyReadTemp(void)
{
Init_DS18B20(); //将DS18B20初始化
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay(200); //转换一次需要延时一段时间
Init_DS18B20(); //
将DS18B20初始化
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位
}
/*void display_temp1(unsigned char x)
{
unsigned char j,k,l;
//j,k,l分别储存温度的百位、十位和个位
j=x/100; //取百位
k=(x%100)/10; //取十位
l=x%10; //取个位
WriteAddress(0x46); //写显示地址,将在第2行第7列开始显示
if(flag==1) //负温度时显示“—”
{
WriteData(digit[10]); //将百位数字的字符常量写入LCD
}
else{
WriteData(digit[j]); //将十位数字的字符常量写入LCD
}
WriteData(digit[k]); //将十位数字的字符常量写入LCD
WriteData(digit[l]); //将个位数字的字符常量写入LCD
delay(50); //延时1ms给硬件一点反应时间
}*/
/***************************** *****************************/ void pand()
{
if(sec==-1)sec=59;
if(sec==60)
{
sec=0;}
if(min==-1)min=59;
if(min==60)
{
min=0;}
if(h==-1)h=23;
if(h==24)
{
h=0;}
if(x==-1)x=6;
if(x==7){x=0;}
//星期
if(m==2) //判
断闰年
{
if(year%4==0)
{
if(d==30){d=1;}if(d==0)d=29;
}
if(year%4!=0)
{
if(d==29)d=1;if(d==0)d=28;
}
}
switch(m)
{
case 1:case 3:case 5:case 7:case 8:case 10:
case 12:
if(d==32)d=1;if(d==0)d=31;break;
case 4:case 6:case 9:case 11:
if(d==31){d=1;}if(d==0)d=30;break ;
} //月完
if(m==0)m=12;
if(m==13)
{m=1;}
if(year<12)year=99;
if(year==100){year=0;} }
void beef()
{
TMOD|=0x11;
TH1=60; TL1=176;
ET1=1;TR1=1;
}
/***************************** ****************************** ************/
/************************* **************************** 函数功能:判断液晶模块的忙碌状态
返回值:result。

result=1,忙碌;result=0,不忙
************************** *************************/
bit BusyTest(void)
{
bit result;
RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1; //E=1,才
允许读写
_nop_(); //空操作
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
result=BF; //将忙碌标志电平赋给result
E=0;
return result;
}
/************************* **************************** 函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
************************** *************************/
void Write_com (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0;
//根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0;
//E置低电平(写指令时,// 就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_(); //空操作两个机器周期,给硬件反应时间
P0=dictate; //将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();
//空操作四个机器周期,给硬件反应时间
E=1;
//E置高电平
_nop_();
_nop_();
_nop_();
_nop_();
//空操作四个机器周期,给硬件反应时间
E=0;
//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/************************* ****************************
函数功能:指定字符显示的实际地址
入口参数:x
************************** *************************/
void WriteAddress(unsigned char x)
{
Write_com(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/************************* **************************** 函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
************************** *************************/
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS 为高电平,RW为低电平时,可以写入数据
RW=0;
E=0; //E置低电平(写指令时,,
// 就是让E从0到1发生正跳变,所以应先置"0"
P0=y; //将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E 由高电平跳变成低电平时,液晶模块开始执行命令
}
/************************* **************************** 函数功能:对LCD的显示模式进行初始化设置
************************** *************************/
void LcdInt(void)
{
delay(15);
//延时15ms,首次写指令时应给LCD一段较长的反应时间
Write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
delay(5); //延时5ms
Write_com(0x38);
delay(5);
Write_com(0x38); //3次写
设置模式
delay(5);
Write_com(0x0c); //显示
模式设置:显示不开0c,有光标0e,光标闪烁0f
delay(5);
// Write_com(0x06); //显示
模式设置:光标右移,字符不移
delay(5);
Write_com(0x01); //清屏
幕指令,将以前的显示内容清除
delay(5);
}
void wendu(void)
{
unsigned char TL,TH,TN; //储存暂存器的温度低位
//unsigned char //储存暂存器的温度高位
unsigned char i,j; //储存温度的整数部分
//unsigned char TD;
//储存温度的小数部分
// LcdInitiate();
//将液晶初始化
// delaynms(5);
//延时5ms给硬件一点反应时间
if(Init_DS18B20()==0)
//display_error();
//display_explain();
//display_symbol();
//显示温度说明
// display_dot();
//显示温度的小数点
// display_cent();
//显示温度的单位
//不断检测并显示温度
{ flag=0;
ReadyReadTemp();
//读温度准备
TL=ReadOneChar(); //先读的是温度值低位
TH=ReadOneChar(); //接着读的是温度值高位
if((TH&0xf8)!=0x00)//
判断高五位得到温度正负标志
{
flag=1;
TL=~TL; //取反
TH=~TH; //取反
tltemp=TL+1; //低位加
1
TL=tltemp;
if(tltemp>255) TH++;
//如果低8位大于255,向高8位进1
TN=TH*16+TL/16;
//实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
i=TN/10;j=TN%10;
WriteAddress(0x49);WriteData('t'); WriteData(s[10]);WriteData(s[i]);Wr iteData(s[j]);
WriteData(0x27);WriteData(0x43);
//这样得出的是温度的整数部分,小数部分被丢弃了
//TD=(TL%16)*10/16;
//计算温度的小数部分,将余数乘以10再除以16取整,
}
else {TN=TH*16+TL/16;
//实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
//这样得出的是温度的整数部分,小数部分被丢弃了
//TD=(TL%16)*10/16;
//计算温度的小数部分,将余数乘以10再除以16取整,
i=TN/10;j=TN%10;
if(TN>8)
{
e=1;
}
WriteAddress(0x49);WriteData('t'); WriteData(0x3a);WriteData(s[i]);Wr iteData(s[j]);
WriteData(0x27);WriteData(0x43);
}
//这样得到的是温度小数部分的第一位数字(保留1位小数)
//display_temp1(TN);
//显示温度的整数部分
//display_temp2(TD);。

相关文档
最新文档