单片机课程设计DS18B20测温及按键控制毕业设计.docx
《单片机课程设计DS18B20测温及按键控制毕业设计.docx》由会员分享,可在线阅读,更多相关《单片机课程设计DS18B20测温及按键控制毕业设计.docx(17页珍藏版)》请在冰点文库上搜索。
单片机课程设计DS18B20测温及按键控制毕业设计
单片机课程设计DS18B20测温及按键控制毕业设计
课程设计
课程名称单片机基础课程设计
题目名称18B20测温及按键控制
学生学院****
专业班级****
班号****
学生组员******
指导教师*****
2010-12-28
●第一章系统的概述及设计任务书……………………………………3
●第二章单元模块的设计与分析……………………………4
1、温度传感器的选择及构造…………………………4
2、单片机的选择及原理………………………………6
3、系统软件算法分析…………………………………6
●第三章实验程序……………………………………………6
1、实验程序…………………………………………7
2、接线要求…………………………………………8
3、程序调试…………………………………………8
附总电图……………………………………………………8
●总结与体会………………………………………………9
●补充:
DS18B20和数码管的使用……………………10
第一章系统的概述及设计任务书
摘要和关键词【摘要】:
本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温准确,其输出温度采用数字显示,主要用于对测温比较准确的场所,或科研实验室使用,该设计控制器使用单片机STC89C52,测温传感器使用DS18B20,用4位共阳极LED数码管以串口传送数据,实现温度显示,能准确达到以上要求。
【关键词】:
单片机,数字控制,温度计,DS18B20,STC89C52
设计任务与技术指标
要求:
1.基本范围-50℃-125℃
2.精度误差小于0.5℃
3.LED数码直读显示
总体设计方案
数字温度计设计方案论证
方案一
由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化的电压或电流采集过来,进行A/D转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到A/D转换电路,感温电路比较麻烦。
方案二
进而考虑到用温度传感器,在单片机电路设计中,大多都是使用传感器,所以这是非常容易想到的,所以可以采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。
从以上两种方案,很容易看出,采用方案二,电路比较简单,软件设计也比较简单,故采用了方案二。
方案二的总体设计框图
温度计电路设计总体设计方框图如图1所示,控制器采用单片机AT89S51,温度传感器采用DS18B20,用3位LED数码管以串口传送数据实现温度显示。
第二章单元模块的设计与分析
主控制器:
单片机STC89C52,具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用。
显示电路:
显示电路采用4位共阳LED数码管,从P0口RXD,TXD串口输出段码。
温度传感器:
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。
DS18B20的性能特点如下:
●独特的单线接口仅需要一个端口引脚进行通信;
●多个DS18B20可以并联在惟一的三线上,实现多点组网功能;
●无须外部器件;
●可通过数据线供电,电压范围为3.0~5.5V;
●零待机功耗;
●温度以9或12位数字;
●用户可定义报警设置;
●报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件;
●负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作;
DS18B20内部结构框图如图2所示。
64位ROM的结构开始8位是产品类型的编号,接着是每个器件的惟一的序号,共有48位,最后8位是前面56位的CRC检验码,这也是多个DS18B20可以采用一线进行通信的原因。
温度报警触发器TH和TL,可通过软件写入户报警上下限。
DS18B20温度传感器的内部存储器还包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。
高速暂存RAM的结构为8字节的存储器,结构如图3所示。
头2个字节包含测得的温度信息,第3和第4字节TH和TL的拷贝,是易失的,每次上电复位时被刷新。
第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。
DS18B20工作时寄存器中的分辨率转换为相应精度的温度数值。
该字节各位的定义如图3所示。
低5位一直为1,TM是工作模式位,用于设置DS18B20在工作模式还是在测试模式,DS18B20出厂时该位被设置为0,用户要去改动,R1和R0决定温度转换的精度位数,来设置分辨率。
系统软件算法分析
系统程序主要包括主程序,读出温度子程序,温度转换命令子程序,计算温度子程序,显示数据刷新子程序等。
主程序
主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值,温度测量每1s进行一次。
这样可以在一秒之内测量一次被测温度,其程序流程见图7所示。
3.2读出温度子程序
读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,校验有错时不进行温度数据的改写。
其程序流程图如图8示
3.3温度转换命令子程序
温度转换命令子程序主要是发温度转换开始命令,当采用12位分辨率时转换时间约为750ms,在本程序设计中采用1s显示程序延时法等待转换的完成。
温度转换命令子程序流程图如上图,图9所示
3.4计算温度子程序
计算温度子程序将RAM中读取值进行BCD码的转换运算,并进行温度值正负的判定,其程序流程图如图10所示。
3.5显示数据刷新子程序
显示数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操作,当最高显示位为0时将符号显示位移入下一位。
程序流程图如图11。
第三章实验程序
/*zhwy.c*/
#include
#include"DS18B20.h"
unsignedchartable[]=
{0xC0,0xF9,0xA4,0xB0,
0x99,0x92,0x82,0xF8,
0x80,0x90,};//不带小数点的编码
externunsignedinttemp;
externfloatf_temp;
unsignedinti;
voidLED_init(void)
{P2=0x0f;
P0=0x00;
}
voidled(signedintm,signedintn,signedintp,signedintq)
{P2=0xef;
P0=table[q];
delay(5);
P2=0xdf;
P0=table[p];
delay(5);
P2=0xbf;
P0=table[n]+0x80;
delay(5);
P2=0x7f;
P0=table[m];
delay(5);
}
unsignedintxianshi(unsignedinty,signedintf,signedintg)
{signedinta,b,c,d;
a=y/1000;
b=(y%1000)/100+f;
c=(y%100)/10+g;
d=(y%10)/1;
if(b<=9&&b>=0)
for(i=16;i>0;i--)
led(a,b,c,d);
elseif(b>9)
{a+=b/10;b=b%10;
for(i=16;i>0;i--)
led(a,b,c,d);}
else
{b=0-b;
if(b%10==1)f-=1;b=10-(b%10);
if(b==10)b=0;
for(i=16;i>0;i--)
led(a,b,c,d);}
returnf;
}
voidmain(void)
{unsignedintSum,k;
signedinth,j;
LED_init();
h=0;j=0;
while
(1)
{tempchange();
Sum=get_temp();
P2=0xff;
for(k=0;k<100;k++)
{
if(P2==0xf7)
{delay(10);
if(P2==0xf7)
h+=1;
h=display(Sum,h,j);
}
if(P2==0xfb)
{delay(10);
if(P2==0xfb)
h-=1;
h=display(Sum,h,j);
}
if(P2==0xfd)
{delay(10);
if(P2==0xfd)
j+=1;
h=display(Sum1,h,j);
}
if(P2==0xfe)
{delay(10);
if(P2==0xfe)
j-=1;
h=display(Sum1,h,j);
}
}
display(Sum1,h,j);
}}
sbitds=P3^5;//温度传感器信号线
/*DS18B20.h*/
unsignedinttemp;
floatf_temp;
unsignedintwarn_l1=260;
unsignedintwarn_l2=250;
unsignedintwarn_h1=300;
unsignedintwarn_h2=320;
voiddelay(unsignedintz)//延时函数
{unsignedintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voiddsreset(void)//18B20复位,初始化函数
{unsignedinti;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bittempreadbit(void)//读1位函数
{unsignedinti;
bitdat;
ds=0;i++;//i++起延时作用
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
return(dat);
}
unsignedchartempread(void)//读1个字节
{unsignedchari,j,dat;
dat=0;
for(i=1;i<=8;i++)
{j=tempreadbit();
dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
voidtempwritebyte(unsignedchardat)//向18B20写一个字节数据
{unsignedinti;
unsignedcharj;
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);//写温度转换指令
}
unsignedcharget_temp()//读取寄存器中存储的温度数据
{unsignedchara,b;
dsreset();
delay
(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a=tempread();//读低8位
b=tempread();//读高8位
temp=b<<5;
temp=temp|(a&0xf8)>>3;//两个字节组合为1个字
f_temp=temp*0.0625;
f_temp=f_temp+0.005;
returntemp;//temp是整型
}
temp=f_temp*100+0.5;
总电路图结构图
4总结与体会
经过将近四周的单片机课程设计,我终于在参考了众多程序之后完成了我的数字温度计的设计,虽然没有完全达到设计要求,但我还是高兴的,毕竟这次设计的电路板是我一手焊出来的。
在本次设计的过程中,我发现很多的问题,也学到了许多东西。
虽然我以前也做过类似的课程设计,但这次设计真的让我长进了很多。
本次单片机课程设计的重点就在于测温及按键编程软件算法的设计,其中有许多很巧妙的算法。
我以前总是能看懂别人写的程序,但自己单独写时就会出现很多问题,经过这次锻炼我基本掌握了C语言编程的方法并在以前的基础上有所提高。
从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高,这就是我在这次课程设计中的最大收获。
补充:
DS18B20和数码管的使用
1温度传感器DS18B20的使用:
DS1820是这样测温的:
用一个高温度系数的振荡器确定一个门周期,内部计数器在这个门周期内对一个低温度系数的振荡器的脉冲进行计数来得到温度值。
计数器被预置到对应于-55℃的一个值。
如果计数器在门周期结束前到达0,则温度寄存器(同样被预置到-55℃)的值增加,表明所测温度大于-55℃。
同时,计数器被复位到一个值,这个值由斜坡式累加器电路确定,斜坡式累加器电路用来补偿感温振荡器的抛物线特性。
然后计数器又开始计数直到0,如果门周期仍未结束,将重复这一过程。
斜坡式累加器用来补偿感温振荡器的非线性,以期在测温时获得比较高的分辨力。
这是通过改变计数器对温度每增加一度所需计数的的值来实现的。
因此,要想获得所需的分辨力,必须同时知道在给定温度下计数器的值和每一度的计数值。
DS1820内部对此计算的结果可提供0.5℃的分辨力。
温度以16bit带符号位扩展的二进制补码形式读出,表1给出了温度值和输出数据的关系。
数据通过单线接口以串行方式传输。
DS1820测温范围-55℃~+125℃,以0.5℃递增。
如用于华氏温度,必须要用一个转换因子查找表。
注意DS1820内温度表示值为1/2℃LSB,如下所示9bit格式:
最高有效(符号)位被复制充满存储器中两字节温度寄存器的高MSB位,由这种“符号位扩展”产生出了示于表1的16bit温度读数。
可用下述方法获得更高的分辨力。
首先,读取温度值,将0.5℃位(LSB)从读取的值中截去,这个值叫做TEMP_READ。
然后读取计数器中剩余的值,这个值是门周期结束后保留下来的值(COUNT_REMAIN)。
最后,我们用到在这个温度下每度的计数值(COUNT_PER_C)。
用户可以用下面的公式计算实际温度值:
1Ds1820用9位存贮温值度最高位为符号位下图为18b20的温度存储方式负温度S=1正温度S=0如00AAH为+85,0032H为25FF92H为55
2Ds18b20用12位存贮温值度最高位为符号位下图为18b20的温度存储方式负温度S=1正温度S=0如0550H为+850191H为25.0625,FC90H为-55
在我们编写的程序中,由于数码管只有四位能够显示,因此我们决定保留一位小数位,而以12位贮藏温度值的最小分度值为0.0625,即2-4。
又由于51单片机的数据位数为八位,我们需要将这16位中的八位数截取出来,经过我们多次的测试,我们终于确定了去掉高八位中的前5位以及低八位中的后三位,这样我们就可以保证输出数据至少有一位小数位,在程序中的数据处理为:
temp=b<<5;
temp=temp|(a&0xf8)>>3;
通过单线总线端口访问DS1820的协议如下:
•初始化
•ROM操作命令
•存储器操作命令
•执行/数据
2.8段式共阳极数码管的使用:
其电路图为:
数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。
在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。
经过我们查的资料可知,1H-4H的输入信号决定了4个数码管中哪一个开始接收来自A-G及DP的信号。
而进过三极管之后P24-P27的信号与1H-4H的信号相同。
共阳极的信号可以通过程序写入单片机来控制数码管的亮和灭,从而通过数码管的循环亮灭,以视觉误差来使数码管显示我们所需要的数字。
经过我们的分析可知,数码管从左至右分别亮的P2口应写入的指令为:
7f,0xbf,0xdf,0xef,他们分别显示的数字从0到9的代码为:
0xC0,0XF9,0xA4,0Xb099,0x92,0x82,0XF8,0x80,0x90。
因此,只要分别写入指令就可以啦。