DS18B20温度采集与显示系统设计.docx
《DS18B20温度采集与显示系统设计.docx》由会员分享,可在线阅读,更多相关《DS18B20温度采集与显示系统设计.docx(34页珍藏版)》请在冰豆网上搜索。
DS18B20温度采集与显示系统设计
•实验专题描述
—实验目的和实验功能
—系统硬件及软件
——STC单片机介绍
•实验原理与方法
—DS18C20简单原理介绍
—LCD1602简单原理介绍
—AT24C02简单原理介绍
•实验结果与讨论
-专题制作过程中所遇到的困难与解決方法
•心得与体会
•程序码
一、实验专题描述
单片机综合实验的目的是训练单片机应用系统的编程及调试能力,通过对一个单片机应用系统进行系统的编程和调试,掌握单片机应用系统开发环境和仿真调试工具及仪器仪表的实用,掌握单片机应用程序代码的编写和编译,掌握利用单片机硬件仿真调试工具进行单片机程序的跟踪调试和排错方法,掌握示波器和万用表等杆塔工具在单片机系统调试中应用。
利用STC89C52、DS18B20、LCD1602、AT24C02等元器件设计温度采集与显示系统。
系统具有以下功能:
1、能正确检测温度;
2、在1602上实时显示温度;
3、每隔10秒采集一次温度数据并保存到AT24C02
4、按键按下后,可逐个显示之前采集到的数据;
5、其他功能可根据系统上的资源自行设定。
扩展功能:
温度超过设定值,蜂鸣器报警;时间日期的显示;按键按下,重新开始采集温度等等
硬件组成:
本系统所用的硬件有如下图
序号
参数
数量
备注
1
STC89C52
1
单片机
2
DIP40针IC座
1
3
8针排针
4
4
MAX232E
1
串口下载
5
DIP16针IC座
1
6
DB9公头
1
7
0.1u瓷片电容
4
8
0.1u瓷片电容
4
9
DS18B20
1
温度传感器
10
3P圆孔座
1
18
5V有源蜂鸣器
1
蜂鸣器
19
100欧电阻
1
20
红色LED
8
LED显示
21
1K排阻
1
22
8针排针
1
23
按键
6
中断电路
25
1K欧电阻
3
26
11.0592M晶振
1
时钟电路
27
22p瓷片电容
2
28
10u瓷片电容
1
复位电路
29
10K欧电阻
5
30
按键
1
31
直流电源插座
1
稳压电源
32
LM7805稳压芯片
1
33
0.33u瓷片电容
2
34
导线,杜邦线
若干
35
AT24C02(DIP封装)
1
存储电路
软件组成
软件有:
keil软件、windows操作系统和串口调试助手等软件组成。
STC单片机介绍
单片机是随着大规模集成电路的出现极其发展,将计算机的CPU,RAM,ROM,定时/计数器和多种I/O接口集成在一片芯片上,形成了芯片级的计算机,因此单片机早期的含义称为单片微型计算机(singlechipmicrocomputer).它拥有优异的性价比、集成度高、体积小、可靠性高、控制功能强、低电压、低功耗的显著优点.主要应用于智能仪器仪表、工业检测控制、机电一体化等方面,并且取得了显著的成果.
图2-1单片机封装及引脚结构
DS18B20数字温度传感器介绍
DALLAS最新单线数字温度传感器DS18B20的“一线器件”体积更小、适用电压更宽、更经济Dallas半导体公司的数字化温度传感器DS1820是世界上第一片支持“一线总线”接口的温度传感器。
表2-1DS18B20内部温度表示形式
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的E2PPRAM,后者存放高温度和低温度触发器TH、T和结构寄存器。
暂存存储器包含了8个连续字节,前两个字节是测得的温度信息,第一个字节的内容是温度的低八位,第二个字节是温度的高八位。
第三个和第四个字节是TH、TL的易失性拷贝,第五个字节是结构寄存器的易失性拷贝,这三个字节的内容在每一次上电复位时被刷新。
第六、七、八个字节用于内部计算。
第九个字节是冗余检验字节,见表2-3。
表2-3DS18B20暂存存储器的8个连续字节
寄存器内容
字节地址
温度最低数字位
0
温度最高数字位
1
高温限值
2
低温限值
3
保留
4
保留
5
计数剩余值
6
每度计数值
7
CTR校验
8
实验原理与方法
一、通过DS18B20采集温度数据,经I/O口传给单片机,单片机对接收到的数据进行实时在lcd上显示,并十秒采集通过I2C总线送到24c02进行储存,当按键按下时进入外部中断,并在外部中断中进行读取24c02所保存的值并在lcd上显示;拓展功能部分:
在lcd的第二行显示时钟,并配有按键进行调时;温度报警电路,当温度上升到一定值时给蜂鸣器低信号,使其响起。
二、LCD顯示控制格式
实验结果与讨论
一、原理图
二、仿真结果
三、硬件结果
软件部分主要遇到的问题是温度采集保存到24c02模块,用一个字发送或者两个字节发送都会出问题,最后用八个字节发送就解决了此问题;关于显示部分,显示放在中断里执行会出现乱码,而放到主程序中则不会。
硬件部分主要是复位电路没焊好会使电路一直处于复位状态,反应出来结果就是无法显示任何内容。
由于老师给的原理图是公头,而发下来的器件是母头,自己没有注意检查,到最后烧写程序的时候才发现,导致只能用开发板来烧写,给程序调试工作增加了很多工作量,并且单片机在拆卸过程中很容易损坏。
我们在调试过程一定要十分小心谨慎,因为有些芯片都是很容易烧坏的,稍有不慎就会导致某块芯片烧坏而导致实验结果出不来失败。
其中我们在检查电路的时候一定要注意检查电路板的短路和虚焊的问题,要经过反复的用万用表不停的检测,由于电路连线比较复杂,所以在测试电路的问题上花了好多的时间。
在本次实验中我们碰到的最大的问题就是LCD显示不能读取温度并显示,最终我们通过不断的检查电路和修改发现由于复位电路由一条线没有接地的原因,解决了就可以了啦。
心得与体会
在本次实验中,我们小组分工合作,首先要对所用的芯片进行了解和查找资料。
在设计过程中protues仿真对设计来说也是很重要的,利用温度传感器和时钟芯片进行对温度实践的检测,再将检测到的数据传送单片机经过程序的处理给LCD显示,在程序的调试过程中,主要注意的就是时间延迟函数和中断读取的设置。
通过这次对温度采集和显示的设计与制作,让我们了解了设计电路的程序,也让我们了解了关于单片机的原理与设计理念,要设计一个电路总要先用仿真仿真成功之后才实际接线的。
但是最后的成品却不一定与仿真时完全一样,因为,再实际接线中有着各种各样的条件制约着。
而且,在仿真中无法成功的电路接法,在实际中因为芯片本身的特性而能够成功。
所以,在设计时应考虑两者的差异,从中找出最适合的设计方法。
通过这次学习,让我对各种电路都有了大概的了解,所以说,坐而言不如立而行,对于这些电路还是应该动手实际操作才会有深刻理解。
从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高,这就是我在这次课程设计中的最大收获。
成员苏晓峰记——
在程序调试过程中,通过按键切换设置时间、当前温度和存储的温度一次显示在LCD上,在如何读取温度上的程序有些困惑,不知道用什么方法来写,自己上网查找各种资料,最后决定用中断来写,但调试过程而然碰到了LCD显示出错了,而且并没有按照存储的数据顺序显示。
通过几个晚上的思考和不断调试,不断的修改,总算是成功了。
成员郑元凯记——
在实验设计之前自己上网查找所用芯片的资料各种管脚接口和类似的一些这次实验作为参考,为设计过程中可能会产生的问题进行分析,尽可能的避免错误。
但理论和实践还是有一定的差距的,不过在大家的努力下一一克服了。
仿真后准备开始焊接电路前要进行电路的布局和线路的连接,最大化的减少交叉线和跑线,使电路板看上去简单明了。
成员梁斌记——
负责焊接的工作有点难度,不止考验焊接的功力还要有足够的耐心,根据已经布局好的电路进行焊接,省下了不少心力。
每每焊接一部分,都要用万用表检查是否连接正确或者有存在虚焊的情况,尽可能的避免错误。
完成后将程序烧录进去结果不能读取温度,大家都很着急,一起重新的检查,通过最后的补救总算是找到错误修改之后成功了。
程序码
主程序
#include
#include
#definewarn_35350
#definewarn_11110
charmiao,shi,fen,flag;
uints1num;
ucharcount,m,n;
uintsu,tt,mm;
//ucharbuff[4];
unsignedcharpDat[7],pDat1[7];
sbits1=P2^3;
sbits2=P2^4;
sbits3=P2^5;
sbitbeep=P1^0;//蜂鸣器
voiddeal(uinttem)
{
if((tem>warn_35)||(tem{
beep=0;
}
elsebeep=1;
}
voidmain()
{
m=0;
n=0;
init();
EX0=1;
//init_com();//包含了对定时器0的设定
while
(1)
{
tempchange();
tt=get_temp();
if(flag==1)
{
EA=0;
flag=0;
IRcvStr(0xa0,n,&pDat1[0],8);
mm=pDat1[0]*100+pDat1[1]*10+pDat1[2];
//pDat1[7]=0;
n=n+0x08;
if(n==0xf8)
n=0;
EA=1;
}
deal(tt);
write_sfm(12,miao);
write_sfm(9,fen);
//write_sfm(6,shi);
dis_temp1(mm);
delay(5);
dis_temp(tt);
keyscan();
}
}
voidint_0()interrupt0
{
flag=1;
}
voidkeyscan()
{
if(s1==0)
{
delay(5);
if(s1==0)
{s1num++;
while(!
s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+12);
//write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+9);
}
if(s1num==3)
{
write_com(0x80+0x40+6);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
TR0=1;
}
}
if(s1num!
=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(12,miao);
write_com(0x80+0x40+12);//指针回原位
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(9,fen);
write_com(0x80+0x40+9);//指针回原位
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(6,shi);
write_com(0x80+0x40+6);//指针回原位
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
if(s1num==1)
{
/*if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}*/
miao--;
if(miao==-1)
miao=59;
write_sfm(12,miao);
write_com(0x80+0x40+12);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(9,fen);
write_com(0x80+0x40+9);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(6,shi);
write_com(0x80+0x40+6);
}
}
}
}
}
voidtimer0()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
su++;
if(su==100)
{
su=0;
pDat[0]=tt/100;
pDat[1]=(tt%100)/10;
pDat[2]=tt%10;
ISendStr(0xa0,m,&pDat[0],8);//存温度
//pDat[7]=0;
m=m+0x08;
if(m==0xf8)
m=0;
}
count++;
if(count==20)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
//write_sfm(4,shi);
}
//write_sfm(7,fen);
}
//write_sfm(10,miao);
}
}
温感部分
#include
#include
#include
sbitds=P1^1;//温度传感器信号线
//sbitbeep=P2^3;//蜂鸣器
uinttemp;
floatf_temp;
voiddsreset(void)//18B20复位,初始化函数
{
uinti;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bittempreadbit(void)//读1位函数
{
uinti;
bitdat;
ds=0;i++;//i++起延时作用
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
return(dat);
}
uchartempread(void)//读1个字节
{
uchari,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
voidtempwritebyte(uchardat)//向18B20写一个字节数据
{
uinti;
ucharj;
bittestb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)//写1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0;//写0
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}
voidtempchange(void)//DS18B20开始获取温度并转换
{
dsreset();
delay
(1);
tempwritebyte(0xcc);//写跳过读ROM指令
tempwritebyte(0x44);//写温度转换指令
}
uintget_temp()//读取寄存器中存储的温度数据
{
uchara,b;
dsreset();
delay
(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a=tempread();//读低8位
b=tempread();//读高8位
temp=b;
temp<<=8;//两个字节组合为1个字
temp=temp|a;
f_temp=temp*0.0625;//温度在寄存器中为12位分辨率位0.0625°
temp=f_temp*10+0.5;//乘以10表示小数点后面只取1位,加0.5是四舍五入
f_temp=f_temp+0.05;
returntemp;//temp是整型
}
////////////////////显示程序调用lcd中的write_sfm1十位地址写4个位为5小数为7//////////////////////////
voiddis_temp(uintt)
{
uinti;
i=t/100;
write_sfm1(0,i);
i=(t%100)/10;
write_sfm1(1,i);
i=t%10;
write_sfm1(3,i);
}
voiddis_temp1(uintt)//显示储存的温度
{
uinti;
i=t/100;
write_sfm1(11,i);
i=(t%100)/10;
write_sfm1(12,i);
i=t%10;
write_sfm1(14,i);
}
/*voidinit_com(void)
{
TMOD=0x20;
PCON=0x00;
SCON=0x50;
TH1=0xFd;
TL1=0xFd;
TR1=1;
}
voidcomm(char*parr)
{
do
{
SBUF=*parr++;//发送数据
while(!
TI);//等待发送完成标志为1
TI=0;//标志清零
}while(*parr);//保持循环直到字符为'\0'
}
*/
//////////////////////////////////////////////
/*voidwarn(uints,ucharled)//蜂鸣器报警声音,s控制音调
{
uchari;i=s;
beep=0;
P1=~(led);
while(i--)
{
dis_temp(get_temp());
}
beep=1;
P1=0XFF;
i=s;
while(i--)
{
dis_temp(get_temp());
}
}
voiddeal(uintt)
{
uchari;
if((t>warn_l2)&&(t<=warn_l1))//大于25度小于27度
{
warn(40,0x01);
}
elseif(t<=warn_l2)//小于25度
{
warn(10,0x03);
}
elseif((t=warn_h1))//小于32度大于30度
{
warn(40,0x04);
}
elseif(t>=warn_h2)//大于32度
{
warn(10,0x0c);
}
else
{
i=40;
while(i--)
{
dis_temp(get_temp());
}
}
}*/
Lcd显示部分
#include
sbitrs=P2^6;
sbitlcden=P2^7;
//sbitrw=P2^5;
ucharcodetablenum[]="0123456789";
ucharcodetable[]="00.0CTemp:
00.0C";
ucharcodetable1[]="Time:
00:
00:
00";
ucharcodetable2[]="XIAOFENGYUANKAI";
ucharcodetable3[]="LIANGBIN";
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardat)
{
rs=1;
lcden=0;
P0=dat;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidinit()
{
ucharnum;
lcden=0;
//rw=0;
//fen=59;
//miao=53;
//shi=23;
write_com(0x38);
write_com(0x0c);
write_