基于单片机的仓库温度控制系统Word文档格式.docx
《基于单片机的仓库温度控制系统Word文档格式.docx》由会员分享,可在线阅读,更多相关《基于单片机的仓库温度控制系统Word文档格式.docx(24页珍藏版)》请在冰豆网上搜索。
3.7系统整体电路图9
4、软件设计10
5、系统测试与调试结果分析11
5.1测试仪器11
5.2测试方法与结果分析11
6、设计总结13
7、参考文献13
8、附件:
源程序14
1、任务设计
1.1设计任务
设计出一个可以对仓库温度监控的系统,并实现以应用。
1.2设计要求
1、检测仓库温度,当大于28度时驱动电机低速转动,当大于30度时驱动电机中速转动,当大于35度时驱动电机高速转动;
2、检测仓库温度,将温度数据上传至上位机,上位机收到温度后做出以下反应:
当大于28度时发送命令01驱动电机低速转动,当大于30度时发送命令02驱动电机中速转动,当大于35度时发送命令03驱动电机高速转动。
(可加分)
1.3创新部分
(1)增加了蜂鸣器报警
(2)可以通过串口把数据发送到上位机、并且上位机可以控制风扇的转速
(3)把直流电机改为风扇使得现象更加明显
2、总体方案设计
2.1系统整体设计思想
本系统不仅可以满足仓库温度变量实行全面、实时、长期监测的要求,而且还实现上位机控制风扇的转速来使仓库恢复所需温度。
系统以52单片机为核心,以DS18B20温度传感器、通过单片机与智能传感器相连,采集并存储智能传感器的测量数据,经过分析处理将结果显示于LCD液晶屏,通过串口模块把温度上传到上位机显示、再通过上位机发送档位控制风扇的转速控制温度,对仓库的温度检测,为名贵产品的保存环境提供了一种有效的监控系统。
3、系统硬件设计(各个功能模块设计)
3.1STC89C52RC单片机最小系统
单片机最小系统是指用最少的元件组成的单片机可以工作的系统.对52系列单片机来说,最小系统一般应该包括:
单片机微处理器芯片、晶振电路、复位电路。
52单片机最小系统复位电路的极性电容C1的大小直接影响单片机的复位时间,一般采用10~30uF,52单片机最小系统容值越大需要的复位时间越短。
(1)复位电路的用途
单片机复位电路就好比电脑的重启部分,当电脑在使用中出现死机,按下重启按钮电脑内部的程序从头开始执行。
当单片机系统在运行中,受到环境干扰出现程序跑飞的时候,按下复位按钮内部的程序自动从头开始执行(感觉没用到,所以没做这一部分)。
(2)52单片机最小系统电路介绍
51单片机最小系统晶振Y1也可以采用12MHz或者11.0592MHz,在正常工作的情况下可以采用更高频率的晶振,52单片机最小系统晶振的振荡频率直接影响单片机的处理速度,频率越大处理速度越快。
51单片机最小系统起振电容C2、C3一般采用15~33pF,并且电容离晶振越近越好,晶振离单片机越近越好,P0口为开漏输出,作为输出口时需加上拉电阻,阻值一般为10k。
设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。
计数值N乘以机器周期Tcy就是定时时间t。
设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。
在每个机器周期的S5P2期间采样T0、T1引脚电平。
当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期的S3P1期间装入计数器。
由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。
当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2ms。
STC89C52RC单片机的最小系统如图2所示。
图2单片机最小系统
3.2蜂鸣器连接电路
利用三极管作为蜂鸣器的开关,三极管基极接单片机的P1^3引脚,如果基极高电平三极管反偏,如果基极低电平,三极管正偏。
其接线图如图3所示。
图3蜂鸣器连接电路
3.3串口收发模块
MAX232芯片是MAXIM公司生产的、包含两路接收器和驱动器的IC芯片,它的内部有一个电源电压变换器,可以把输入的+5V电源电压变换成为RS-232输出电平所需的+10V电压。
模块如图4所示。
图4串口连接电路
3.4DS18B20温度传感器模块
(1)初始化(时序图如下)
1 先将数据线置高电平1。
2 延时(时间不是很严格要求,但要尽可能短一点)。
3 数据线拉到低电平。
4 延时750us(该时间范围可以在480~960us)。
5 数据线拉到高电平。
6 延时等待。
如果初始化成功则在15~60ms内产生一个由DS18B20返回的低电平0,据该状态可以确定它的存在。
但是应注意不能无限地等待,不然会使程序进入死循环,所以要进行超时判断。
7 若CPU读到数据线上的低电平0后,还要进行延时,其延时的时间从发出高电平算起(第5步的时间算起)最少要480us。
8 将数据线再次拉到高地平1后结束。
(2)DS18B20写数据(时序图如下)
1 数据线先置低电平0.
2 延时的时间确定为15us。
3 按从低到高的顺序发送数据(一次只发送一位)。
4 延时时间为45us。
5 将数据线拉到高电平1。
6 重复1-5步骤,直到发送完整个字节。
7 最后将数据线拉高到1。
(3)DS18B20读数据(时序图如下)
1 将数据线拉高到1。
2 延时2us。
3 将数据线拉低到0。
4 延时6us。
5 将数据线拉高到1。
6 延时4us。
7 读数据线的状态得到一个状态位,并进行数据处理。
8 延时30us。
9 重复1~7步骤,直到读取完一个字节。
3.5LCD1602液晶显示屏模块
(1)1602液晶接口信号说明图如下:
3.6直流电机模块
(1)电机驱动芯片ULN2803内部结构如下:
1~18、2~17、3~16、4~15、5~14、6~13、7~12、8~11是对应的非门,9为地(与电机共地),10为12v输入。
(2)电机模块的电路图如下:
3.7系统整体电路图
原理图:
PCB图:
4、软件设计
开始后程序初始化,LCD1602、DS18B20、串口初始化,并且处于循环读取温度,并且把温度不断地在LCD1602上刷新,还发送到上位机,然后在上位机上输入档位使风扇达到不同的转速。
5、系统测试与调试结果分析
5.1测试仪器
万用表、一字螺丝刀、PC机显示界面、采用电脑USB通过串口通信模块进行供电。
5.2测试方法与结果
打开电源系统各个模块开始工作,各模块正常工作,如图16、图17所示:
图16系统初始化工作图
图17温度检测1602显示和上传到上位机、上位机输入档位控制风扇转速
6、设计总结
1、整个设计过程中团队的合作最为重要、各队员既要完成好各自负责的模块也要小组内成员互相协作。
2、要想实现一个系统,那必须对整个系统的设计有整体的思路。
3、目前系统设置已经基本实现功能,不足在于中断部分没有弄得进去就没办法规定时间读取温度到上位机,因为一开总中断允许位就会使温度读取出错。
4、设计电路是系统功能实现的前提,合理的选用芯片十分关键,合理设置元器件参数更是一个难点。
5、焊接电路路需要扎实的基础功及较强的耐心,调试电路是必须认真细心。
如有问题,耐心排查。
6、需要有扎实的知识基础,既懂软件又懂硬件,会写程序能搭电路,对常用元器件比较了解。
7、任何小的问题都会影响系统的最终功能,所以必须注意细节,同时完成设计需要投入大量时间和精力,需要极强的毅力。
7、参考文献
[1]郭天祥新概念51单片机C语言教程——入门、提高、开发、拓展全攻略,电子工业出版社2014,(05)
[2]上网查阅资料。
源程序
#include<
reg52.h>
intrins.h>
stdio.h>
math.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitRS=P1^0;
sbitrw=P1^1;
sbitLCDEN=P1^2;
sbitfengmingqi=P1^3;
sbitDSPORT=P1^4;
sbitdianji=P2^0;
floatt;
intvalue;
uchara;
uchartable1[]="
wendu:
"
;
uchartable2[]="
dangwei:
uchartable3[]="
0"
uchartable4[]="
1"
uchartable5[]="
2"
uchartable6[]="
3"
voiddelayMs(uintz)//延时函数
{
uinti,j;
for(i=z;
i>
0;
i--)
for(j=110;
j>
j--);
}
voidwriteComm(ucharcomm)//写命令函数
RS=0;
P0=comm;
LCDEN=1;
_nop_();
LCDEN=0;
delayMs
(1);
voidwriteData(uchardat)//写数据函数
RS=1;
P0=dat;
}
voidinit()//1602初始化
rw=0;
writeComm(0x38);
writeComm(0x0c);
writeComm(0x06);
writeComm(0x01);
voidwriteString(uchar*str,ucharlength)//在1602上写第一行数据的格式函数
uchari;
for(i=0;
i<
length;
i++)
{
writeData(str[i]);
/*******************************************************************************
*函数名:
Ds18b20Init
*函数功能:
初始化
*输入:
无
*输出:
初始化成功返回1,失败返回0
*******************************************************************************/
ucharDs18b20Init()
DSPORT=0;
//将总线拉低480us~960us
i=70;
while(i--);
//延时642us
DSPORT=1;
//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
i=0;
while(DSPORT)//等待DS18B20拉低总线
i++;
if(i>
5)//等待>
5MS
{
return0;
//初始化失败
}
delayMs
(1);
return1;
//初始化成功
Ds18b20WriteByte
向18B20写入一个字节
com
voidDs18b20WriteByte(uchardat)
for(j=0;
j<
8;
j++)
DSPORT=0;
//每写入一位数据之前先把总线拉低1us
DSPORT=dat&
0x01;
//然后写入一个数据,从最低位开始
i=6;
while(i--);
//延时68us,持续时间最少60us
DSPORT=1;
//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
dat>
>
=1;
Ds18b20ReadByte
读取一个字节
ucharDs18b20ReadByte()
ucharbyte,bi;
for(j=8;
j>
0;
j--)
//先将总线拉低1us
//然后释放总线
//延时6us等待数据稳定
bi=DSPORT;
//读取数据,从最低位开始读取
/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。
*/
byte=(byte>
1)|(bi<
<
7);
i=4;
//读取完之后等待48us再接着读取下一个数
}
returnbyte;
Ds18b20ChangTemp
让18b20开始转换温度
voidDs18b20ChangTemp()
Ds18b20Init();
Ds18b20WriteByte(0xcc);
//跳过ROM操作命令
Ds18b20WriteByte(0x44);
//温度转换命令
//delayMs(100);
//等待转换成功,而如果你是一直刷着的话,就不用这个延时了
Ds18b20ReadTempCom
发送读取温度命令
*输入:
无
voidDs18b20ReadTempCom()
{
//跳过ROM操作命令
Ds18b20WriteByte(0xbe);
//发送读取温度命令
Ds18b20ReadTemp
读取温度
intDs18b20ReadTemp()
uinttemp=0;
uchartmh,tml;
Ds18b20ChangTemp();
//先写入转换命令
Ds18b20ReadTempCom();
//然后等待转换完后发送读取温度命令
tml=Ds18b20ReadByte();
//读取温度值共16位,先读低字节
tmh=Ds18b20ReadByte();
//再读高字节
temp=tmh;
temp<
=8;
temp|=tml;
value=temp;
t=value*0.0625;
value=t*100+(value>
0?
0.5:
-0.5);
//大于0加0.5,小于0减0.5
returnvalue;
voiddisplay(intv)
ucharcount;
uchardatas[]={0,0,0,0,0};
uinttmp=abs(v);
datas[0]=tmp/10000;
datas[1]=tmp%10000/1000;
datas[2]=tmp%1000/100;
datas[3]=tmp%100/10;
datas[4]=tmp%10;
if(v<
0)
writeString("
-"
1);
else
+"
if(datas[0]!
=0)
writeData('
0'
+datas[0]);
for(count=1;
count!
=5;
count++)
+datas[count]);
if(count==2)
.'
);
writeComm(0x80+6);
if((tmp<
=3400)|(v<
0))
fengmingqi=1;
elseif((3400<
tmp)&
&
(tmp<
=3500))
delayMs(50);
fengmingqi=0;
elseif((3500<
=3600))
{
delayMs(10);
elseif(tmp>
3600)
}
voidinit_com(void)
TMOD=0x20;
PCON=0x00;
SCON=0x50;
TH1=0xfd;
TL1=0xfd;
ET2=1;
TR1=1;
voidcomm(char*parr)
do
SBUF=*parr++;
while(!
TI);
TI=0;
}while(*parr);
voidshangweiji_duqu()
ucharbuff[19];
if(t>
0)
sprintf(buff,"
temp:
+%-10.2f"
t);
comm(buff);
else
-%-10.2f"
}
voidshangweiji_fasong()
RI=0;
a=SBUF;
switch(a)
case0:
writeComm(0x80+0x40+8);
writeString(table3,1);
dianji=0;
break;
case1:
writeString(table4,1);
delayMs(200);
dianji=1;
case2:
writeString(table5,1);
break;
case3:
writeString(table6,1);
delayMs(5);
break