基于单片机的数字温度计系统的设计.docx
《基于单片机的数字温度计系统的设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的数字温度计系统的设计.docx(23页珍藏版)》请在冰豆网上搜索。
基于单片机的数字温度计系统的设计
武汉理工大学华夏学院
信息工程课程设计报告书
课程名称单片微型计算机与接口技术
课程设计总评成绩
学生姓名、学号马越10212410133
学生专业班级自动化1101
指导教师姓名李文彦
课程设计起止日期2012.12.29-2013.1.18
课程设计任务书
学生姓名:
专业班级:
指导教师:
工作单位:
题目:
基于51单片机的数字温度计的设计
初始条件:
1.运用所学的单片机原理与接口技术知识和数字电路知识;
2.51单片机应用开发系统一套;
3.PC机及相关应用软件;
要求完成的主要任务:
1.完成数字温度计的设计和调试。
2.要求用DS18B20测量室温,用四位八段数码管显示,并能设置显示精度。
3.撰写课程设计说明书。
4.课程设计说明书要求:
引言、设计要求、系统结构、原理设计、各个模块的设计与实现、软件设计、调试过程、收获、体会及总结、参考文献、电路图和源程序。
说明书使用A4打印纸计算机打印或手写,用Protel等绘图软件绘制电子线路图纸。
时间安排:
第1天下达课程设计任务书和日程安排,根据任务书查找资料;
第2~3天完成方案论证,单片机系统的设计;
第4~6天参考有关文献,完成程序的编写;
第7~10天调试硬件系统和软件程序;
第11~13天结果分析整理、撰写课程设计报告;
第14~15天验收和答辩。
指导教师签名:
年月日
一、课程设计项目名称
基于51单片机的数字温度计的设计
二、项目设计目的及技术要求
2.1项目设计目的:
1.理解掌握MCS-51系列单片机的功能和实际应用。
2.掌握开发软件的使用,学会运用仿真软件画图,能够在数码管上显示温度值。
3.掌握数字式温度计电路的设计、组装与调试方法。
2.2设计技术要求:
1.完成数字温度计的设计和调试。
2.要求用DS18B20测量室温,用四位八段数码管显示,并能设置显示精度。
3.利用数字温度传感器DS18B20测量温度信号,计算后在LED数码管上显示相应的温度值。
4.说明书使用A4打印纸计算机打印或手写,用Protel等绘图软件绘制电子线路图纸。
三、项目设计方案论证(可行性方案、最佳方案、软件程序、硬件电路原理图和PCB图)
3.1引言
在日常生活及工农业生产中,经常要用到温度的检测及控制,传统的测温元件有热电偶和热电阻。
而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,需要比较多的外部硬件支持。
其缺点有:
1.硬件电路复杂;2.软件调试复杂;3.制作成本高。
随着科技的不断发展,在三大信息信息采集(即传感器技术)、信息传输(通信技术)和信息处理(计算机技术)中,传感器属于信息技术的前沿尖端产品,尤其是温度传感器技术,在我国各领域已经引用的非常广泛,可以说是渗透到社会的每一个领域,人民的生活与环境的温度息息相关,在工业生产过程中需要实时测量温度,在农业生产中也离不开温度的测量,因此研究温度的测量方法和装置具有重要的意义。
目前的智能温度传感器(亦称数字温度传感器)是在20世纪90年代中期问世的,它是微电子技术、计算机技术和自动测试技术(ATE)的结晶,特点是能输出温度数据及相关的温度控制量,适配各种微控制器(MCU)。
社会的发展使人们对传感器的要求也越来越高,现在的温度传感器正在基于单片机的基础上从模拟式向数字式,从集成化向智能化、网络化的方向飞速发展,并朝着高精度、多功能、总线标准化、高可靠性及安全性、开发虚拟传感器和网络传感器、研制单片测温系统等高科技的方向迅速发展,本文将介绍智能集成温度传感器DS18B20的结构特征及控制方法,并对以此传感器,AT89C52单片机为控制器构成的数字温度测量装置的工作原理及程序设计作了详细的介绍。
3.2设计方案
方案一:
设计一个测温电路,包括温度传感器,温度变送器,A/D转换电路。
具体流程为温度传感器测量温度信号,经过温度变送器变换为电流信号,再通过A/D转换器转换为数字信号进入单片机进行处理,再在数码管上显示。
采用热电偶温差电路测温,温度检测部分可以使用低温热偶,热电偶由两个焊接在一起的异金属导线所组成(热电偶的构成如图3.1),热电偶产生的热电势由两种金属的接触电势和单一导体的温差电势组成。
通过将参考结点保持在已知温度并测量该电压,便可推断出检测结点的温度。
数据采集部分则使用带有A/D通道的单片机,在将随被测温度变化的电压或电流采集过来,进行A/D转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来。
热电偶的优点是工作温度范围非常宽,且体积小,但是它们也存在着输出电压小、容易遭受来自导线环路的噪声影响以及漂移较高的缺点,并且这种设计需要用到A/D转换电路,感温电路比较麻烦。
图3.1热电偶电路图
方案二:
考虑用温度传感器,在单片机电路设计中,大多都是使用传感器,所以这是非常容易想到的,所以可以采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。
温度测量上使用集成芯片DS18B20,实现温度测量并输出数字信号,由单片机接收。
该系统利用AT89C52芯片控制温度传感器DS18B20进行实时温度检测并显示,能够实现快速测量环境温度。
方案选择:
根据上述两种方案的设计思路可以看出方案一和方案二都是可行方案。
方案一的测温装置可测温度范围宽、体积小,但是线性误差较大,方案二的测温装置电路简单、精确度较高、实现方便、软件设计也比较简单。
综上所述,方案二更加容易实现和操作,而且电路相对简单,软件设计也比较简单,所以最佳方案应选择方案二。
设计电路主要总体框图如图3.2所示。
图3.2电路设计总体框图
3.3硬件模块设计
本设计由DS18B20温度传感器芯片测量当前的温度并将转换后的结果送入单片机。
然后通过AT89C52单片机驱动八段共阴极LED数码管显示测量温度值。
如附录一中本设计硬件电路图所示,本电路主要有DS18B20温度传感器芯片,共阴极数码管,AT89C52单片机及相应外围电路组成。
其中DS18B20采用“一线制”与单片机相连。
附录一的图中由单片机P0口串接锁存器74HC573驱动共阴极数码管,由单片机的P2.0、P2.1和P2.2口接74LS138译码器驱动其字位。
由一个按键串接单片机的P3.0口来设置显示精度,由DS18B20温度传感器的DQ端和单片机的P1.3口连接来读入温度。
3.3.1温度检测电路
DS18B20最大的特点是单总线数据传输方式,DS18B20的数据I/O均由同一条线来完成。
DS18B20的电源供电方式有2种:
外部供电方式和寄生电源方式。
工作于寄生电源方式时,VDD和GND均接地,他在需要远程温度探测和空间受限的场合特别有用,原理是当1Wire总线的信号线DQ为高电平时,窃取信号能量给DS18B20供电,同时一部分能量给内部电容充电,当DQ为低电平时释放能量为DS18B20供电。
但寄生电源方式需要强上拉电路,软件控制变得复杂(特别是在完成温度转换和拷贝数据到E2PROM时),同时芯片的性能也有所降低。
外部电源供电方式是DS18B20最佳的工作方式,工作稳定可靠,抗干扰能力强,而且电路也比较简单,可以开发出稳定可靠的多点温度监控系统。
因此本设计采用外部供电方式。
如下图所示:
DS18B20的管脚排列、各种封装形式如图3.3所示,DQ为数据输入/输出引脚。
DS18B20仿真图如图3.4所示。
图3.3外部封装形式
图3.4DS18B20仿真图
3.3.2数码管显示模块
数码管连接电路如图3.5所示,P0口输出码型,P2口输出位选。
锁存器74HC573起驱动作用,提供驱动电流供数码管发光。
译码器74HC138将位选地址转换成位选信号,例如当前是第5个数码管显示,那么P2口输出位选地址05H,译码器输入CBA=110,输出位选信号Y7-Y0=11101111,其中Y5=0,第5个数码管选通并显示,其它数码管不显示。
实验时将J6的左边两个引脚针(1和2)用跳冒连接,锁存器11脚接VCC,关闭锁存功能。
数码管显示方式为动态扫描方式,当P0口送第一个数0的码型到锁存器时,P2送位选地址01H,即Y0=0,只有第一个数码管亮,显示0,其他数码管不显示。
当P0口送第二个数1的码型到锁存器时,P2送位选地址02H,即Y1=0,只有第二个数码管亮,显示1,其他数码管不显示。
即每次只有一个数码管点亮,8个数码管是轮流被点亮的,轮流点亮的间隔时间很短(一般用延时程序延时几个毫秒),由于视觉的暂留现象,看到的却好象全都点亮着,这就是动态扫描。
图3.5数码管连接电路
数码管显示数字的码型由数码管的数据脚a~dp决定,图3.6为数码管的笔段分布图,由于是共阴极的,所以当a~dp为高电平时相应的笔段会亮,电路中P1.0~P1.7分别接数码管的a.b.c.d.e.f.g.dp,得到0~9这10个数字的码型如表1所示。
图3.6数码管的笔段分布图
表1数字的码型表
引脚
P0.7
P0.6
P0.5
P0.4
P0.3
P0.2
P0.1
P0.0
数字
码型
笔段
dp
g
f
e
d
c
b
a
0
0
1
1
1
1
1
1
0
3FH
0
0
0
0
0
1
1
0
1
06H
0
1
0
1
1
0
1
1
2
5BH
0
1
0
0
1
1
1
1
3
4FH
0
1
1
0
0
1
1
0
4
66H
0
1
1
0
1
1
0
1
5
6DH
0
1
1
1
1
1
0
1
6
7DH
0
0
0
0
0
1
1
1
7
07H
0
1
1
1
1
1
1
1
8
7FH
0
1
1
0
1
1
1
1
9
6FH
1
0
0
0
0
0
0
0
小数点
80H
3.4软件模块设计
3.4.1程序介绍
此程序是利用C语言编写,keil生成的HEX文件。
程序分多个部分:
主程序、DS18B20初始化程序、读取温度子程序、写温度子程序、显示子程序等。
DS18B20初始化程序:
初始化温度传感器DS18B20。
读取温度子程序:
控制温度传感器DS18B20获取DS18B20测量的温度值。
写温度子程序:
读出的温度写入DS18B20内带的寄存器中以便获取温度值。
显示子程序:
控制显示电路在8位数码管上显示出对应数值。
程序功能:
能够实时获取温度传感器DS18B20测量的温度值,以十进制的形式进行显示。
3.4.2总程序流程图
四、项目设计结果分析(分析试验过程中获得的数据、波形、现象或问题的正确性和必然性,分析产生不正确结果的原因和处理方法)
4.1结果分析
数字式温度计的应用程序主要包括主程序,温度检测程序,温度转换程序,LED显示程序等。
系统的主程序主要用来初始化一些系统参数,对DS18B20的配置数据进行一系列的设定。
在测试方面,检查电路板及程序的运行情况,在检查无误后上电检查LED显示器。
(1)在室温下,LED显示器示数为11.9摄氏度,如图4.1所示,用手盖住温度传感器后,LED显示器示数升高,比如升高到17.8摄氏度,如图4.2所示,时间越长,升的温度越高,松开手后,温度又慢慢降回室温。
经分析可知,硬件调试结果也达到了要求。
图4.1
图4.2
(2)上电后室温最开始显示一位小数,长按S1键,直到数码管出现小数点,松手,这时温度示数由一位小数出现两位,如图4.3,再按S1,出现三位小数,再按S1,出现四位小数,如图4.4,再按S1又回到显示一位小数的状态,如此循环,在误差允许的范围内,由示数分析可知,达到了了设置显示精度的目的。
图4.3
图4.4
4.2分析与总结
本次课设对我来说是一次难得的经历,在试验中遇到的主要问题如下:
(1)装软件老是失败,不能正常运行,后来发现不能装在除C盘以外的地方。
(2)编程,本次课设我是用的C语言编的,在参考别人成功先例的基础上根据自己设计的需要编制程序,其中历经不少曲折,遇到的最大问题是最开始编辑、链接、运行没有错误但不能实现设计要求,经排错,后来发现是换了开发板,程序里的接口要改,要对应,最后用万用表检测,DS18B20的DQ端应与单片机的P1.3连,对应的程序要改。
(3)设置显示精度,在这个问题上花了很多时间,一开始编的程序只能显示一位小数,还可以显示C符号,但后来把程序改了,加了if的判断,设置全局变量,然后慢慢调试,最后能达到要求。
(4)仿真时数码管问题,用仿真软件仿真时,程序无问题,但不能显示,后来找到原因是数码管选择错了,应用共阴极而选择器件时点了共阳极。
这次课程设计,我最深的感受是,编程一定要细心,针对每一个细节,稍有疏忽,程序就不能正常工作。
试验中,觉得DS18B20温度传感器灵敏度不太高,示数变化不大。
另外,我前期花了一些时间专门学习这块芯片,了解DS18B20的工作原理的时序图。
从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高。
在这次的实践与学习中,尽管期间困难重重,但我还是从中学习了不少新的知识与技能和解决困难的方法,也终于体验到了经历困难到最终获得成功的那种无以言表的喜悦之情,总之,本次课设是我收获最多的一次,也希望自己在以后的各项研究活动中能坚持这种精神。
五、参考文摘(相关文摘不少于5篇,记录每篇文献的作者姓名.文献名称.文献发行城市:
文献出版社,出版年;文献内容摘要,每篇不少于100字)
[1]李群芳,张士军,黄建.单片微型计算机与接口技术(第3版).北京:
电子工业出版社,2009.
[2]楼然苗,李光飞.单片机课程设计指导.北京:
北京航空航天大学出版社,2007.
[3]牛昱光,李晓林.单片机原理与接口技术(第二版).北京:
电子工业出版社,2010.
[4]韩志军.单片机系统设计与应用实例.北京:
机械工业出版社,2009.
[5]蔡明文,冯先成.单片机课程设计.武汉:
华中科技大学出版社,2007.
[6]詹春华,杨沙.C语言程序设计教程.北京:
科学出版社,2011.
[7]朱定华,戴汝平.单片微机原理与应用.北京:
清华大学出版社,2003.
[8]潘永雄.新编单片机原理及应用.西安:
西安电子科技大学出版社,2003.
附录一总体设计电路图
附录二总体设计源程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLED_DATAP0//定义LED数据端口
#defineLED_CSP2//定义LED位选端口
sbitERROR=P1^7;//当温度超过门限值时该端口输出高点平
sbitP16=P1^6;
sbitDS_DATA=P1^3;
uchartable_cs[9]={0,0,0,0,0,0,0,0,11};//定义LED输出数组
ucharintx_data=0,inty_data;
ucharkey_change1,key_change2;
ucharprs=5;
uchartmp[2]={0x00,0x00};//测量值
uchartmpH[2]={0xF0,0x00};//高门限制
uchartmpL[2]={0x00,0xFF};//低门限制
sbitk1=P3^0;
intjishu=0;//微秒级延迟
voiddelay(intus)
{
while(us--);
}//DS18B20初始化
voidinit_DS18B20()
{
DS_DATA=1;//总线复位
delay(8);
DS_DATA=0;//拉低总线复位
delay(80);
DS_DATA=1;//拉高总线
delay(15);//等待50us后DS18B20复位
}
//对ds18B20写一个字节控制字
voidWRITE_ONE_CHAR(unsignedchardat)
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DS_DATA=0;//单片机将一位总线拉低
DS_DATA=dat&0x01;//单片机输出一位数据
delay(5);//延迟,等待DS18B20读取
DS_DATA=1;//单片机释放总线输出一位完成
dat>>=1;//输出数据指向下一位
}
delay(5);
}
//读取DS18B20一个字节数据
unsignedcharREAD_ONE_CHAR(void)
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DS_DATA=0;//单片机给予芯片低电平启动信号
dat>>=1;
DS_DATA=1;
if(DS_DATA)
dat|=0x80;
delay(5);
}
return(dat);
}
//DS18B20完成温度转换到读取数据
voidREAD_TEMPERATURE(unsignedchar*p)
{
uchara=0,b=0,num=0;
uintzhengfu=0;
init_DS18B20();
WRITE_ONE_CHAR(0xCC);//跳过读序号列号的操作
WRITE_ONE_CHAR(0x44);//启动温度转换
delay(200);
init_DS18B20();//呼叫DS18B20
WRITE_ONE_CHAR(0xCC);//跳过读序号列号的操作
WRITE_ONE_CHAR(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
*p=READ_ONE_CHAR();//读取温度数据低8位
*(p+1)=READ_ONE_CHAR();//读取温度数据高8位
}
voidLED_SHOW(unsignedintxnum)
{
//0,1,2,3,4,5,6,7,8,9,-,小数点,空格,
uchartable_LED[13]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x80,0x00};
uchari=0;
table_cs[xnum]=11;
for(i=0;i{
if(i==xnum)LED_CS=3;//判定小数点的位置,表示要设置个位在第4个数码管与5个数码管之间
elseLED_CS=i;
LED_DATA=table_LED[table_cs[i]];//确定LED输出数据
delay(100);
}
}
voidQV_SHU(unsignedchar*p)
{
uchara,b,zhengfu,num;
a=*p;
b=*(p+1);
if(b>0xf0)
{
if(a!
=0)a=~(a-1);
else
{
b=b-1;
a=0;
}
b=~b;
table_cs[0]=10;
zhengfu=1;
}
num=a;
num=num&0x0F;
a>>=4;
b<<=4;
if(zhengfu==0)table_cs[0]=12;
table_cs[1]=(a+b)/100;
table_cs[2]=(a+b)/10%10;
table_cs[3]=(a+b)%10;
table_cs[4]=num*625/1000;
table_cs[5]=num*625%1000/100;
table_cs[6]=num*625%100/10;
table_cs[7]=num%10;
}
unsignedcharkey()
{
uintkey;
P3=0xff;
delay(100);
key=P3;
switch(key)
{
case0xFE:
return1;break;//当P3.0按下时返回值为1
case0xFD:
return2;break;//当P3.1按下时返回值为2
case0xFB:
return3;break;//当P3.2按下时返回值为3
case0xF7:
return4;break;//当P3.3按下时返回值为4
default:
return0;//其他状况返回值为0
}
}
voidkey_pd()
{
if(key_change1==1)//当P3.0按下进入精度调整
{
prs++;
if(prs==9)prs=5;
}
if(key_change1==2)//当P3.1按下进入显示上下限门限值
{
key_change2++;
}
switch(key_change2)
{
case0:
if(jishu==150)QV_SHU(tmp);break;//当P3.1未被按下显示测量值
case1:
QV_SHU(tmpH);break;//当P3.1按下一次显示高门限制
case2:
QV_SHU(tmpL);break;//当P3.1按下两次显示低门限制
case3:
key_change2=0;break;//当P3.1按下三次返回显示测量值
}
if(key_change1==3)//当P3.2被按下进入上下门限上升调整
{
if(key_change2==1)//当P3.2被按下且P3.1被按下一次上升高门限制
{
if(tmpH[0]>=0xf0)tmpH[1]=tmpH[1]+1;
tmpH[0]=tmpH[0]+0x10;
}
elseif(key_change2==2)//当P3.2被按下且P3.1被按下两次上升低门限制
{
if(tmpL[0]>=0xf0)tmpL[1]=tmpL[1]+1;
tmpL[0]=tmpL[0]+0x10;
}
key_change1=0;
}
if(key_change1==4)//当P3.3被按下