配色: 字号:
基于单片机与DS18B20设计的恒温器
2012-05-04 | 阅:  转:  |  分享 
  






实训报告











学院 电子与信息学院 课程名称 电路课程设计 设计题目 基于MCU51设计的恒温器 专业 电子信息工程 班级 08电本 姓名 学号 指导教师 杨舰老师 时间 2010年9月29日











题目要求:

设计并制作一个自动加热电路并具有一定恒温范围的控制电路,当加热器加热到90°C时,电路能自动控制加热器停止加热;当法度降到70°C时,又能自动启动加热装置;恒温范围误差≦5°C;加热和恒温时均有指示灯显示,要求有过热保护。

本设计实现的功能:

本设计完成了题目的要求,并在此基础上加上了调节恒温温度的调节按钮。

设计思路:

设计51单片机的恒温箱控制系统设计时,需要考虑下面3个方面的内容:

1.选择合适的温度传感器芯片。显然,本文中的核心器件是单片机和温度传感器,单片机采用常用的51单片机即可,而温度传感器的选择则需慎重。

2.单片机和温度传感器的接口电路设计。

3.控制温度传感器实现温度信息采集以及数据传输的软件设计。

温度传感器的选择

方案一:采用热敏电阻,可满足40~90℃的测量范围,但热敏电阻精度、重复性、可靠性都比较差,其测量温度范围相对较小,稳定性较差,不能满足本系统温度控制的范围要求。

方案二:采用温度传感器铂电阻Pt1000。铂热电阻的物理化学性能在高温和氧化性介质中很稳定,它能用作工业测温元件,且此元件线性较好。在0—100摄氏度时,最大非线性偏差小于0.5摄氏度。铂热电阻与温度关系是,Rt=R0(1+At+Btt);其中Rt是温度为t摄氏度时的电阻;R0是温度为0摄氏度时的电阻;t为任意温度值,A,B为温度系数。

方案三:采用模拟温度传感器AD590K,AD590K具有较高精度和重复性(重复性优于0.1℃),其良好的非线性可以保证优于±0.1℃的测量精度。但其测量的值需要经过运算放大、模数转换再传给单片机,硬件电路较复杂,调试也会相对困难,所以本系统不宜采用此法。

方案四:采用数字温度传感器DS18B20,DS18B20提供九位温度读数,测量范围-55℃~125℃,采用独特1-WIRE总线协议,只需一根口线即实现与MCU的双向通讯,具有连接简单,高精度,高可靠性等特点。并且,DS18B20支持一主多从,若想实现多点测温,可方便扩展。

综合以上四种方案,本设计采用第四种方案,利用数字温度计DS18B20作为温度传感器。

显示部分

方案一:数码管显示:采用串行口驱动、动态扫描显示,利用单片机的串行口输出数据,显示多位数码,多个数码管可共用驱动芯片和限流电阻。

方案二:液晶显示:采用1062液晶进行控制方式显示和温度显示,成本造价相对较高,但是能显示更多的内容。

综合以上二种方案,本设计采用方案二种方案

输出控制

方案一:采用继电器,易于控制,且实行比较简单,但强电和弱电不能很好的隔离,抗干扰能力极差。

方案二:采用光电藕合器,控制信号与输出信号可以很好的隔离,增强了系统的安全性和抗干扰能力。

综合以上两种方案,本设计采用继电器控制负载工作。

程序流程图:









设计中遇到的问题与解决方案:

1、1602液晶被烧,不能显示,具体问题不明,后换过液晶把问题解决;

2、继电器不能工作,后来经过重复排查,发现是万能表出错,把PNP三极管当成NPN型,导致连接电路时出错。

具体系统的实现:

1、硬件设计(用proteus软件仿真,如下图所示)











2、软件设计(C语言)#include

#defineucharunsignedchar

#defineuintunsignedint



uchari;

ucharn=0;

intnowtemp;

inthighest=900;

intlowest=700;

sbitp23=P2^0;

sbitlcdrs=P2^5;//数据/命令选择端(h/l)

sbitlcdrw=P2^6;//读/写选择端(h/l)

sbitlcden=P2^7;



sbitp12=P1^3;

sbitp14=P1^4;



sbitp25=P3^0;

sbitp26=P3^1;

sbitp27=P3^2;



sbitp20=P1^0;

sbitp30=P1^1;

bitk=0;

bitu=0;

bitj=0;

ucharcodewendu[]="0123456789";//利用一个温度表解决温度显示乱码

sbitDQ=P1^2;//定义ds18B20总线IO



voiddelay(ucharz)//延时子函数

{

ucharx,y;

for(x=50;x>1;x--)

for(y=z;y>1;y--);

}



uchardata_bh(uchardd)

{

ucharaccept=0;

ucharacc=0;

uchari=7;

uchark=0x01;

ucharn=8;

ucharddd=dd;

while(n)

{

acc=0;

acc=ddd&k;

acc=acc<
accept=accept|acc;

ddd=ddd>>1;

i--;

n--;

}



returnaccept;

}



voidwrite_com(ucharcom)//向液晶写入命令函数

{

uchardd=data_bh(com);

lcdrs=0;

lcdrw=0;

P0=dd;

delay(5);

lcden=1;

delay(5);

lcden=0;

}



voidwrite_date(uchardate)//写入数据函数

{

uchardd=data_bh(date);

lcdrs=1;

lcdrw=0;

P0=dd;

delay(1);

lcden=1;

delay(1);

lcden=0;

}



voidinit_lcd()//液晶初始化

{

lcden=0;

delay(21);//液晶使能

lcdrw=0;

delay(21);//置写状态

write_com(0x38);

delay(21);//显示模式设置;

write_com(0x01);

delay(21);//清除屏幕;

write_com(0x0c);

delay(21);//开显示;

write_com(0x06);

delay(1);//显示光标移动设置

write_com(0x80);

delay(21);//设置数据地址指针

}



voidwrite_one(charp)

{

unsignedchari;

write_com(0x80);

for(i=0;p[i]!=0;i++)

{

write_date(p[i]);

delay(10);

}

}



voidwrite_two(charp)

{

unsignedchari;

write_com(0x80+0x40);

for(i=0;p[i]!=0;i++)

{

write_date(p[i]);

delay(10);

}

}



write_int(intnum)

{

unsignedintbai,shi,ge,xiaoshu;//这里的num,shi,ge,xiaoshu必须用unsigned//int无符号整数来表示,用unshignedchar字符

unsignedchard;

if(num<0)d=0x2D;

elsed=0x2B;

if(num<0)num=-num;

bai=num/1000;

shi=num%1000/100;

ge=num%1000%100/10;

xiaoshu=num%10;

write_date(d);

write_date(wendu[bai]);

write_date(wendu[shi]);

write_date(wendu[ge]);

write_date(0x2e);//写入小数点

write_date(wendu[xiaoshu]);

write_date(0xDF);

write_date(0x43);

}



voidtmpDelay(intnum)//延时函数

{

while(num--);

}



voidInit_DS18B20()//初始化ds1820

{

unsignedcharx=0;

DQ=1;//DQ复位

tmpDelay(8);//稍做延时

DQ=0;//单片机将DQ拉低

tmpDelay(80);//精确延时大于480us

DQ=1;//拉高总线

tmpDelay(14);

x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败

tmpDelay(20);

}



unsignedcharReadOneChar()//读一个字节

{

unsignedchari=0;

unsignedchardat=0;

for(i=8;i>0;i--)

{

DQ=0;//给脉冲信号

dat>>=1;

DQ=1;//给脉冲信号

if(DQ)

dat|=0x80;

tmpDelay(4);

}

return(dat);

}



voidWriteOneChar(unsignedchardat)//写一个字节

{

unsignedchari=0;

for(i=8;i>0;i--)

{

DQ=0;

DQ=dat&0x01;

tmpDelay(5);

DQ=1;

dat>>=1;

}

}



intReadtemp()//读取温度

{

unsignedchara=0;

unsignedcharb=0;

intt=0,t1=0;

floattt=0;

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0x44);//启动温度转换

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0xBE);//读取温度寄存器

a=ReadOneChar();//连续读两个字节数据//读低8位

b=ReadOneChar();//读高8位

t=b;

t1=a;

if(t>7){t=t&0x07;tt=-(128-t16-t10.0625);}

else{t<<=8;

t=t|a;//两字节合成一个整型变量。

tt=t0.0625;}//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据//的最低位代表的是0.0625度

t=tt10+0.5;//放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进//行一个四舍五入操作。

return(t);

}



voidmain()

{

p23=0;

p12=1;

p14=0;

init_lcd();

while(1)

{

nowtemp=Readtemp();

if(p26==1)u=0;

if(p27==1)k=0;

if(p25==1)j=0;



if(nowtemp
{

if(nowtemp>lowest)

p30=0;

}



if(nowtemp
{

p30=1;

p20=0;

p23=1;

}



if(nowtemp>highest)

{

p20=1;

p23=0;

p30=1;

}



if(p26==0)

{

if(u==0)

{

if(n==1)

highest=highest+50;

if(n==2)

if(lowest<(highest-50))

lowest=lowest+50;

}

u=1;

}

if(p27==0)

{

if(k==0)

{

if(n==1)

if(highest>(lowest+50))

highest=highest-50;

if(n==2)

lowest=lowest-50;

}

k=1;

}

if(p25==0)

{

if(j==0)

{

n++;

if(n>2)n=0;

write_com(0x01);

}

j=1;

}



if(n==0)

{

write_one("now");

write_two("");

write_int(nowtemp);

}

if(n==1)

{

write_one("highest");

write_two("");

write_int(highest);

}

if(n==2)

{

write_one("lowest");

write_two("");

write_int(lowest);

}



}

}





调试方法及操作步骤

此时钟设计是利用protues仿真软件进行仿真后,再焊接的。基本上实现了要求的功能,该多功能数字恒温器实现的温度的显示和恒温温度上下限的设置功能,。可通过三个独立按钮调节得到所需恒温的温度值。其中,上面的按钮是模式转换按钮;中间按钮在恒温上下限设置令设置值增加5°C;底部的按钮则是减少5°C。



附录(程序清单)





名称 个数 AT89s51 1块 1602液晶 1个 11.0952HZ晶振 1个 DS18B20温度传感器 1个 继电器 1个 排阻 1个 30p电容 2个 10u电容 1个 开关 4个 10K电阻 2个 500欧电阻 1红+1绿 底座 2个 PNP三极管 1个 电灯泡 1个

















电子与信息学院



2



































































































































献花(0)
+1
(本文系朽木轩首藏)