北方民族大学计算机控制课设 按要求设置温度控制系统硬件仿真流程图程序.docx
《北方民族大学计算机控制课设 按要求设置温度控制系统硬件仿真流程图程序.docx》由会员分享,可在线阅读,更多相关《北方民族大学计算机控制课设 按要求设置温度控制系统硬件仿真流程图程序.docx(19页珍藏版)》请在冰豆网上搜索。
北方民族大学计算机控制课设按要求设置温度控制系统硬件仿真流程图程序
计算机控制硬件图终极版
仿真
程序
主程序流程图中断服务子程序流程图
#include
#include
#include
#include
structPIDspid;//PIDControlstructure
unsignedintrout;//PIDresponse(output)
unsignedintrin;//PIDfeedback(input)
sbitA0=P0^0;
sbitA1=P0^1;
sbitWR=P0^2;
sbitRD=P0^3;
sbitA0_2=P3^0;
sbitA1_2=P3^1;
sbitWR_2=P3^6;
sbitRD_2=P3^7;
unsignedcharflag,flag_1=0;//标志未初始化
unsignedcharhigh_time,low_time,count=0;//占空比调节参数
unsignedcharset_temper;//设定温度
unsignedchartemper;//测量的温度
unsignedchari;
unsignedcharj=0;
unsignedints;
/********************1602液晶初始化********************/
ucharcodetable[]={"Temper"};
ucharnum;
ucharnum_cal;
sbitrs=P1^5;//数据命令选择
sbitrw=P1^6;//读写选择
sbiten=P1^7;//使能端
sbitlcd_le=P3^4;
sbitlcd_8253=P3^5;
voiddelay(ucharz)//延时
{
ucharx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidlcd_com(ucharcom)//命令函数
{
rs=0;
rw=0;
en=0;
lcd_8253=0;
lcd_le=1;
P0=com;
lcd_8253=1;
lcd_le=0;
delay(5);
en=1;
delay(5);
en=0;
}
voidlcd_data(uchardate)//数据
{
rs=1;
rw=0;
en=0;
lcd_8253=0;
lcd_le=1;
P0=date;
lcd_8253=1;
lcd_le=0;
delay(5);
en=1;
delay(5);
en=0;
}
voidinit_lcd()//初始化
{
lcd_com(0x38);
lcd_com(0x0f);
lcd_com(0x06);
lcd_com(0x80);
lcd_com(0x01);
}
*******************LCD显示子程序*********************/
voiddisplay()
{
unsignedchardisp_num[6];
unsignedintk,k1;
k=high_time;
k=k%1000;
k1=k/100;//得到百位温度值
if(k1==1)
disp_num[0]=0;
else
disp_num[0]=0x60;
k=k%100;//得到十位的温度值
disp_num[1]=number[k/10];
disp_num[2]=number[k%10];
k=temper;
k=k%100;//得到个位的温度值
disp_num[3]=number[k/10];
disp_num[4]=number[k%10]+1;
disp_num[5]=number[s/10];
disp_1(disp_num);
for(num=0;num<12;num++)
{
lcd_data(table[num]);
delay(500);
}
lcd_com(0x80+40);
lcd_data(disp_num[3]);//显示百位
lcd_data(disp_num[4]);//显示十位
lcd_data(disp_num[5]);//显示个位
delay(500);
}
}
void8253_init()
{RD_2==1;//写控制字
WR_2=0;
A0_2=1;
A1_2=1;
P2=01110000B;//T1方式016位二进制计数
RD_2==1;//写计数初值
WR_2=0;
A0_2=0;
A1_2=0;
P2=100H;
RD==1;//写控制字
WR=0;
A0=1;
A1=1;
P1=00110100B;//频率发生器模式
}
voidget_temper()
{
P1=01000000B;//计数器锁存
temper=P1;
}
/************************************************/
structPID{
unsignedintSetPoint;//设定目标desiredvalue
unsignedintProportion;//比例常数proprotional
unsignedintIntegral;//积分常数integralconst
unsignedintDerivative;//微分常数derivativeconst
unsignedintLastError;//error[-1]
unsignedintPrevError;//error[-2]
unsignedintSumError;//sumsoferrors
};
/**********************史密斯控制算法***************************************/
voidSMITHInit(structSMITH*pp)
{
memset(pp,0,sizeof(structSMITH));
}
/*******************史密斯计算部分******************************************/
unsignedintSMITHCalc(structSMITH*pp,unsignedintNextPoint)
{
unsignedintdError,Error;
Error=pp->SetPoint-NextPoint;//计算出偏差
pp->SumError+=Error;//积分
dError=pp->LastError-pp->PrevError;//当前微分
pp->PrevError=pp->LastError;
pp->LastError=Error;
return(pp->Proportion*Error//比例项
+pp->Integral*pp->SumError//积分项
+pp->Derinative*dError);//微分项
}
compare_temper()
{
unsignedchari;
if(set_temper>temper)//判断温度
{
If(set_temper-temper>1)//判断温差是否大于1度
{
high_time=100;
low_time=0;
}
else
{
for(i=0;i<10;i++)
{
get_tember();//得到当前温度
rin=s;//读输入
rout=PIDCalc(&spin,rin);//输出pid计算结果
}
if(high_time<=100)
high_time=(unsignedchar)(rout/800);
else
high_time=100;
low_time=(100-high_time);
}
}
elseif(set_temper<=temper)//如果设定的温度小于测量温度
{
if(temper-set_temper>0)
{
high_time=0;
low_time=100;
}
else
{
for(i=0;i<10;i++)
{
get_temper();
rin=s;//读输入
rout=PIDCalc(&spin,rin);//输出pid计算结果
}
if(high_time<100)
high_time=(unsignedchar)
(rout/10000);
else
high_time=0;
low_time=(100-high_time);
}
}
/*************************************************************************
T1中断服务子程序
*************************************************************************/
voidserve_T1()interrupt1using1
{
if(num_cal==20)
{num_cal=0;
get_temper;//获取温度;
compare_temper();//Smith算法及温度处理
RD==1;
WR=0;
A0=0;
A1=0;
P1=rout;//更新8253脉冲
TH0=0x2f;
TL0=0xe0;
}
else=num_cal++;
}
*************************************************************************/
主程序
*************************************************************************/
main()
{
unsignedcharz;
unsignedchara,b,flag_2=1,count1=0;
unsignedcharphil[]={2,0xce,0x60,0x1c,2};
TMOD=0x21;
TH0=0x2f;
TL0=0x40;
SCON=0x50;
PCON=0x00;
TH1=0xfd;
TL1=0xfd;
PS=1;
EA=1;
EX1=0;
ET0=1;
ES=1;
TR0=1;
TR1=1;
high_time=50;//高电平时间
low_time=50;//低电平时间
init_lcd();//液晶初始化
8253_init();//8253初始化
PIDInit(&spid);//初始化PID结构
spid.Proportion=10;//设定PID系数
spid.Integral=8;
spid.Derivative=6;
spid.SetPoint=100;//SetPIDSetpoint
while
(1)
{
disp_1(phil);//实时显示温度变化
}
}