18B20温度采集LCD12864显示.docx
《18B20温度采集LCD12864显示.docx》由会员分享,可在线阅读,更多相关《18B20温度采集LCD12864显示.docx(23页珍藏版)》请在冰豆网上搜索。
18B20温度采集LCD12864显示
18B20温度采集LCD12864显示
基于单片机STC89C51的温度显示系统的设计
引言
随着电子技术,特别是随大规模集成电路的产生而出现的微型计算机技术的飞速发展,人类生活发生了根本性的改变。
如果说微型计算机的出现使现代科学研究得到了质的飞跃,那么可以毫不夸张地说,单片机技术的出现则是给现代工业测控领域带来了一次新的技术革命。
目前,单片机以其体积小、重量轻、抗干扰能力强、对环境要求不高、高可靠性、高性能价格比、开发较为容易,在工业控制系统、数据采集系统、智能化仪器仪表、办公自动化等诸多领域得到极为广泛的应用,并已走人家庭,从洗衣机、微波炉到音响、汽车,到处都可见到单片机的踪影。
因此,单片机技术开发和应用水平已逐步成为一个国家工业发展水平的标志之一。
本课题研究的内容就是以单片机为主要控制元件,通过温度传感器DS18B20实现对温度的测量,并通过LCD12864直接显示所测温度。
1、设计任务
用温度传感器DS18b20检测空气中的温度,STC89C51采集DS18B20的数据并通过LCD12864显示实时温度。
2、系统硬件设计
2.1系统方框图
见图2-1.
图3-1系统方框图
2.2各模块方案的选择
方案一:
采用热电偶或热敏电阻作感温元件,但热电偶需冷端补偿,电路设计复杂,热敏电阻虽然精度较高,但需要标准稳定电阻匹配才能使用,而且重复性、可靠性都比较差。
方案二:
采用集成温度传感器DS18B20。
该传感器结构简单,不需外接电路,数据传输采用one-wire。
总线,可用一根I/O数据线即供电又传输数据,在-10℃--+85℃范围内精度为±0.5℃,分辨率较高,重复性和可靠性好。
故采用方案二。
方案一:
采用数码管显示。
数码管亮度高、体积小、重量轻,但其显示信息简单、有限,在本题目中应用受到很大的限制。
方案二:
采用液晶显示。
液晶显示功耗低,轻便防震。
采用液晶显示界面友好清晰,操作方便,显示信息丰富。
故采用方案二
2.3单片机控制系统
单片机作为整个硬件系统的核心,它既是协调整机工作的控制器,又是数据处理器。
它由单片机、时钟电路、复位电路等组成。
为了简化电路、降低成本、提高可靠性,本系统采用STC89C51作为主控制器,它是一款与MCS51完全兼容且内部自带有4KB的Flash存储器及256KBRAM单元的芯片,因此可以不需另外扩展EEPROM及静态RAM就可以实现所需功能。
单片机最小系统是软硬件系统连接的桥梁。
它包括:
单片机89C51,LCD12864液晶模块,DS18B20温度采集模块。
单片机的时钟信号用来提供单片机片内各种微操作的时间基准,时钟信号通常用两种电路形式得到:
内部振荡和外部振荡。
MCS-51单片机内部有一个用于构成振荡器的高增益反向放大器,引脚XTALl和XTAL2分别是此放大电器的输入端和输出端,由于采用内部方式时,电路简单,所得的时钟信号比较稳定,实际使用中常采用这种方式,如图所示在其外接晶体振荡器(简称晶振)或陶瓷谐振器就构成了内部振荡方式,片内高增益反向放大器与作为反馈元件的片外石英晶体或陶瓷谐振器一起可构成一个自激振荡器并产生振荡时钟脉冲。
下图中外接晶体以及电容C2和C1构成并联谐振电路,它们起稳定振荡频率、快速起振的作用,其值均为30P左右,晶振频率选6MHz。
为了初始化单片机内部的某些特殊功能寄存器,必须采用复位的方式,复位后可使CPU及系统各部件处于确定的初始状态,并从初始状态开始正常工作。
单片机的复位是靠外电路来实现的,在正常运行情况下,只要RST引脚上出现两个机器周期时间以上的高电平,即可引起系统复位,但如果RST引脚上持续为高电平,单片机就处于循环复位状态。
复位操作有两种情况,即上电复位和手动(开关)复位。
本系统采用上电复位方式。
图2-2中R9和Cl组成上电复位电路,其值R取为1K,C取为22μF.
图3-2单片机最小系统
2.4温度检测模块
由DALLAS半导体公司生产的DS18B20型单线智能温度传感器,属于新一代适配微处理器的智能温度传感器,可广泛用于工业、民用、军事等领域的温度测量及控制仪器、测控系统和大型设备中。
它具有体积小,接口方便,传输距离远等特点。
DS18B20性能特点
①采用单总线专用技术,既可通过串行口线,也可通过其它I/O口线与微机接口,无须经过其它变换电路,直接输出被测温度值(9位二进制数,含符号位)。
②测温范围为-55℃-+125℃,测量分辨率为0.0625℃。
③内含64位经过激光修正的只读存储器ROM。
④适配各种单片机或系统机。
⑤用户可分别设定各路温度的上、下限。
⑥内含寄生电源。
DS18B20内部结构主要由四部分组成:
64位光刻ROM,温度传感器,非挥发的温度报警触发器TH和TL,高速暂存器。
64位光刻ROM是出厂前被光刻好的,它可以看作是该DS18B20的地址序列号。
64位ROM结构图如图2所示。
不同的器件地址序列号不同。
DS18B20的管脚排列如图5-1所示。
图3-4-2DS18B20引脚分布图
DS18B20高速暂存器共9个存储单元,如表所示:
序号
寄存器名称
作 用
序号
寄存器名称
0
温度低字节
以16位补码形式存放
4
配置寄存器
1
温度高字节
5、6、7
保留
2
TH/用户字节1
存放温度上限
8
CRC
3
HL/用户字节2
存放温度下限
表3-4-3DS18B20高速暂存器
以12位转化为例说明温度高低字节存放形式及计算:
12位转化后得到的12位数据,存储在18B20的两个高低两个8位的RAM中,二进制中的前面5位是符号位。
如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625才能得到实际温度。
高8位
S
S
S
S
S
26
25
24
低8位
23
22
21
20
2-1
2-2
2-3
2-4
DS18B20有六条控制命令,如表所示:
指 令
约定代码
操 作 说 明
温度转换
44H
启动DS18B20进行温度转换
读暂存器
BEH
读暂存器9个字节内容
写暂存器
4EH
将数据写入暂存器的TH、TL字节
复制暂存器
48H
把暂存器的TH、TL字节写到E2RAM中
重新调E2RAM
B8H
把E2RAM中的TH、TL字节写到暂存器TH、TL字节
读电源供电方式
B4H
启动DS18B20发送电源供电方式的信号给主CPU
表3-4-4DS18B20控制命令
DS18B20器件要求采用严格的通信协议,以保证数据的完整性。
该协议定义了几种信号类型:
复位脉冲,应答脉冲时隙;写0,写1时隙;读0,读1时隙。
与DS18B20的通信,是通过操作时隙完成单总线上的数据传输。
发送所有的命令和数据时,都是字节的低位在前,高位在后。
复位和应答脉冲时隙
每个通信周期起始于微控制器发出的复位脉冲,其后紧跟DS18B20发出的应答脉冲,在写时隙期间,主机向DS18B20器件写入数据,而在读时隙期间,主机读入来自DS18B20的数据。
在每一个时隙,总线只能传输一位数据。
时序图见图
图
3-4-5-1DS18B20复位时序图
写时隙
当主机将单总线DQ从逻辑高拉到逻辑低时,即启动一个写时隙,所有的写时隙必须在60~120us完成,且在每个循环之间至少需要1us的恢复时间。
写0和写1时隙如图所示。
在写0时隙期间,微控制器在整个时隙中将总线拉低;而写1时隙期间,微控制器将总线拉低,然后在时隙起始后15us之释放总线。
3-4-5-2DS18B20写时序图
读时隙
8B20器件仅在主机发出读时隙时,才向主机传输数据。
所以在主机发出读数据命令后,必须马上产生读时隙,以便DS18B20能够传输数据。
所有的读时隙至少需要60us,且在两次独立的读时隙之间,至少需要1us的恢复时间。
每个读时隙都由主机发起,至少拉低总线1us。
在主机发起读时隙之后,DS18B20器件才开始在总线上发送0或1,若DS18B20发送1,则保持总线为高电平。
若发送为0,则拉低总线当发送0时,DS18B20在该时隙结束后,释放总线,由上拉电阻将总线拉回至高电平状态。
DS18B20发出的数据,在起始时隙之后保持有效时间为15us。
因而主机在
读时隙期间,必须释放总线。
并且在时隙起始后的15us之内采样总线的状态。
3-4-5-3DS18B20写读序图
采用集成温度传感器DS18B20。
该传感器结构简单,不需外接电路,数据传输采用one-wire。
总线,可用一根I/O数据线即供电又传输数据,在-10℃--+85℃范围内精度为±0.5℃,分辨率较高,重复性和可靠性好。
图3-3DS18B20电路
DS18B20为单总线器件,数据和命令在一根线上传输,先向温度传感器写入转换命令,延长一段时间,再发送读命令,将温度值读回单片机,单片机进行数据处理,送显示。
转换关系为:
T=temperature*6.25
T为单片机要显示的温度,temperature为从DS18B20读回的数字量。
图中TEM接单片机P0^6口
2.5液晶显示模块
LCD12864是一款具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64,内置8192个16*16点汉字,和128个16*8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。
可以显示8×4行16×16点阵的汉字.也可完成图形显示.低电压低功耗是其又一显著特点。
由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。
管脚号
名称
LEVEL
功能
1
VSS
0V
电源地
2
VDD
+5V
电源正(3.0V-5.5V)
3
VO
-
对比度(亮度)调整
4
CS
H/L
模组片选端,高电平有效
5
SID
H/L
串行数据输入端
6
CLK
H/L
串行同步时钟:
上升沿时读取SID数据
15
PSB
L
L:
端口方式
17
/RESET
H/L
复位端
19
A
VDD
背光源电压+5V
20
K
VSS
背光源负端0V
RS,R/W的配合选择决定控制界面的四种模式
BF忙标志位
字形产生ROM
显示数据RAM
字形产生RAM
地址计数器AC
数据传输过程
时序图
串口读写时序
D0—D7接单片机P2口,RES接高电平,RS、RW、LCD-E分别接P0^3,P0^4,P0^5口。
3、系统软件设计
3.1C51语言的优缺点
现在有四种语言支持8051系列单片机编程,即汇编、PL/M,C和BASIC,在开发中最常用的是汇编语言,但随着程序复杂程度的提高,汇编语言逐渐暴露了它的不足,BASIC适合于初学者或要求编程简单而对编程效率和运行速度不高的场合。
PL/hi对8051系列单片机来讲,不支持复杂的算术运算和浮点变量,无丰富的库函数支持。
C语言是一种源于编写UNIX操作系统的语言,是一种结构化语言,可产生紧凑代码。
为了更好地实现对单片机的开发,C51应运而生。
每个不同公司开发的C51不尽相同,本系统采用的是KeilElektronikGmbh开发的KeiluVision3工具软件来进行系统软件编写和调试的。
在嵌入式系统中,相对于汇编语言,C语言作为一种高级语言主要存在两个不足:
一,生成的可执行代码冗长,效率不高。
对于这一点,随着处理芯片运算速度的提高、集成ROM的扩大,特别编译系统的不断优化,冗长已经不再是问题。
这也是C在嵌入式系统中逐渐成为主流编程语言的主要原因之一。
二,C生成的可执行代码在时序上不容易控制,比如本系统中要实现的时序控制。
一般的解决方案是在C程序中嵌入汇编语句,但其实只要充分挖掘C的潜力,在时序要求严格的场合完全可以用C语言实现。
具体方法就是阅读开发环境给我们提供的反汇编代码。
反汇编代码一目了然的反映了微控器的运行时序,然后根据反汇编代码修改C源程序。
3.2程序设计
3.2.1程序流程图
3.2.2液晶显示流程图程图
3.2.3温度传感器流程图程图
4、仿真与调试
首先调试液晶程序。
单片机STC89C51的P2口接液晶数据口,根据液晶手册,将RS1和RE借口接高电平;RS、R/W、EN接口接单片机P0^3,P0^4,P0^5口,单独调试液晶程序,将hex文件下载到单片机,看看是否在液晶第一排是否显示“温度”,在第三排是否显示“液晶温度显示”
然后根据DS18B20的手册书写程序,将液晶程序设为头文件,若DS18B20程序无误,则在液晶的第一排首位开始会显示“温度”,第二排的第三个字符开始会显示温度值XX℃,第三排不显示,第四排首位开始显示“液晶温度显示”。
如果程序有误,则再看看芯片资料和程序的书写是否有出入,如有错误则再更正,直至显示正确为止。
5、结论
根据题目要求,我们完成了液晶温度显示系统的设计,分别写出了液晶12864的程序和DS18B20的程序,完成了温度检测模块、液晶显示模块的设计,达到了题目的功能要求。
在这个过程中,我们对LCD12864和DS18B20的芯片资料做了分析和了解,特别是液晶模块,它的显示量大且接口简单,占用单片机I/O口少,如果单片机的对外借口欠缺是,我们还可以在电路中使用74HC595,这样单片机输出数据端口可以重8位缩减到3位,大大缩小了单片机I/O口得使用。
6、收获与体会
在本设计中,我们重点放在了液晶显示应用上,将液晶模块从程序中单独制成头文件,对液晶的命令字和显示做了分析,做到了可以在液晶的指定位置显示数据。
另外,本设计中我们也对我们的单片机软件和硬件知识做了一个整体的复习。
因为,要想编写出一个系统的程序,就必须十分清楚硬件电路中所用芯片的工作原理以及使用它们的一些注意事项。
在完成任务的过程中,我们先后应用keil3对程序进行编译和修改,是开发板上实验,用ALtiumdesigner绘制电路图和PCB图,因而,本次实训中,我收获很多,明白了看似简单的问题也要对其进行深入分析,特别是芯片的官方资料的理解,才能真正的掌握和运通它。
由于时间和本身知识水平的发挥,我们认为本系统还有需要改进和提高的地方,例如液晶可以显示图形,系统中可以设计报警器等。
这让我明白:
在以后的学习工作中,不仅要有刻苦努力,还要有钻研精神。
附录
1、整体电路图
2、主函数
#include
#include"yejing.h"
#defineucharunsignedchar
#defineuintunsignedint
#include
sbitDQ=P3^2;//数据口defineinterface
uinttemp;//温度值variableoftemperature
voiddelay2(unsignedchari)//延时函数
{
while(--i);
}
voidInit_Ds18b20(void)//DS18B20初始化sendresetandinitializationcommand
{
DQ=1;//DQ复位,不要也可行。
delay2
(1);//稍做延时
DQ=0;//单片机拉低总线
delay2(250);//精确延时,维持至少480us
DQ=1;//释放总线,即拉高了总线
delay2(100);//此处延时有足够,确保能让DS18B20发出存在脉冲。
}
ucharRead_One_Byte()//读取一个字节的数据readabytedate
//读数据时,数据以字节的最低有效位先从总线移出
{
uchari=0;
uchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//将总线拉低,要在1us之后释放总线
//单片机要在此下降沿后的15us内读数据才会有效。
_nop_();//至少维持了1us,表示读时序开始
dat>>=1;//让从总线上读到的位数据,依次从高位移动到低位。
DQ=1;//释放总线,此后DS18B20会控制总线,把数据传输到总线上
delay2
(1);//延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分
if(DQ)//控制器进行采样
{
dat|=0x80;//总线为1,DQ为1,那就把dat的最高位置1;若为0,不处理,保持0
}
delay2(10);//此延时不能少,确保读时序的长度60us。
}
return(dat);
}
voidWrite_One_Byte(uchardat)
{
uchari=0;
for(i=8;i>0;i--)
{
DQ=0;//拉低总线
_nop_();//至少维持了1us,表示写时序(包括写0时序或写1时序)开始
DQ=dat&0x01;//从字节的最低位开始传输
//指令dat的最低位赋予给总线,必须在拉低总线后的15us内,
//因为15us后DS18B20会对总线采样。
delay2(10);//必须让写时序持续至少60us
DQ=1;//写完后,必须释放总线,
dat>>=1;
delay2
(1);
}
}
uintGet_Tmp()//获取温度getthetemperature
{
floattt;
uchara,b;
Init_Ds18b20();//初始化
Write_One_Byte(0xcc);//忽略ROM指令
Write_One_Byte(0x44);//温度转换指令
Init_Ds18b20();//初始化
Write_One_Byte(0xcc);//忽略ROM指令
Write_One_Byte(0xbe);//读暂存器指令
a=Read_One_Byte();//读取到的第一个字节为温度LSB
b=Read_One_Byte();//读取到的第一个字节为温度MSB
temp=b;//先把高八位有效数据赋于temp
temp<<=8;//把以上8位数据从temp低八位移到高八位
temp=temp|a;//两字节合成一个整型变量
tt=temp*0.0625;//得到真实十进制温度值,DS18B20可以精确到0.0625度
//所以读回数据的最低位代表的是0.0625度
temp=(uint)(tt*10+0.5);//放大十倍,目的是将小数点后第一位也转换为可显示数字
returntemp;
}
voidmain()
{
P0=0;
delay(50);
init();
delay(10);
show();
while
(1)
{
display(Get_Tmp());
}
}
液晶头文件
#ifndef__yejing_H__
#define__yejing_H__
#defineucharunsignedchar
#defineuintunsignedint
ucharCMDAddress;
sbitRS=P2^5;
sbitRW=P2^1;
sbitEN=P2^2;
voiddelay(uchart)//延时函数
{
uintx,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}
bitbusy()//判忙标志位
{
bitflag;
RS=0;
RW=1;
EN=1;
flag=(bit)(P0&0x80);
EN=0;
returnflag;
}
voidwrite_cmd(ucharcmd)//写命令字
{
while(busy());
RW=0;
RS=0;
delay(5);
P0=cmd;
EN=1;
delay(5);
EN=0;
delay(5);
}
voidwrite_date(uchardat)//写数据
{
while(busy());
RW=0;
RS=1;
delay(5);
P0=dat;
EN=1;
delay(5);
EN=0;
delay(5);
}
voidinit()//初始化
{
delay(100);
write_cmd(0x30);//ExtendedFunctionSet(功能设定控制字)基本指令集,8位
delay
(1);
write_cmd(0x30);//FunctionSet基本指令集
delay
(1);
write_cmd(0x0c);//(显示开关控制字),全部显示ON,游标OFF,闪烁OFF
delay
(1);
write_cmd(0x01);//清屏控制字
delay(15);
write_cmd(0x06);//EntryMode(进入设定点控制字)光标从左向右加一位移动
delay
(1);
}
voidSetAddress(ucharx,uchary)//设置输入数据位置
{
switch(y)
{
case0:
CMDAddress=0x80+x;break;
case1:
CMDAddress=0x90+x;break;
case2:
CMDAddress=0x88+x;break;
case3:
CMDAddress=0x98+x;break;
}
write_cmd(CMDAddress);
}
voidputstring(ucharx,uchary,uchar*pdate)//该行是否完
{
SetAddress(x,y);
while(*pdate!
='\0')
{
write_date(*pdate++);
}
}
voidshow()//显示“温度”
{
putstring(0,0,"温度:
");//第一排首位子显示“温度”两字
putstring(0,3,"液晶温度显示");//第三排首位子显示“液晶温度显示”
}
voiddisplay(uintTemp)//显示温度值