课程设计报告Word文档格式.docx
《课程设计报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《课程设计报告Word文档格式.docx(30页珍藏版)》请在冰豆网上搜索。
1.1.1采用单片机及相应的组成部件完成电阻炉温度控制系统设计,包括硬件电路和软件程序设计;
1.1.2测温范围0~100℃,使其系统控制的温度保温值的变化范围为30~60℃;
1.1.3可根据按键设定目标温度,能够显示控温时的实际炉温和恒温时间等信息。
1.2提高功能要求:
1.2.1对其主电路和控制电路设计相应的保护电路,使其安全可靠地工作;
1.2.2对影响温度控制时间和精度的因素进行分析,改进相应的计算机控制算法,完成计算机控制高效的算法设计。
1.3设计条件
1.3.1电源条件:
双路稳压电源0V~30V可调,220V直流电源
1.3.2测试条件:
双路示波器DS5062C,万用表
1.3.2元件清单:
如表1.1示。
元件清单
型号
名称及功能
数量
DS18B20
温度传感器
1
STC89C52
单片机
1602
液晶显示器
74HC20
四输入与非门
9012
三极管
9013
2
TLP521-1
光电耦合器
PC1010
整流桥
IRFP460
MOSFET
7805
电源转换芯片(9V-5V)
按键
10
电阻
若干
发光二极管
电容(450V220UF)
电容
表1-1
第二章系统设计方案
2.1原理图设计
根据设计要求设计原理图如入2-1所示。
图2-1原理图
2.2硬件设计
该设计本系统由STC89C52RC单片机最小系统及其外围电路组成,单片机系统有自己的电源模块、显示模块、温度采集模块,如图2-1所示。
用单片机的P0口接上拉1K电阻接液晶1602的数据口,P3~6和P3~7口接液晶1602的RS和EN端。
P1口接4*3的矩阵键盘,通过按键进行设定温度设置。
键盘的列口通过7420四输入与非门接P3~2中端口。
P2~0接DS18B20的数据口,用于采集温度。
P2~2作为PWM输出,用于温度的控制。
电路图如图2-2所示。
图2-2硬件电路方框图
2.3软件设计
2.3.1软件设计方案
通过外部按键设置要求温控炉恒定的温度,用外部中断0扑捉按键。
通过DS18B20采集温度,通过定时器1没10秒钟采集一次温度。
通过定时器0输出PWM波。
液晶时刻显示设定温度,当前采集温度,PWM输出占空比,温度恒定时间。
温度控制采用PID控制,du=kp*(error[2]-error[1])+ki*error[2]+kd*(error[2]-2*error[1]+error[0]);
将采集回来的温度与设定温度进行比较,在设定温度差T1范围内采用纯P控制;
当采集温度在温度差T2范围内采用PI控制;
当采集温度在温度差T3范围内是PWM输出恒0,通过余热使温度升到设定温度范围内。
2.3.2软件流程
软件流程图如图2-5所示。
图2-3软件流程图
2.3.3程序清单(含必要的注释)
#include<
reg52.h>
math.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitds=P2^0;
sbitwarn=P2^1;
sbitpwm_output=P2^2;
sbitp3_2=P3^2;
sbitlcdrs=P3^6;
sbitlcden=P3^7;
ucharcodetable[]="
0123456789."
;
ucharreceive[2];
interror[3];
ucharpwm_flag,clear_flag,key_flag,time_flag,ui_flag;
ucharkey,key_temp,keyscan,point,t1,t2,t3,collect_con,time_con;
uintduty;
intui;
inttime;
intdu;
floatkp,ki;
uinttemp,temp1;
floatf_temp;
uchara,b;
voiddelay(uintz)//延时函数
{
uinti,j;
for(i=z;
i>
0;
i--)
for(j=110;
j>
j--);
}
voidwrite_com(ucharcom)//液晶显示驱动函数
lcdrs=0;
lcden=1;
P0=com;
delay(5);
lcden=0;
voidwrite_data(uchardate)
lcdrs=1;
P0=date;
voidduty_input(chart_duty)//PWM输出
uchari,j;
i=t_duty/10;
j=t_duty%10;
write_com(0x80+0x40+13);
write_data(i+0x30);
write_data(j+0x30);
write_data('
%'
);
TR0=0;
duty=100*t_duty;
TH0=(65536-duty)/256;
TL0=(65535-duty)%256;
pwm_output=0;
pwm_flag=1;
TR0=1;
voidlcd_init()//液晶显示初始化
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
t'
1'
:
'
2'
0'
write_com(0x80+5);
write_data(0xdf);
write_data(0x43);
write_com(0x80+9);
write_com(0x80+14);
write_com(0x80+0x40);
write_com(0x80+0x40+6);
s'
write_com(0x80+0x40+8);
d'
u'
y'
voidinit()
EA=0;
TMOD=0x11;
//定时器初始化
TH1=0x3c;
TL1=0xb0;
ET0=1;
ET1=1;
EX0=1;
IT0=1;
PT0=1;
TR1=1;
EA=1;
lcd_init();
pwm_flag=0;
point=0;
t1=20;
t2=27;
write_com(0x80+12);
7'
key_flag=0;
time_flag=0;
clear_flag=1;
ui_flag=0;
ui=0;
time=0;
duty_input(ui);
receive[0]=0;
receive[1]=0;
error[0]=0;
error[1]=0;
time_con=0;
collect_con=0;
P1=0xf0;
//PID参数
kp=8;
ki=0.6;
warn=1;
voiddelay1()//键盘消抖延时函数
{
uinti,j;
for(i=50;
ucharscan()//键盘扫描函数
uchari;
for(i=0;
i<
4;
i++)
if(i==0)
P1=0xfe;
if(i==1)
P1=0xfd;
if(i==2)
P1=0xfb;
if(i==3)
P1=0xf7;
key_temp=P1;
key_temp=key_temp&
0xf0;
while(key_temp!
=0xf0)
{
delay1();
key_temp=P1;
key_temp=key_temp&
while(key_temp!
{
key_temp=P1;
switch(key_temp)
{
case0xee:
key=7;
break;
case0xde:
key=8;
case0xbe:
key=9;
case0xed:
key=4;
case0xdd:
key=5;
case0xbd:
key=6;
case0xeb:
key=1;
case0xdb:
key=2;
case0xbb:
key=3;
case0xe7:
key=0;
case0xd7:
key=10;
case0xb7:
key=11;
}
while(key_temp!
key_temp=P1;
key_temp=key_temp&
}
}
}
}
returnkey;
/*voidpid()
if(t1-t2>
=15)
{//大于15KP
ki=0;
ui_flag=0;
else//小于15KPKI
ki=0.6;
ui_flag=1;
if(t2>
=t1)
TR0=0;
pwm_output=1;
write_com(0x80+0x40+13);
write_data('
ui=0;
else
{
if(ui_flag==0)
du=kp*(error[2]-error[1]);
//+kd*(error[2]-2*error[1]+error[0]);
//P控制
ui=ui+du;
if(ui>
99)
ui=99;
if(ui<
=1)
ui=1;
duty_input(ui);
if(ui_flag==1)
du=kp*(error[2]-error[1])+ki*error[2];
//+kd*(error[2]-2*error[1]+error[0]);
//PI控制
}*/
voidpid()//pid控制
ui=kp*error[2];
if(ui>
99)//温差在13°
C以上,pwm全速
pwm_output=0;
O'
N'
'
elseif(ui<
=1)//关闭pwm
ui=1;
F'
duty_input(ui);
}
voiddsreset(void)//18B20复位,初始化函数
uinti;
ds=0;
i=103;
while(i>
0)i--;
ds=1;
i=4;
bittempreadbit(void)//读1位函数
bitdat;
i++;
//i++起延时作用
dat=ds;
i=8;
while(i>
return(dat);
uchartempread(void)//读1个字节
uchari,j,dat;
dat=0;
for(i=1;
=8;
j=tempreadbit();
dat=(j<
<
7)|(dat>
>
1);
//读出的数据最低位在最前面,这样刚好一个字节DAT里
return(dat);
voidtempwritebyte(uchardat)//向18B20写一个字节数据
ucharj;
bittestb;
for(j=1;
j<
j++)
testb=dat&
0x01;
dat=dat>
1;
if(testb)//写1
i++;
//写0
voidtempchange(void)//DS18B20开始获取温度并转换
dsreset();
delay
(1);
tempwritebyte(0xcc);
//写跳过读ROM指令
tempwritebyte(0x44);
//写温度转换指令
uintget_temp()//读取寄存器中存储的温度数据
tempwritebyte(0xbe);
a=tempread();
//读低8位
b=tempread();
//读高8位
temp=b;
temp=temp<
8;
temp=temp|a;
f_temp=temp*0.0625;
temp=f_temp+0.5;
returntemp;
voidmain()
init();
while
(1)
if(key_flag==1)////有键按下
key_flag=0;
if(keyscan!
=11)//设定温度
if(point<
write_com(0x80+7);
write_data('
write_com(0x80+3+point);
write_data(table[keyscan]);
if(clear_flag==1)
clear_flag=0;
receive[1]=0;
receive[point]=keyscan;
point++;
else
clear_flag=1;
write_com(0x80+7);
write_data(0x2f);
if(point==1)
t1=receive[0];
else
t1=10*receive[0]+receive[1];
point=0;
if(t2>
=t1*0.95&
&
t2<
=t1*1.05)
time_flag=1;
else
time_flag=0;
}//pwm输出
voidtimer0()interrupt1using1
switch(pwm_flag)
case0:
TH0=(65536-duty)/256;
TL0=(65535-duty)%256;
pwm_output=0;
pwm_flag=1;
break;
case1:
TH0=(65535-(10000-duty))/256;
TL0=(65535-(10000-duty))%256;
pwm_output=1;
pwm_flag=0;
}//按键控制
voidint0()interrupt0using3
EX0=0;
p3_2=1;
keyscan=scan();
key_flag=1;
//有键按下
while(~p3_2);
voidtimer1()interrupt3//温度采集
uchari,j,x,y,z;
TR1=0;
if(time_flag==1)//温度在稳定范围之内
time_con++;
if(time_con==20)//稳定时间加一
time_con=0;
time++;
x=time/100;
y=time%100/10;
z=time%100%10;
write_com(0x80+0x40+2);
write_data(x+0x30);
write_data(y+0x30);
write_data(z+0x30);
if(time_flag==0)
time=0;
time_con=0;
collect_con++;
if(collect_con==2