多点温度监测系统.docx
《多点温度监测系统.docx》由会员分享,可在线阅读,更多相关《多点温度监测系统.docx(28页珍藏版)》请在冰豆网上搜索。
多点温度监测系统
电子设计自动化
实训报告
题目:
多点温度监测系统
学生姓名:
宋安邦
学生学号:
2104020685
学院:
工学院
专业:
电子信息工程
班级:
2011级
指导教师:
林君副教授
一、实训目的和意义
通过对多点温度检测系统的设计,可以更深入的了解MC5.2单片机的特点以及应用技巧,对单片机的应用可以温习其中的结构以及原理。
而且proteus的强大功能也能通过此次试验反应出来,熟悉其界面的风格以及各种应用,又重新的认识了proteus在单片机方面的强大功能。
二、实训设计内容要求
Ø1.实现4点温度实时采集,温度传感器采用DS18B20
Ø2.采用LCD1602显示4个采集点温度
Ø3.具有温度上下限报警功能:
上限90°C,下限20°C
Ø4.声音和光报警2种模式:
光报警采用4只发光LED;
声音报警采用扬声器,报警音调采用2KHz方波。
三、系统设计
1.方案设计
2.硬件电路设计
(1)工作原理:
(a)通过四个温度采集器采集数字温度输入到单片机的p2.0~p2.3口。
(b)初始化LCD1602使1602能够接受数据,并分配其显示位置,此处采用两行两列式显示。
(c)单片机读取信号。
(d)单片机向LCD1602写信号,并延时。
(e)判断是否有数据高于90度或低于20度,如果有点亮相应的led,并启动蜂鸣器。
(2)硬件系统组成
(a)80C52
(b)晶振电路
(c)复位电路
(d)LED灯电路
(e)LCD1602
(f)温度检测ds18b20
3.软件设计
(1)时间的设定:
从此采用中断T0方式延时,而且是基本单位,无论蜂鸣器还是led,或是显示温度都用到此延时程序。
延时程序如下:
voidtmpDelay(intnum)
{
while(num--);
}
voidTime0(void)interrupt1using0
{
sound=~sound;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
}
(2)信号的读入与写出:
读字节程序如下unsignedcharReadOneChar1()//
{
unsignedchari=0;
unsignedchardat1=0;
for(i=8;i>0;i--)
{
DQ1=0;//给脉冲信号
dat1>>=1;
DQ1=1;//给脉冲信号
if(DQ1)
dat1|=0x80;
tmpDelay(4);
}
return(dat1);
一共读四个字节,接下来是写字节程序如下
voidWriteOneChar1(unsignedchardat1)//
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ1=0;
DQ1=dat1&0x01;
tmpDelay(5);
DQ1=1;
dat1>>=1;
}
注意度字节的返回值。
读取温度
unsignedintReadtemp1()//
{
unsignedchara=0;
unsignedcharb=0;
unsignedintt=0;
floattt=0;
Init_DS18B201();
WriteOneChar1(0xCC);
WriteOneChar1(0x44);
Init_DS18B201();
WriteOneChar1(0xCC);
WriteOneChar1(0xBE);
a=ReadOneChar1();
b=ReadOneChar1();//
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t=tt*10;
if((t>900)|(t<200))
{
LED1=0;
EA=1;
TR0=1;
}
else
{
LED1=1;
EA=0;
TR0=0;
}
return(t);}
(3)蜂鸣器以及led的显示
程序如下
voiddelay(ucharz)
{ucharx,y;
for(x=1000;x>1;x--)
for(y=z;y>1;y--);
}
voidwrite_com(ucharcom)//写命令函数
{lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;}
voidwrite_date(uchardate)//写数据函数
{lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;}
voidinit_lcd()//初始化函数
{lcden=0;//默认开始状态为关使能端,见时序图
lcdrw=0;//选择状态为写
write_com(0x0f);
write_com(0x38);//显示模式设置,默认为0x38,不用变。
write_com(0x01);//显示清屏,将上次的内容清除
write_com(0x0c);//显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不显光标,光标不闪
write_com(0x06);//设置光标状态默认0x06,为读一个字符光标加1.
write_com(0x80);//设置初始化数据指针
for(i=0;i<16;i++)
{//显示Thetemperature
write_date(t0[i]);
delay(0);
}
write_com(0x80+0x40);
for(i=0;i<16;i++)
{//显示isC
write_date(t1[i]);
delay(0);
}
}
(4)程序流程图如下图所示:
四、调试方法及步骤
1.用软件调试工具先调试设计好的程序,方法是打开调试工具后新建项目,设计开发环境,选择单片机种类,建立.c,然后加载到环境中,编写程序,生成HEX,把他放虚拟单片机中,调试。
2出现错误,就要修改错误,编译全部通过后再接外围硬件电路,接上仿真头,硬件电路供电后再开启仿真头,然后正确设置好仿真器,最后全速运行,查看硬件电路显示结果是否与原设计思想一致。
3.显示结果正确后结束仿真,先停止运行程序,再关掉仿真头开关,最后断电,撬开仿真器。
五、结果与讨论.
查看结果是否与自己想的一样,如果不一样,可以向同学和老师讨教,如果一样就记录下。
六、实训心得
通过本次试验学会了如何使用虚拟工具来进行单片机的编辑,通过写c语言又温习了以前的所学,回味看单片机和c语言的魅力。
通过调试程序锻炼了个人的耐心恒,恒心,毅力,和理论联系实际的能力
通过学习使得懂得了开发工具的使用,多了一门吃饭的的本领,多了一门学习其他学科的实践基础。
经过这次实训课程设计,我学到了很多书本上没有的,比较实际、实用的东西,学会了怎样将理论知识运用到实际设计当中,对实验设备和设计软件的使用和分析问题解决问题的能力也有了很大的提高。
同时也明白了电路焊接和作品调试时,需要更多的耐心。
通过这次实训课程设计,不仅可以在专业上可以学到更多的知识,同时也对平时的学习和工作中产生了影响,那就是认认真真的去完成每一件事。
附录(程序清单)
#include//包含52单片机寄存器定义的头文件
/**************************************************
程序功能:
LCD1602显示温度
***************************************************/
#defineucharunsignedchar
#defineuintunsignedint
sbitlcdrs=P2^6;//数据命令选择控制
sbitlcdrw=P2^5;//读/写选择控制
sbitlcden=P2^7;//使能信号
sbitLED1=P1^0;
sbitLED2=P1^1;
sbitLED3=P1^2;
sbitLED4=P1^3;
sbitsound=P1^4;
ucharcodet0[]="T1:
T2:
";
ucharcodet1[]="T3:
T4:
";
ucharcodedigital[]="0123456789";
sbitDQ1=P2^0;//定义温度DS18B20接口,详情见原理图
sbitDQ2=P2^1;//定义温度DS18B20接口,详情见原理图
sbitDQ3=P2^2;//定义温度DS18B20接口,详情见原理图
sbitDQ4=P2^3;//定义温度DS18B20接口,详情见原理图
uchari;
/*****************************************
函数功能:
DS18B20相关函数
*****************************************/
voidtmpDelay(intnum)//延时函数
{
while(num--);
}
voidTime0(void)interrupt1using0
{
sound=~sound;
TH0=(65536-5000)/256;//定时器T0的高8位重新赋初值
TL0=(65536-5000)%256;//定时器T0的高8位重新赋初值
}
voidInit_DS18B201()//初始化ds1820
{
unsignedcharx=0;
DQ1=1;//DS复位
tmpDelay(8);//稍做延时
DQ1=0;//单片机将DS拉低
tmpDelay(80);//精确延时大于480us
DQ1=1;//拉高总线
tmpDelay(14);
x=DQ1;//稍做延时后如果x=0则初始化成功x=1则初始化失败
tmpDelay(20);
}
voidInit_DS18B202()//初始化ds1820
{
unsignedcharx=0;
DQ2=1;//DS复位
tmpDelay(8);//稍做延时
DQ2=0;//单片机将DS拉低
tmpDelay(80);//精确延时大于480us
DQ2=1;//拉高总线
tmpDelay(14);
x=DQ2;//稍做延时后如果x=0则初始化成功x=1则初始化失败
tmpDelay(20);
}
voidInit_DS18B203()//初始化ds1820
{
unsignedcharx=0;
DQ3=1;//DS复位
tmpDelay(8);//稍做延时
DQ3=0;//单片机将DS拉低
tmpDelay(80);//精确延时大于480us
DQ3=1;//拉高总线
tmpDelay(14);
x=DQ3;//稍做延时后如果x=0则初始化成功x=1则初始化失败
tmpDelay(20);
}
voidInit_DS18B204()//初始化ds1820
{
unsignedcharx=0;
DQ4=1;//DS复位
tmpDelay(8);//稍做延时
DQ4=0;//单片机将DS拉低
tmpDelay(80);//精确延时大于480us
DQ4=1;//拉高总线
tmpDelay(14);
x=DQ4;//稍做延时后如果x=0则初始化成功x=1则初始化失败
tmpDelay(20);
}
unsignedcharReadOneChar1()//读一个字节
{
unsignedchari=0;
unsignedchardat1=0;
for(i=8;i>0;i--)
{
DQ1=0;//给脉冲信号
dat1>>=1;
DQ1=1;//给脉冲信号
if(DQ1)
dat1|=0x80;
tmpDelay(4);
}
return(dat1);
}
unsignedcharReadOneChar2()//读一个字节
{
unsignedchari=0;
unsignedchardat2=0;
for(i=8;i>0;i--)
{
DQ2=0;//给脉冲信号
dat2>>=1;
DQ2=1;//给脉冲信号
if(DQ2)
dat2|=0x80;
tmpDelay(4);
}
return(dat2);
}
unsignedcharReadOneChar3()//读一个字节
{
unsignedchari=0;
unsignedchardat3=0;
for(i=8;i>0;i--)
{
DQ3=0;//给脉冲信号
dat3>>=1;
DQ3=1;//给脉冲信号
if(DQ3)
dat3|=0x80;
tmpDelay(4);
}
return(dat3);
}
unsignedcharReadOneChar4()//读一个字节
{
unsignedchari=0;
unsignedchardat4=0;
for(i=8;i>0;i--)
{
DQ4=0;//给脉冲信号
dat4>>=1;
DQ4=1;//给脉冲信号
if(DQ4)
dat4|=0x80;
tmpDelay(4);
}
return(dat4);
}
voidWriteOneChar1(unsignedchardat1)//写一个字节
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ1=0;
DQ1=dat1&0x01;
tmpDelay(5);
DQ1=1;
dat1>>=1;
}
}
voidWriteOneChar2(unsignedchardat2)//写一个字节
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ2=0;
DQ2=dat2&0x01;
tmpDelay(5);
DQ2=1;
dat2>>=1;
}
}
voidWriteOneChar3(unsignedchardat3)//写一个字节
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ3=0;
DQ3=dat3&0x01;
tmpDelay(5);
DQ3=1;
dat3>>=1;
}
}
voidWriteOneChar4(unsignedchardat4)//写一个字节
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ4=0;
DQ4=dat4&0x01;
tmpDelay(5);
DQ4=1;
dat4>>=1;
}
}
unsignedintReadtemp1()//读取温度
{
unsignedchara=0;
unsignedcharb=0;
unsignedintt=0;
floattt=0;
Init_DS18B201();
WriteOneChar1(0xCC);//跳过读序号列号的操作
WriteOneChar1(0x44);//启动温度转换
Init_DS18B201();
WriteOneChar1(0xCC);//跳过读序号列号的操作
WriteOneChar1(0xBE);//读取温度寄存器
a=ReadOneChar1();//连续读两个字节数据//读低8位
b=ReadOneChar1();//读高8位
t=b;
t<<=8;
t=t|a;//两字节合成一个整型变量。
tt=t*0.0625;//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
t=tt*10;//放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
if((t>900)|(t<200))
{
LED1=0;
EA=1;
TR0=1;
}
else
{
LED1=1;
EA=0;
TR0=0;
}
return(t);}
unsignedintReadtemp2()//读取温度
{
unsignedchara=0;
unsignedcharb=0;
unsignedintt=0;
floattt=0;
Init_DS18B202();
WriteOneChar2(0xCC);//跳过读序号列号的操作
WriteOneChar2(0x44);//启动温度转换
Init_DS18B202();
WriteOneChar2(0xCC);//跳过读序号列号的操作
WriteOneChar2(0xBE);//读取温度寄存器
a=ReadOneChar2();//连续读两个字节数据//读低8位
b=ReadOneChar2();//读高8位
t=b;
t<<=8;
t=t|a;//两字节合成一个整型变量。
tt=t*0.0625;//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
t=tt*10;//放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
if(t>900|t<200)
{
LED2=0;
EA=1;
TR0=1;
}
else
{
LED2=1;
EA=0;
TR0=0;
}
return(t);}
unsignedintReadtemp3()//读取温度
{
unsignedchara=0;
unsignedcharb=0;
unsignedintt=0;
floattt=0;
Init_DS18B203();
WriteOneChar3(0xCC);//跳过读序号列号的操作
WriteOneChar3(0x44);//启动温度转换
Init_DS18B203();
WriteOneChar3(0xCC);//跳过读序号列号的操作
WriteOneChar3(0xBE);//读取温度寄存器
a=ReadOneChar3();//连续读两个字节数据//读低8位
b=ReadOneChar3();//读高8位
t=b;
t<<=8;
t=t|a;//两字节合成一个整型变量。
tt=t*0.0625;//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
t=tt*10;//放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
if(t>900|t<200)
{
LED3=0;
EA=1;
TR0=1;
}
else
{
LED3=1;
EA=0;
TR0=0;
}
return(t);}
unsignedintReadtemp4()//读取温度
{
unsignedchara=0;
unsignedcharb=0;
unsignedintt=0;
floattt=0;
Init_DS18B204();
WriteOneChar4(0xCC);//跳过读序号列号的操作
WriteOneChar4(0x44);//启动温度转换
Init_DS18B204();
WriteOneChar4(0xCC);//跳过读序号列号的操作
WriteOneChar4(0xBE);//读取温度寄存器
a=ReadOneChar4();//连续读两个字节数据//读低8位
b=ReadOneChar4();//读高8位
t=b;
t<<=8;
t=t|a;//两字节合成一个整型变量。
tt=t*0.0625;//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
t=tt*10;//放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
if(t>900|t<200)
{
LED4=0;
EA=1;
TR0=1;
}
else
{
LED4=1;
EA=0;
TR0=0;
}
return(t);}
/*****************************************
函数功能:
LCD相关函数
*****************************************/
voiddelay(ucharz)
{ucharx,y;
for(x=1000;x>1;x--)
for(y=z;y>1;y--);
}
voidwrite_com(ucharcom)//写命令函数
{lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;}
voidwrite_date(uchardate)//写数据函数
{lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;}
voidini