各位高手,本人这个程序调了一天了,他的占空比好像一直不变化!求助!!!用PID做的一个测温程
各位高手,本人这个程序调了一天了,他的占空比好像一直不变化!求助!!!#ifndef pid
#define pid
uchar set; //温度初始值
uint rout; // PID Response (Output)
uchar high_time,low_time,count=0; //占空比调节参数
struct PID {
unsigned int SetPoint; // 设定目标 Desired Value
unsigned int Proportion; // 比例常数 Proportional Const
unsigned int Integral; // 积分常数 Integral Const
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 Control Structure
/****************pid初始化*********************/
void init_pid()
{
high_time=50;
spid.LastError = 20;
spid.PrevError = 20;
spid.SumError= 20;
spid.Proportion = 20; // Set PID Coefficients
spid.Integral = 8;
spid.Derivative =6;
spid.SetPoint = set; // Set PID Setpoint
}
/***************************PID算法**************************/
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
unsigned int dError=0,Error=0;
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->Derivative * dError);
}
/********************PID控制占空比*************************/
//high_time表示高电平数
void duty_cycle(uint t) // 占空比
{
/* uchar s;
s=set;
if(s>t)
{
if(s-t>2)
high_time=100;
else
{
rout = PIDCalc ( &spid,t ); // Perform PID Interation
if(high_time<=100)
high_time=(uchar)(rout/600);
else
high_time=100;
}
}
else
{
high_time=0;
}
*/
uchar i;
if(set>t)
{
if(set-t>3)
{
high_time=100;
low_time=0;
}
else
{
for(i=0;i<10;i++)
{
rout=PIDCalc(&spid,t);
}
if(high_time<=100)
high_time=(uchar)(rout/800);
else
{ high_time=100;
low_time=(100-high_time);
}
}
}
else if(set<=t)
{
if(t-set>0)
{
high_time=0;
low_time=100;
}
else
{
for(i=0;i<10;i++)
{
rout=PIDCalc(&spid,t);
}
if(high_time<=100)
high_time=(uchar)(rout/10000);
else
high_time=100;
low_time=(100-high_time);
}
}
}
#endif
void main ()
{
uint t;
TMOD=0x01;
TH0 =0x10;
TL0 =0x10;
EA= 1;
ET0 = 1;
TR0 = 1;
set=70;
init_pid();
view();
while(1)
{
t=gettemp;
duty_cycle(t);
}
}
/*void t0_int(void) interrupt 1 //PWM波输出
{
if(++count<=(high_time))
SWH=0;
else if(count<=100)
SWH=1;
else
count=0;
TH0=0x10;//定时器初始化
TL0=0x10;
} */
void t0() interrupt 1
{
TF0=0;
TR0=0;
if(++count<=(high_time))
SWH=0;
else if((high_time)<count<=100)
{
SWH=1;
}
else
//SWH=0;
count=0;
TH0=0x10;
TL0=0x10;
TR0=1;
} 请问你调试成功了吗 可以说说是什么问题吗? 楼主可以试试增量式PID,我感觉效果还不错,目前还在调呢 本帖最后由 okyinglong 于 2012-4-19 23:08 编辑
请教楼上的 我的是采用增量式 PID我用89c51单片 如何将PID值利用一个定时器来控制IO口状态 (也就是温度控制中,用PID算法得到的是一个数值,这个数值如何转换为占空比?)我的思路是下面的 但是我知道不行
void compare_temper() //PID温度控制输出函数
{
unsigned char i;
if(set_temper>temper)
{
if(set_temper-temper>50)//如果控制目标温度温与实时温度差大于5度,(放大10倍)是50
{
pwms = 256; //PWM 输出高电平占空比最大。即全速加温
}
else
{
for(i=0;i<10;i++) //5度范围内PID增量控制,10次周期 即PID积分式中T=10
{
rin=ReadTemperature();//PID输入实时温度采样值
rout = PIDCalc ( &spid,rin ); // PID增量输出
} //PID增量输出范围(0-255)配合pwm取值范围
if(rout>=240)rout=240; //保障PWM输入值10-240 防止pwm出现失调。stc单片机特性。
if(rout<=20)rout=20;
pwms=255-rout;
}
}
else if(set_temper<=temper) //目标温度小于实时温度pwm输出低电平最高占空比,关闭加热。
{
pwms = 250;
}
}
/***************************************************************
* 占空比处理函数 *
***************************************************************/
void init_t0()
{
TMOD=0X02; //定时器0,工作模式2(0000,0010),8位定时模式
TH0=0x06; //写入预置初值6到定时器0,使250微秒溢出一次(12MHz)
TL0=0x06; //写入预置值
TR0=1; //启动定时器
ET0=1; //允许定时器0中断
EA=1; //允许总中断
}
void timer0() interrupt 1 //定时器0中断服务程序
{
staticunsigned int tt ; //tt用来保存当前时间在一秒中的比例位置
tt++; //每250微秒增加1
if(tt>=240)
tt = 0;
if(tt<=pwms) //2.5毫秒的时钟周期
{
tt=0;//使tt=0,开始新的PWM周期
P2_0=1;
}
else
{
//if(scale==tt)//按照当前占空比切换输出为高电平
P2_0=0;
}
}
页:
[1]