DS B 数字温度计设计实验报告文档格式.docx
《DS B 数字温度计设计实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《DS B 数字温度计设计实验报告文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
器
DS18B20
显示电路
扫描驱动
图
3.硬件设计
温度计电路设计原理图如下图所示,控制器使用单片机AT89C2051,温度传感器使用DS18B20,使用四位共阳LED数码管以动态扫描法实现温度显示。
主控制器单片机AT89C2051
具有低电压供电和小体积等特点,两个端口刚好满足电路系统的设计需要,很适合便携手持式产品的设计使用。
系统可用两节电池供电。
AT89C2051的引脚图如右图所示:
1、VCC:
电源电压。
2、GND:
地。
3、P1口:
P1口是一个8位双向I/O口。
口引脚~提供内部上拉电阻,和要求外部上拉电阻。
和还分别作为片内精密模拟比较器的同相输入(ANI0)和反相输入(AIN1)。
P1口输出缓冲器可吸收
20mA电流并能直接驱动LED显示。
当P1口引脚写入“1”时,其可用作输入端,当引脚~用作输入并被外部拉低时,它们将因内部的写入“1”时,其可用作输入端。
当引脚~用作输入并被外部拉低时,它们将因内部的上拉电阻而流出电流。
4、P3口:
P3口的~、是带有内部上拉电阻的七个双向I/O口引脚。
用于固定输入片内比较器的输出信号并且它作为一通用I/O引脚而不可访问。
P3口缓冲器可吸收20mA电流。
当P3口写入“1”时,它们被内部上拉电阻拉高并可用作输入端。
用作输入时,被外部拉低的P3口脚将用上拉电阻而流出电流。
5、RST:
复位输入。
RST一旦变成高电平所有的I/O引脚就复位到“1”。
当振荡器正在运行时,持续给出RST引脚两个机器周期的高电平便可完成复位。
每一个机器周期需12个振荡器或时钟周期。
6、XTAL1:
作为振荡器反相器的输入和内部时钟发生器的输入。
7、XTAL2:
作为振荡器反相放大器的输出。
总线驱动器74LS244
74LS244为3态8位缓冲器,一般用作总线驱动器。
引脚图见上图。
显示电路
显示电路采用4位共阳极LED数码管,从P1口输出段码,列扫描用~口来实现,列驱动用8055三极管。
温度传感器DS18B20
DS18B20的性能特点:
1、适应电压范围更宽,电压范围:
~,在寄生电源方式下可由数据线供电。
2、独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
3、DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温。
4、DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内。
5、温范围-55℃~+125℃,在-10~+85℃时精度为±
℃。
6、可编程的分辨率为9~12位,对应的可分辨温度分别为℃、℃、℃和℃,可实现高精度测温。
7、在9位分辨率时最多在内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快。
8、测量结果直接输出数字温度信号,以"
一线总线"
串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力。
9、负压特性:
电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。
DS18B20与单片机的接口电路(引脚图见右图)
DS18B20可以采用电源供电方式,此时DS18B20的第1脚接地,第2脚作为信号线,第3脚接电源。
4.软件设计
系统程序主要包括主程序、读出温度子程序、温度转换命令子程序、计算温度子程序和显示数据刷新子程序等。
主程序
主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量温度值。
温度测量每1s进行一次。
主程序流程图如图所示。
读出温度子程序
读出温度子程序的主要功能是读出RAM中的9字节。
在读出时必须进行CRC校验,校验有错时不能进行温度数据的改写。
读出温度子程序流程图如下图所示:
初始化
调用显示子程序
1s到
初次上电
读出温度值
温度计酸处理
显示数据刷新
发温度转换开始命令
读出温度子程序读出温度子程序的主要功能是读出RAM中的9字节。
在读出时须进行CRC校验,校验有错时不进行温度数据的改写。
得出温度子程序流程图如下图所示。
发DS18B20复位指令
CRC校验正确
发跳过ROM指令
移入温度暂存器
发读取温度指令
结束
读取操作,CRC校验
9字节完
温度转换命令子程序温度转换命令子程序主要是发温度转换开始命令。
当采用12位分辨率时,转换时间约为750ms。
在本程序设计中,采用1s显示程序延时法等待转换的完成。
温度转换命令子程序流程图如下图所示。
发DS18B20复位命令
发跳过ROM命令
计算温度子程序计算温度子程序将RAM中读取值进行BCD码的转换运算,并进行温度值正负的判定。
计算温度子程序流程图如下左图所示.
现实数据刷新子程序现实数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操作,当最高数据显示位为0时,将符号显示位移入下一位。
现实数据刷新子程序流程图如下右图所示.
温度数据移入显示寄存器
开始
计算小数位温度BCD值
十位数0
温度零下
计算整数位温度BCD值
百位数0
置+标志
温度值取补码置‘一’标志
百位数显示数据(不显示符号)
十位数显示符号百位数不显示
结束
5.系统调试
系统的调试以程序调试为主。
硬件调试比较简单,首先检查电感的焊接是否正确,然后可用万用表测试或通电检测。
软件调试可以先编写显示程序并进行硬件的正确性检验,然后分别进行主程序、读出温度子程序、温度转换命令子程序、计算温度子程序和现实数据刷新子程序等的编程及调试
由于DS18B20与单片机采用串行数据传送,因此,对DS18B20进行读/写编程时必须严格地保证读/写时序;
否则将无法读取测量结果。
本程序采用单片机汇编或C语言编写用或KeilC51编译器编程调试。
软件调试到能显示温度值,并且在有温度变化时显示温度能改变,救基本完成。
性能测试可用制作的温度机和已有的成品温度计同时进行测量比较。
由于DS18B20的精度很高,所以误差指标可以限制在℃以内。
另外,-55~+125℃的测温范围使得该温度计完全适合一般的应用场合,其低电压供电特性可做成用电池供电的手持温度计。
DS18B20温度计还可以在高低温报警、远距离多点测温控制等方面进行应用开发,但在实际设计中应注意以下问题;
1、DS18B20工作时电流高大,总线上挂接点数较多且同时进行转换时要考虑增加总线驱动,可用单片机端口在温度转换时导通一个MOSFET供电。
2、连接DS18B20的总线电缆是有长度限制的,因此在用DS18B20进行长距离测温系统设计时要充分考虑总线分布电容和阻抗匹配等问题。
3、在DS18B20测温程序设计中,向DS18B20发出温度转换命令后,程序总要等待DS18B20的返回信号。
一旦某个DS18B20接触不好或断线,当程序读DS18B20时,将没有返回信号,程序进入死循环。
这一点在进行DS18B20硬件连接和软件设计时要给予一定的重视。
6.设计总结
历时2个星期的单片机课程设计已经结束了,在这两个星期的时间里,我们在老师的指导下完成了基于DS18B20的数字温度计的设计和制作。
在进行实验的过程中,我们了解并熟悉DS18B20、AT89C2051以及74LS244的工作原理和性能。
并且通过温度计的制作,我们将电子技能实训课堂上学到的知识进行运用,并在实际操作中发现问题,解决问题,更加增加对知识的认识和理解。
在课程设计的过程中,也遇到了一些问题。
比如最开始根据课本上的电路图进行合理的设计布局和布线。
有些同学的布局不合理,导致焊接的过程中任务相当繁重,并且不美观。
在之后的烧程序调试的时候,出现问题之后,没有合理布线的同学在查找问题的过程中相当棘手。
在焊接过程中,出现最多的就是虚焊问题。
对于这个问题,在焊接的过程中,我尽量依照书中的指导,尽量将焊点焊成水滴状,最后接电后再根据数码管的显示情况进行逐个排查。
在将程序烧到单片机之后,接上电源,发现数码管没有出现正常的“”,而是出现了“”,在检查线路无误之后,和其他的同学讨论之后得出结论:
书中程序是对于单片机、电阻及数码管是直接连接而设计的,而在加入了74LS244之后,要将8个输入输出端口进行掉序。
于是,我便将8个端口进行调换,之后再次接通电源,数码管显示“”,调试成功。
在自己的温度计制作完成之后,我还帮助其他没有完成的同学进行检修,并且成功帮助2位同学找到问题进行解决,最后都调试成功。
总之,在这2个星期中,通过自己在实验室动手制作数字温度计,不仅将课本的知识与实践相结合,而且在实践中更加深入了解书中原本抽象的知识。
这也是整个课程设计中最有收获的地方。
7.附录
源程序代码
/*********************************************************************/
//
//DS18B20温度计C程序
//使用AT89C2051单片机,12MHZ晶振,用共阳LED数码管
//P1口输出段码,P3口扫描
//#pragmasrc(d:
\
#include"
"
//_nop_();
延时函数用
#defineDisdataP1//段码输出口
#definediscanP3//扫描口
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P3^7;
//温度输入口
sbitDIN=P1^0;
//LED小数点控制
uinth;
//
//*******温度小数部分用查表法**********//
Ucharcodeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}
ucharcodedis_7[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf};
/*共阳LED段码表"
0"
"
1"
2"
3"
4"
5"
6"
7"
8"
9"
不亮"
-"
*/
ucharcodescan_con[4]={0xfe,0xfd,0xfb,0xf7};
//列扫描控制字
uchardatatemp_data[2]={0x00,0x00};
//读出温度暂放
uchardatadisplay[5]={0x00,0x00,0x00,0x00,0x00};
//显示单元数据,共4个数据,一个运算暂存用
/***********11微秒延时函数**********/
voiddelay(uintt)
{
for(;
t>
0;
t--);
}
/***********显示扫描函数**********/
scan()
chark;
for(k=0;
k<
4;
k++)//四位LED扫描控制
{
Disdata=dis_7[display[k]];
if(k==1){DIN=0;
discan=scan_con[k];
delay(90);
discan=0xff;
}
/***********18B20复位函数**********/
ow_reset(void)
charpresence=1;
while(presence)
DQ=1;
_nop_();
DQ=0;
//
delay(50);
//550us
//
delay(6);
//66us
presence=DQ;
//presence=0继续下一步
delay(45);
//延时500us
presence=~DQ;
DQ=1;
}
/**********18B20写命令函数*********/
//向1-WIRE总线上写一个字节
voidwrite_byte(ucharval)
uchari;
for(i=8;
i>
i--)//
DQ=0;
//5us
DQ=val&
0x01;
//最低位移出
delay(6);
//66us
val=val/2;
//右移一位
DQ=1;
delay
(1);
/*********18B20读1个字节函数********/
//从总线上读取一个字节
ucharread_byte(void)
ucharvalue=0;
i>
i--)
value>
>
=1;
//4us
//4us
if(DQ)value|=0x80;
return(value);
/***********读出温度函数**********/
read_temp()
ow_reset();
//总线复位
write_byte(0xCC);
//发SkipROM命令
write_byte(0xBE);
//发读命令
temp_data[0]=read_byte();
//温度低8位
temp_data[1]=read_byte();
//温度高8位
//SkipROM
write_byte(0x44);
//发转换命令
/***********温度数据处理函数**********/
work_temp()
ucharn=0;
if(temp_data[1]>
127)
{temp_data[1]=(256-temp_data[1]);
temp_data[0]=(256-temp_data[0]);
n=1;
}//负温度求补码
display[4]=temp_data[0]&
0x0f;
display[0]=ditab[display[4]];
display[4]=((temp_data[0]&
0xf0)>
4)|((temp_data[1]&
0x0f)<
<
4);
display[3]=display[4]/100;
display[1]=display[4]%100;
display[2]=display[1]/10;
display[1]=display[1]%10;
if(!
display[3]){display[3]=0x0A;
display[2]){display[2]=0x0A;
}}//最高位为0时都不显示
if(n){display[3]=0x0B;
}//负温度时最高位显示"
/**************主函数****************/
main()
Disdata=0xff;
//初始化端口
for(h=0;
h<
h++){display[h]=8;
}//开机显示8888
//开机先转换一次
500;
h++)
{scan();
}//开机显示"
8888"
2秒
while
(1)
read_temp();
//读出18B20温度数据
work_temp();
//处理温度数据
for(h=0;
}//显示温度值2秒
//*********************结束**************************//
作品展示