zjyydn 发表于 2012-7-6 19:57:47

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;
}

lcw_swust 发表于 2012-7-7 00:08:52

c_en1 = c_en;      
c_en2 = c_en1;
这两句貌似应当交换

tiancaigao7 发表于 2012-7-7 08:43:49

数据更新反了吧。c_en1 = c_en;c_en2 = c_en1;应该改成c_en=c_en1;c_en1=c_en2;

zjyydn 发表于 2012-7-7 19:44:14

谢谢:      
c_en2 = c_en1
c_en1 = c_en;
明天,试试

maomeijian 发表于 2012-8-31 19:23:35

mark。。。。。。。

skdyu 发表于 2012-9-3 10:48:07

试一下,学习了解~谢谢
页: [1]
查看完整版本: m8 PID算法 在控制电机时效果不好,上下偏差大