基于单片机的18B20温度采集与适时24C02存储方案设计.docx
《基于单片机的18B20温度采集与适时24C02存储方案设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的18B20温度采集与适时24C02存储方案设计.docx(25页珍藏版)》请在冰豆网上搜索。
基于单片机的18B20温度采集与适时24C02存储方案设计
基于单片机的温度采集与适时存储方案设计
摘要
本课题为基于STC89C52单片机的温度采集与适时存储功能设计。
系统不仅具有适时的温度采集功能,而且还具有将温度存储的功能,为一些场合需记录特殊温度提供了可能。
温度采集部分使用单总线的DS18B20温度传感器,用液晶LCD1602作为显示器,存储器件使用芯片AT24C02。
温度传感器DS18B20采集温度信号送给单片机处理,单片机再把温度数据送液晶显示器LCD1602显示,键盘是用来温度查询的,本设计还可以根据需要实时存储并显示一些必要的温度值。
关键词:
STC89C52单片机18B20LCD160224C02存储
Abstract
ThistopicisSTC89C52basedonsingle-chiptemperaturegatheringandtimelystoragefunctiondesign.Systemnotonlyhasthefunctionoftemperaturegatheringtimely,butalsohasthefunctionofstoragetemperaturewillneedsomeoccasionsforspecialtemperaturerecords.TemperaturegatheringpartusesingletemperaturesensorDS18B20buswithLCDdisplay,LCD1602,storagedevicesusedasAT24C02chips.TemperaturesensorDS18B20collectiontemperaturesignalprocessingchipmicrocontroller,forthetemperaturedatasentLCD1602LCDdisplayandkeyboardisused,thedesignofthetemperatureinquiresaccordingtostillcanreal-timedisplaysomenecessaryandstoragetemperature.
Keywords:
STC89C52microcontroller18B20LCD160224C02storage
一、方案选择与论证
按照系统的设计功能要求,本设计采用单片机软件系统实现,用单片机的自动控制能力配合按键控制,来控制温度的采集和适时存储。
确定设计系统由单片机主控模块、测温模块、显示模块、按键接口模块和存储模块共五个模块组成,电路系统框图如图1所示。
1)显示方案选择
方案一:
温度的显示可以用数码管,但数码管的只能显示简单的数字,其电路复杂,占用资源较多,显示信息少,不宜显示大量信息。
方案二:
用液晶显示器LCD1602显示温度,其功耗小、体积小、显示内容丰富、超薄轻巧,且其内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形。
我们通过比较选择方案二。
2)温度采集方案选择
方案一:
采用SHT10来实现温度采集,SHT10是瑞士Sensirion公司生产的具有I2C总线接口的单片全校准数字式相对湿度和温度传感器。
该传感器采用独特的CMOSensTM技术,具有数字式输出、免调试、免标定、免外围电路及全互换的特点。
方案二:
温度传感器DS18B20是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9-12位的数字值读数方式,它内部有一个结构为8字节的高速暂存RAM存储器。
本设计只需采集温度,故我们通过比较选择方案二。
二、理论计算
2.1温度计算
实现温度的实时显示是由计算温度子程序将RAM中读取值进行BCD码的转换运算,并进行温度值正负的判定,从DS18B20读取出的二进制值必须先转换成十进制值,才能用于字符显示。
因为DS18B20的转换精度为9-12位可选的,为了提高精度采用12位。
在采用12位转换精度时,温度寄存器里德值是以0.0625为步进的,即温度值为温度寄存器里德二进制值乘以0.0625,就是实际的十进制温度值。
华氏温度与摄氏温度的转换公式:
摄氏:
C=5/9ºC(F-32)华氏:
F=9/5ºC+32
计算温度子程序流程图见图2图2
三6{;F;tj6?
#b0r9hfG]x0三三、硬件的设计与实现
根据方案的选择,系统由AT89C52、显示电路、测温电路和键盘电路组成。
其电路如图3所示:
注:
接口有错,从网上找的图,24C02也没画上去,具体节后见程序端口定义。
四,软件部分
硬件部分不多说了,时间很紧,软件里写的很详细,请参考者仔细阅读程序。
使用注意:
由于程序是模块化设计的,所以使用时应根据各模块程序类型来复制粘贴。
下面附一个本人调试时的界面图,供大家参考。
1.18b20驱动程序
///*************18b20.h********///////
#ifndef__18b20_h__
#define__18b20_h__
#include
#include<18b20.h>
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P1^3;
externvoidread_ds18b20();
externvoiddelay(uinti);
externvoidInit_DS18B20(void);
externunsignedcharReadOneChar(void);
externvoidWriteOneChar(uchardat);
externunsignedintReadTemperature(void);
#endif
///*************18b20.c********///////
/*--------------程序名称:
18b20驱动程序--------------------------------------------------------*/
/*--------------出口信息:
读出温度值后,返回值为t,使用时,把t值付给一个Int型变量即可使用------*/
/*--------------注意:
温度值t为int型,高四位为0------------------------------------------------*/
/*--------------作者:
孟良---------------------------------------------------------------------*/
/*--------------单位:
安徽建筑工业学院---------------------------------------------------------*/
/*--------------时间:
2010.8.27----------------------------------------------------------------*/
#include
#include<18b20.h>
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
/*******************延时函数******************/
voiddelay(uinti)
{
while(i--);
}
/******************************************************************/
/*初始化*/
/*****************************************************************/
voidInit_DS18B20(void)
{
unsignedcharx=0;
DQ=1;//DQ复位
delay(8);//稍做延时
DQ=0;//单片机将DQ拉低
delay(80);//精确延时大于480us
DQ=1;//拉高总线
delay(10);
x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败
delay(5);
}
//读一个字节
unsignedcharReadOneChar(void)
{
uintj=0;
uchardat=0;
for(j=8;j>0;j--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay(5);
}
return(dat);
}
//写一个字节
voidWriteOneChar(uchardat)
{
uchark=0;
for(k=8;k>0;k--)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(5);
}
//读取温度
unsignedintReadTemperature(void)
{
unsignedchara=0;
unsignedintb=0;
unsignedintt=0;
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
delay(200);
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
a=ReadOneChar();//低位
b=ReadOneChar();//高位
b<<=8;
t=a+b;
if(t==0x0550)//屏蔽第一次显示85
return(0);
else
return(t);
}
2.1602驱动程序
//////////////*1602.h*********////////
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitrs=P2^4;
sbitrw=P2^5;
sbite=P2^6;
voiddelay_1ms(uintz);
voidinit_1602();
voidwrite_1602_com(ucharcom);
voidwrite_1602_dat(uchardate);
voiddelay_1ms(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidinit_1602()
{
delay_1ms(15);
write_1602_com(0x38);//显示模式设置,不检测忙信号
write_1602_com(0x0c);//开显示,显示光标,闪烁
write_1602_com(0x06);//当读或写一个字节后,地址加1,光标向后移一字节
write_1602_com(0x80);//光标显示在第一行第一个字节
}
voidwrite_1602_com(ucharcom)
{
rs=0;
rw=0;
P0=com;
delay_1ms(5);
e=1;
delay_1ms(5);
e=0;
}
voidwrite_1602_dat(uchardate)
{
rs=1;
rw=0;
P0=date;
delay_1ms(5);
e=1;
delay_1ms(5);
e=0;
}
3.24c02驱动程序
////////////24c02.H//////////
#ifndef__24C02_h__
#define__24C02_h__
#include
#defineucharunsignedchar
#defineuinrunsignedint
#defineAddWr0xae
#defineAddRd0xaf
sbitwp=P1^0;
sbitscl=P1^1;
sbitsda=P1^2;
externvoidmDelay(unsignedcharj);
externvoidStart(void);
externvoidStop(void);
externvoidAck(void);
externvoidNoAck(void);
externvoidSend(unsignedcharData);
externunsignedcharRead(void);
externvoidWrToROM(unsignedcharData[],unsignedcharAddress,unsignedcharNum);
externvoidRdFromROM(unsignedcharData[],unsignedcharAddress,unsignedcharNum);
externvoidSend_Byte_add(ucharaddress,uchardate);
externucharRead_Byte_add(ucharaddress);
#endif
/*******************************************************************************
*标题:
24C02调试*
*
*要写入和读出的值都是放在table中,想办法把给要显示的值给table就行,但是本C程序根据调试,
写入数组数据时较方便,而写入单个的数或变化着的数不是太方便。
为此,在此C函数中加入写入
和读出单个字节的函数就较方便。
*作者:
孟良
*单位:
安徽建筑工业学院*
*时间:
2010.8.26*
********************************************************************************/
#include
#include
#include<24c02.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineAddWr0xae
#defineAddRd0xaf
/*------------------------------------------------
延时程序
------------------------------------------------*/
/*voidmDelay(unsignedcharj)
{
unsignedinti;
for(;j>0;j--)
{
for(i=0;i<125;i++)
{;}
}
}
*/
/*------------------------------------------------
启动IIC总线
------------------------------------------------*/
voidStart(void)
{
sda=1;
_nop_();_nop_();
scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
sda=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
scl=0;
}
/*------------------------------------------------
停止IIC总线
------------------------------------------------*/
voidStop(void)
{
sda=0;
_nop_();
scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
sda=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
scl=0;
}
/*------------------------------------------------
应答IIC总线
------------------------------------------------*/
voidAck(void)
{
sda=0;
_nop_();_nop_();_nop_();
scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
scl=0;
_nop_();_nop_();
}
/*------------------------------------------------
非应答IIC总线
------------------------------------------------*/
/*voidNoAck(void)
{
sda=1;
_nop_();_nop_();_nop_();
scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
scl=0;
_nop_();_nop_();
}
/*------------------------------------------------
发送一个字节
------------------------------------------------*/
voidSend(unsignedcharData)
{
unsignedcharBitCounter=8;
unsignedchartemp;
do
{
temp=Data;
scl=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
if((temp&0x80)==0x80)
sda=1;
else
sda=0;
scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
scl=0;
}
/*------------------------------------------------
读入一个字节并返回
------------------------------------------------*/
unsignedcharRead(void)
{
unsignedchartemp=0;
unsignedchartemp1=0;
unsignedcharBitCounter=8;
sda=1;
do
{
scl=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
if(sda)
temp=temp|0x01;
else
temp=temp&0xfe;
if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}
while(BitCounter);
return(temp);
}
voidSend_Byte_add(ucharaddress,uchardate)//向24C02写入一个字节函数
{
Start();
Send(AddWr);
Ack();
Send(address);
Ack();
Send(date);
Ack();
Stop();
}
ucharRead_Byte_add(ucharaddress)//从24C02读出一个字节函数
{
uchardate;
Start();
Send(AddWr);
Ack();
Send(address);
Ack();
Start();
Send(AddRd);
Ack();
date=Read();
Stop();
returndate;
}
/*------------------------------------------------
写入数据
------------------------------------------------*/
/*voidWrToROM(unsignedcharData[],unsignedcharAddress,unsignedcharNum)
{
unsignedchari;
unsignedchar*PData;
PData=Data;
for(i=0;i{
Start();
Send(AddWr);//写入芯片地址
Ack();
Send(Address+i);//写入存储地址
Ack();
Send(*(PData+i));//写数据
Ack();
Stop();
mDelay(20);
}
}*/
/*------------------------------------------------
读出数据
------------------------------------------------*/
/*voidRdFromROM(unsignedcharData[],unsignedcharAddress,unsignedch