m8 PID算法 在控制电机时效果不好,上下偏差大
m8 PID算法 在控制电机时效果不好,上下偏差大,那老大帮我分析一下,谢谢函数名称: 参数初始化程序
功 能: 数据初始
参 数: 无
返 回 值: 无
/********************************************/
void czl_set(void)
{
//c_kp =500;
//c_t=1000;
//c_ti =12;
//c_td =1500;
c_en=0;
c_en1 =0;
c_en2 =0;
f210 =500;
f220 =12;
f230 =1500 ;
f240 =1000 ;
f250 =150 ;
}
/*******************************************
计算公式:Kp[(en-en-1)+(T/Ti)en+(Td/T)(en-2*en-1+en-2)]
KP:比例系数(设KP=1~2)
KI:积分系数(设KI=1~2)
float xdata EK,EK1,EK2,PIn //全局变量
返 回 值: 要输出的数据增量
/********************************************/
signed int PID(int tem_en)
{
signed long tem01,tem02,tem03;
signed int tem00;
//Kp[(en-en-1)+(T/Ti)en+(Td/T)(en-2*en-1+en-2)]
//f210
c_en =adc01 -tem_en;
tem02 =c_en;
//===tem02 =tem02*f240;
//===tem02 =tem02/f220/10;
tem02 =tem02*f220/100;
//tem02 =(signed long)c_en*f240/f220/10;//10 =*100/1000
tem03 =(c_en-2*c_en1+c_en2);
tem03 =tem03*f230/100;
//=== tem03 =tem03*10/f240;
//tem03 =(signed long)f230*10*(c_en-2*c_en1+c_en2)/f240; //10 =*100/1000
tem01 =((c_en-c_en1)+tem02+tem03);
tem01=tem01*f210/100;
//tem01 =(signed long)f210*((c_en-c_en1)+tem02+tem03)/100;
//tem02 =c_en*c_t/c_ti/10;//10 =*100/1000
//tem03 =c_td*10*(c_en-2*c_en1+c_en2)/c_t; //10 =*100/1000
//tem01 =c_kp*((c_en-c_en1)+tem02+tem03)/100;
if (tem01< -1000 ) tem01=-1000;
if (tem01> 1000) tem01=1000;
c_en1 = c_en;
c_en2 = c_en1;
return tem01;
}
/*******************************************
函数名称: INT0中断
功 能: 对AVR单片机进行初始化
参 数: 无
返 回 值: 无
/********************************************/
#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{ uint a_b,a_c,a_d,a_x1,a_go1;
signed int tem01,tem11,tem12,tem13;
floattem14;
uint d01,d01n,d02n;
//external interupt on INT0
// CLI();
//adc=mega48_ad();//读出AD的采样值
// SEI();
//PIND//现PD0-7的状态
if (!(isme==1)) return;
a_a =adc;
a_a=(3*a_a)>>1;
adc01=a_a;
if (adc==0)
{TCCR1B = 0;
ad_go=big_x;
dongx=0;
dong=1;
g2g02=0;
g2g03=0;
return;}//stop
//if (k==5)
// {ad_go=1024*8-adc01*16/3;}
//else
c_count=c_count+1;
if (++c_count>=f250)
{
//c_t=1000;
//f240=1000;
//c_count=0;
c_fk_x=fk_x;
c_true01=1;
}
if (c_true01==1 )
{
c_count=0;
c_true01=2;
tem01 =PID(c_fk_x);
tem11=ad_go;
tem11=tem11-tem01;
if (tem11<0) tem11=1;
if (tem11>big_x) tem11=big_x;
ad_go=tem11;
}
// delay_nus(adc/adc_a*adc_b+adc_c);//adc (0-1024)*5+1000 US单位
//delay_nus(adc*5+adc_c);
a_go1 =0xffff-ad_go-adc_c;
TCCR1B = 0; //stop
TCNT1H= (a_go1&0xff00)>>8; //计数器初始值
TCNT1L= a_go1&0x00ff;//计数器初始值
TCCR1B=0x02; //启动定时器1,采用256分频
if (++contx>=8888)
contx =1;
} c_en1 = c_en;
c_en2 = c_en1;
这两句貌似应当交换 数据更新反了吧。c_en1 = c_en;c_en2 = c_en1;应该改成c_en=c_en1;c_en1=c_en2; 谢谢:
c_en2 = c_en1
c_en1 = c_en;
明天,试试 mark。。。。。。。 试一下,学习了解~谢谢
页:
[1]