过程控制课程报告基于单片机的水温控制系统.docx
《过程控制课程报告基于单片机的水温控制系统.docx》由会员分享,可在线阅读,更多相关《过程控制课程报告基于单片机的水温控制系统.docx(21页珍藏版)》请在冰豆网上搜索。
过程控制课程报告基于单片机的水温控制系统
过程控制系统课程设计
实验报告
课程设计题目:
基于单片机的水温控制系统
指导老师:
XXX
小组成员:
XX
XX
一、系统总方案设计
图1-1系统框图
本系统的电路设计方框图如图1-1所示,它由七部分组成:
①控制部分主芯片采用单片机STC89C52;②显示部分采用4位共阳极LED数码管以动态扫描方式实现温度显示;③温度采集部分采用DS18B20温度传感器;④加热控制部分采用继电器电路;⑤时钟电路;⑥复位电路;⑦单列3按键键盘输入设定温度值。
二、硬件电路设计
1.时钟电路设计
时钟电路是用来产生STC89C52单片机工作时所必须的时钟信号,STC89C52本身就是一个复杂的同步时序电路,为保证工作方式的实现,STC89C52在唯一的时钟信号的控制下严格的按时序执行指令进行工作,时钟的频率影响单片机的速度和稳定性。
通常时钟由于两种形式:
内部时钟和外部时钟。
我们系统采用内部时钟方式来为系统提供时钟信号。
STC89C52内部有一个用于构成振荡器的高增益反向放大器,该放大器的输入输出引脚为XTAL1和XTAL2,它们跨接在晶体振荡器和用于微调的电容,便构成了一个自激励振荡器。
电路中的C1、C2的选择在30PF左右,但电容太小会影响振荡的频率、稳定性和快速性。
晶振频率为在1.2MHZ~12MHZ之间,频率越高单片机的速度就越快,但对存储器速度要求就高。
为了提高稳定性我们采用温度稳定性好的30pf的贴片电容,采用的晶振频率为12MHZ。
本次系统的时钟电路设计如图2-1所示。
图2-1时钟电路图
2.系统复位电路
在图2-2中复位开关K1被按下并松开,使
端获得低电平,RST端输出复位信号,单片机复位。
图2-2复位电路
3.报警与控制电路设计
当水箱内的温度超出或低于设定的温度超出1℃时,P1.4输出低电平“0”时,晶体管导通,压电蜂鸣器两端获得约+5V电压而鸣叫,出报警声音;单片机的P1.1输出低电平,此时红色指示灯亮,直到低于设定的最低温度时,P1.4输出高电平时,三极管截止,蜂鸣器停止发声,P1.1输出电平高电平,发光二极管灭,(由于实验器材有限,本设计的蜂鸣器使用发光二级管替代)报警和控制电路而下图2-3所示
图2-3报警与控制电路与单片机的连接
4LED显示电路设计
在本设计中采用了四位共阳极八段数码管,用动态驱动来显示温度的值,如图2-4-2所示,其结构如2-4-1所示
图2-4-1数码管内部结构
图2-4-2LED显示电路
5温度检测电路设计
本次设计所采用的温度传感器为DS18B20,无需A/D转换,因此从主机CPU到DSl8B20仅需一条线,当DS18B20接收到温度转换命令后,开始启动转换。
DS18B20的测量温度范围为-55°C--+125°C,在-10--+85°C范围内,精度为±0.5°C。
现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。
图2-5为DS18B20与单片机的连接图
图2-5DS18B20与STC89C52单片机的连接
6按键电路设计
键盘共有三个键,判断K2-K4键是否按下,可采用软件查询和中断的方法,当某个键按下时,低电平有效。
3个键K2-K4的功能定义如表所示。
K2-K4键的定义
按键
键名
功能
K2
功能转换键
此键按下,显示温度设定值,按键松开,显示当前温度
K3
加1键
设定温度值加1
K4
减1键
设定温度值减1
图2-6按键电路
7继电器控制电路
控制P10的高低电平来控制继电器的断开和闭合,当P10口为低电平时,三极管导通,发光二极管亮,控制继电器开始加热,当P10为高电平时,三极管截止,继电器断开,停止加热。
(由于实验设备有限,本设计使用发光二级管代替继电器加热装置,当二极管发亮时代表正在加热)。
图2-7继电器控制加热装置电路图
三、软件设计
1.系统总流程图
图3-1系统总流程图
2.主程序
主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值,温度测量每1s进行一次。
这样可以在一秒之内测量一次被测温度,其程序流程见图3-2所示。
通过调用读温度子程序把存入内存储中的整数部分与小数部分分开存放在不同的两个单元中,然后通过调用显示子程序显示出来。
图3-2主程序流程图
3.读出温度子程序
DS18B20复位、应答子程序
读温度命令子程序
写入子程序
跳过ROM匹配命令
DS18B20复位、应答子程序
显示子程序(延时)
写入子程序
温度转换命令
写入子程序
跳过ROM匹配命令
图4-3读出温度子程序
4.数码管显示模块
图4-4数码管显示模块
附录一系统电路图
附录二系统源代码
#include//52系列头文件
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitds=P3^4;
sbitdula=P2^6;
sbitbeep=P1^4;//定义蜂鸣器
sbitled=P1^1;
sbitjdq=P1^0;
uinttemp,t,w;//定义整型的温度数据
ucharflag;
floatf_temp;//定义浮点型的温度数据
uintlow;//定义温度下限值是温度乘以10后的结果
uinthigh;//定义温度的上限值
sbitled1=P1^0;//控制发光二极管
sbitled2=P1^1;//控制发光二极管
sbits1=P3^5;
sbits2=P3^6;
sbits3=P3^7;
ucharflag1,flag2,flag3,flag4,s1num,qian,bai,shi,ge;
ucharcodetable[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0xc6
};//共阳数码管段码表
ucharcodetable1[]=
{0x40,0x79,0x24,0x30,0x19,
0x12,0x02,0x78,0x00,0x10};//带小数点的编码
voiddelay(ucharz)//延时函数
{
uchara,b;
for(a=z;a>0;a--)
for(b=100;b>0;b--);
}
voidinit()
{
EA=1;
ET1=1;
TR1=1;
TMOD=0x10;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
flag=0;
high=100;
jdq=1;
}
voiddidi()
{
beep=0;
led=0;
delay(500);
beep=1;
led=1;
delay(500);
}
voiddsreset(void)//DS18b20复位,初始化函数
{
uinti;
ds=0;
i=103;//延时最短480us
while(i>0)i--;
ds=1;//等待16-60us,收到低电平一个约60-240us则复位成功
i=4;
while(i>0)i--;
}
bittempreadbit(void)//读1位数据函数
{
uinti;
bitdat;
ds=0;i++;
ds=1;i++;i++;//i++起到延时作用
dat=ds;
i=8;
while(i>0)i--;
return(dat);
}
uchartempread(void)//读1字节的数据函数
{
uinti,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1);
//读出的数据最低位在最前面,这样刚好一个字节在dat里
}
return(dat);
}
voidtempwritebyte(uchardat)//向DS18B20写一个字节的数据函数
{
uinti;
ucharj;
bittestb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)//写1
{
ds=0;
i++;i++;
ds=1;
i=8;
while(i>0)
i--;
}
else//写0
{
ds=0;
i=8;
while(i>0)i--;
ds=1;
i++;i++;
}
}
}
voidtempchange(void)//DS18B20开始获取温度并转换
{
dsreset();
delay
(1);
tempwritebyte(0xcc);//写跳过读ROM指令
tempwritebyte(0x44);//写温度转换指令
}
uintget_temp()//读取寄存器中存储的温度数据
{
uchara,b;
dsreset();
delay
(1);
tempwritebyte(0xcc);//写跳过读ROM指令
tempwritebyte(0xbe);//写温度转换指令
a=tempread();//读低8位
b=tempread();//读高8位
temp=256*b+a;
f_temp=temp*0.0625;//温度在寄存器中为12位,分辨率为0.0625
temp=f_temp*10+0.5;//乘以10表示小数点后面只取一位
returntemp;//temp是整型
}
voidkeyscan()
{
if(s1==0)
{P2=0xff;
delay(5);
if(s1==0)
{
while(!
s1);
s1num++;
if(s1num==1)
{
flag=1;
}
if(s1num==2)
{
s1num=0;
flag=0;
}
}
}
if(s1num==1)
{
flag=1;
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
high+=10;
if(high==1000)
high=100;
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
high-=10;
if(high==0)
high=100;
}
}
}
}
voidmain()//主函数
{
init();
while
(1)
{
tempchange();//温度转换函数
if(temp{
jdq=0;
didi();
}
if((temp>=high-10)&&(temp<=high))
{
jdq=0;
beep=1;
}
if((temp>high)&&(temp<=high+10))
{
jdq=1;
beep=1;
}
if(temp>high+10)
{
jdq=1;
didi();
}
}
}
voidtime1()interrupt3
{
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
t++;
keyscan();
if(flag==0)
{
if(t==4)t=0;
switch(t)
{
case1:
P0=table[get_temp()/100];P2=0xfd;break;
case2:
P0=table1[get_temp()%100/10];P2=0xfb;break;
case3:
P0=table[get_temp()%10];P2=0xf7;break;
}
}
if(flag==1)
{
if(t==4)t=0;
switch(t)
{
case0:
P0=0xff;P2=0xfe;break;
case1:
P0=0xff;P2=0xfd;break;
case2:
P0=table[high/100];P2=0xfb;break;
case3:
P0=table[high%100/10];P2=0xf7;break;
}
}
}