我的主题是基于PID算法的温度控制系统
89C51单片机,通过键盘输入预置值,与DS18B20测量的实际值进行比较,然后驱动冷却或加热电路。用Keil C语言实现PID控制。
最好的答案
//PID算法温度控制c语言-08-17 183336958
#include
#include
#include
#include
Structpid}
Unsigned int SetPoint//设定目标Desired Value
Unsigned int Proportion//比例常数Proportional Const
Unsigned int Integral//积分常数integrateconst
Unsigned int Derivative//微分常数Derivative Const
Unsigned int LastError//Error[-1]
Unsigned int PrevError//Error[-2]
Unsigned int SumError//Sums of Errors
}
Struct PID spid//PID控制结构
Unsigned int rout//PID响应(Output)
Unsigned int rin//PID Feedback(输入)
sbit data 1=P1 0;
sbit clk=P1 1;
sbit plus=P2 0;
sbit subs=P2 1;
sbit stop=P2 2 2;
sbit output=P3 4;
sbit dq=P3 3;
Unsigned char flag,flag _ 1=0;
Unsigned char high _ time、low _ time、count=0;//占空比调整参数
Unsigned char set _ temper=35
Unsigned char temper
unsigned char I;
unsigned char j=0;
unsigned int s;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
延迟子程序,延迟时间基于12M确定诊,延迟时间为30ustime
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Void delay(unsigned char time)
Unsigned char m,n;
for(n=0);ni;/*将此写入移动到最低位*/
Temp=temp1
write _ bit(temp);/*将此位写入总线*/
}
delay(7);/*延迟120us后*/
//TR0=1;
EA=1;/*开幕*/
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
读取数据子例程
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Unsigned char read_bit()
Unsigned char i,value _ bit
EA=0;
DQ=0;/*低DQ,开始读取计时*/
_ nop _();
_ nop _();
DQ=1;/*禁用总线*/
for(I=0);I2;I ){}
Value _ bit=DQ
EA=1;
return(value _ bit);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
读取单字节数据子程序
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Unsigned char read_byte()
Unsigned char i,value=0;
EA=0;
for(I=0);i8;I))
If(read_bit()) /*单字节数据读取、一次读取和移动*/
Value |=0x014
temper=I | j;/*获得的温度在temper上*/
}
/*=======================================================================================
Initialize PID Structure
=======================================================================================*/
Void PIDInit (struct PID *pp)
Memset (pp,0,size of(struct PID));
}
/*=======================================================================================
PID计算部分
=======================================================================================*/
unsigned int PID calc(struct PID * PP,unsigned int next point)
Unsigned int dError,Error
error=PP-SetPoint-next point;//偏差
PP-sum Error=Error;//积分
d error=PP-last error-PP-prev error;//当前微分
PP-PrevError=PP-last error;
PP-LastError=Error;
Return (pp-Proportion *错误//速率
Pp-Integral * pp-SumError //积分项
PP-Derivative * dError);//微分项目
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
温度比较处理子例程
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Compare_temper()
unsigned char I;
If(set_tempertemper)
If(set_temper-temper1)
High _ time=100
low _ time=0;
}
Else
for(I=0);I10I))
{ get _ temper();
rin=s;//Read Input
Rout=PIDCalc (spid,rin);//Perform PID Interation
}
If (high_time=100)
high _ time=(unsigned char)(route/800);
Else
High _ time=100
low _ time=(100-high _ time);
}
}
Else if(set_temper=temper)
If(temper-set_temper0)
high _ time=0;
Low _ time=100
}
Else
for(I=0);I10I))
{ get _ temper();
rin=s;//Read Input
Rout=PIDCalc (spid,rin);//Perform PID Interation
}
If (high_time100)
high _ time=(unsigned char)(route/10000);
Else
high _ time=0;
low _ time=(100-high _ time);
}
}
//else
//{}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
T0中断服务子程序,控制级别翻转,40us * 100=4毫秒周期
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Void serve_T0() interrupt 1 using 1
If(count=(high_time))
output=1;
Else if(count=100)
output=0;
}
Else
count=0;
TH0=0x2f
TL0=0xe0
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
串行中断服务程序,用于