单片机课程设计DS18B20的温度测量与显示系统.docx
《单片机课程设计DS18B20的温度测量与显示系统.docx》由会员分享,可在线阅读,更多相关《单片机课程设计DS18B20的温度测量与显示系统.docx(20页珍藏版)》请在冰豆网上搜索。
单片机课程设计DS18B20的温度测量与显示系统
单片机课程设计说明书
题目:
DS18B20的温度测量与显示系统
学院:
航空自动化学院
系别:
自动化系
专业名称:
自动化专业
班级:
学号:
__
指导
中国民航大学航空自动化学院
1课程设计要求…………………………………………………………………1
2总体方案设计…………………………………………………………………4
2.1、单片机系统
2.2、电源模块
2.3、显示模块
2.4、总体设计方案
3系统方框图……………………………………………………………………4
4系统各方框的电路图…………………………………………………………9
4.1、温度传感器DS18B20电路
4.2、显示电路
4.3、主控制器
4.4、系统总电路图
5主程序流程图和各个子程序的流程图………………………………………12
1、主程序流程图
2、温度读取子程序流程图
3、温度转换子程序流程图
6源程序说明……………………………………………………………………15
7心得体会………………………………………………………………………
附录一DS18B20简介…………………………………………………………20
基于数字温度计DS18B20的温度测量与显示系统
一、任务与要求
1.利用1个DS18B20测量室内温度(误差小于?
)
2.用数码管显示温度
3.显示精度为0.1℃
扩展要求
1.多通道测量
2.LCD显示
3.生成印刷电路板
三、二、总体方案设计(基本功能)
1、单片机系统
我选用了AT89C52单片机,查过资料后我知道AT89C52单片机具有不但AT89C51单片机所有的优点,而且具有更大的程序存储空间,可在线仿真的功能,方便调试。
所以选用AT89S52八位单片机作为温度采集的控部分。
2、电源模块
采用普通的直流电源实现电路简单,而且采用集成电源芯片设计的直流电源电压比较稳定,完全满足系统各模块的供电要求。
3、显示模块
为了显示出温度,采用数码管显示工具。
4、总体设计方案
为了不失通用性和智能性,本方案采用AT89S52单片机作为控制器,单总线温度传感器DS18B20进行温度采集。
电源部分采用普通的直流电源,完全满足AT89S52和DS18B20等各模块的工作电压范围。
温度显示采用数码管。
四、系统方框图
四、系统各方框的电路图
1、温度传感器DS18B20电路
由于DS18B20工作在单总线方式,其硬件接口非常简单,仅需利用系统的一条I/O线与DS18B20的数据总线相连即可,如图1所示。
图1DS18B20电路
2、显示电路
显示电路采用4位共阳极LED数码管,P0口由上拉电阻提高驱动能力,作为段码输出并作为数码管的驱动。
P2口的低四位作为数码管的位选端。
采用动态扫描的方式显示。
3、主控制器
单片机AT89S5具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用系统可用二节电池供电。
4、系统总电路图
总体设计电路图所下,控制器采用单片机AT89S52,温度传感器采用DS18B20,用4位LED数码管以串口传送数据实现温度显示。
五、主程序流程图和各个子程序的流程图
1、主程序流程图
主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值,温度测量每1s进行一次。
这样可以在一秒之内测量一次被测温度,其程序流程见图3.1所示。
2、温度读取子程序流程图
3、温度转换子程序流程图
六、程序与说明:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P2^3;
sbitdula=P2^6;
sbitwela=P2^7;
sbitFM=P2^5;
sbitLED1=P2^0;
sbitLED2=P2^1;
sbitLED3=P2^2;
uinttemp,tmp,temp1,temp2,temp3;
ucharflag1=0;
ucharqian,bai,shi,ge;
ucharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x86,0xc7,0xc0,};//数码管显示代码
ucharcodetable1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x86,0xc7,0xc0,};//数码管显示代码
voiddelay(uchari)
{
while(--i);
}//延时函数
voiddelays(uchari)
{
while(i--);
}//延时函数
voiddelayms(uinttimer)
{
ucharx,y;
for(x=timer;x>0;x--)
for(y=110;y>0;y--);
}ms级别的延时函数
voidDs18b20_Init(void)
{
/*uinti;
DQ=0;
i=103;
while(i>0)i--;
DQ=1;
i=4;
while(i>0)i--;*/
ucharflag=0;//设置标志位
DQ=1;//拉高数据总线
delay
(1);//延时一段时间,尽量短一点
DQ=0;//拉低总线
delays(100);//延时时间在480us到960us之间
DQ=1;//拉高总线
delay(15);//如果在15-60ms的时间内产生一个低电平,则初始化完成。
flag=DQ;
delay(100);
}//ds18b20初始化
bittempreadbit()//位读取子程序
{
uinti;
bitdat;
DQ=0;i++;//i++起延时作用,1us后进入读时序
DQ=1;i++;i++;//i++起延时作用,在1us到15us内进行采样,这里延时大概8us
dat=DQ;
i=8;while(i>0)i--;//至少需要60us才能完成读周期
return(dat);//返回位数据
}
ucharRead_One_Byte()
{
uchari,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1);
}//循环8次读一个字节
return(dat);
}
voidWrite_One_Byte(ucharwdat)
{
uinti;
ucharj;
bittestb;
for(j=1;j<=8;j++)
{
testb=wdat&0x01;
wdat=wdat>>1;//右移位
if(testb)//写1周期
{
DQ=0;
i++;i++;//延时一段时间,写周期开始
DQ=1;
i=8;while(i>0)i--;//完成一次写周期至少要需要60us,这里大概是100us
DQ=1;
i++;i++;
}
Else//写0周期
{
DQ=0;
i=8;while(i>0)i--;
DQ=1;
i++;i++;
}
}
/*uchari=0;
uchartime=0;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();
DQ=0;
_nop_();
DQ=wdat&0x01;
delay(40);
DQ=1;
for(time=0;time<1;time++);
wdat>>=1;
delay(10);
}*/
}
uintGet_temp()
{
floattt;
ucharlow,high;
Ds18b20_Init();//调用初始化函数
delayms
(1);
Write_One_Byte(0xcc);//跳过读ROM指令
Write_One_Byte(0x44);//温度转换指令
//delayms
(2);
Ds18b20_Init();//调用初始化函数
delayms
(1);
Write_One_Byte(0xcc);//跳过读ROM指令
Write_One_Byte(0xbe);//读温度指令
//delayms
(2);
low=Read_One_Byte();//低字节存放在LOW
high=Read_One_Byte();//高字节存放在high
temp=high;
temp<<=8;
temp=temp|low;//将温度合并
if(temp<0x07ff)//判断温度正负
flag1=0;
else
{temp=~temp+1;
flag1=1;
}
/*if(temp>63488)
{
temp=~temp+1;
}
tt=temp*(0.0625);
if(tt>=100)
{
flag1=1;
}*/
//temp=tt*10+0.5;
tt=temp*(0.0625);
temp=tt*10+0.5;
//temp=temp+0.05;
return(temp);
}
voidDisplay(uintvalue)
{
/*ucharqian,bai,shi,ge;
bai=value/100;
shi=value%100/10;
ge=value%10;*/
qian=temp/1000;//百位数
bai=temp%1000/100;//十位数
shi=temp%100/10;//个位数
ge=temp%10;//小数位
if(qian==0)//百位若为零,则不显示
{
dula=1;
P0=0xff;
dula=0;
P0=0xff;
wela=1;
P0=2;
wela=0;
delayms(5);
P0=0xff;
}
else
{
dula=1;
P0=table[qian];
dula=0;
P0=0xff;
wela=1;
P0=2;
wela=0;
delayms(5);
P0=0xff;
}
if(flag1==0)//若温度我正数,则最高位不显示
{
dula=1;
P0=0xff;
dula=0;
P0=0xff;
wela=1;
P0=1;
wela=0;
delayms(5);
P0=0xff;
}
Else//若温度为负数,则最高位为负号
{
dula=1;
P0=0xbf;
dula=0;
P0=0xff;
wela=1;
P0=1;
wela=0;
delayms(5);
P0=0xff;
}
/*dula=1;
P0=table[qian];
dula=0;
P0=0xff;
wela=1;
P0=2;
wela=0;
delayms(5);
P0=0xff;*/
dula=1;//显示百位
P0=table[bai];
dula=0;
P0=0xff;
wela=1;
P0=4;
wela=0;
delayms(5);
P0=0xff;
dula=1;//显示十位
P0=table[shi];
dula=0;
P0=0xff;
wela=1;
P0=8;
wela=0;
delayms(5);
P0=0xff;
dula=1;//显示个位
P0=table[ge];
dula=0;
P0=0xff;
wela=1;
P0=0x10;
wela=0;
delayms(5);
P0=0xff;
}
voidmain()
{
LED1=1;
while
(1)
{
P1=0x39;
tmp=Get_temp();
Display(tmp);
delayms(25);
}
}
六、DS18B20简介
DS18B20采用3脚PR-35封装或8脚SOIC封装,管脚排列如图3所示。
图中GND为地,DQ为数据输入/输出端(即单线总线),该脚为漏极开路输出,常态下呈高电平,Vcc是外部+5V电源端,不用时应接地,NC为空脚。
图3DS18B20的外部结构
DS18B20内部主要包括寄生电源、温度传感器、64位激光ROM单线接口、存放中间数据的高速暂存器(内含便笺式RAM),用于存储用户设定的温度上下限值的TH和TL解发器存储与控制逻辑、8位循环冗余校验码(CRC)发生器等七部分,内部结构如图4。
图4DS18B20内部结构
七、心得体会
在两个星期的努力中,这次课程设计终于顺利完成了,在设计中我遇到了很多编程问题,在老师和同学的帮助下,终于把这些问题逐个解决。
同时这次课程设计给我一个很好的锻炼的机会。
非常感谢学校和老师!