倒立摆,pid算法

2019-08-16 19:32发布

各个模块都正常,但好像算法部分就是有问题,救助啊
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
#include "adc.h"
#include "lcd.h"
#include "encode.h"

u8 mode;
u16 adcx,count,num;
u8 flag=0;

int err,err_last,err2,err2_last,set_num=1000,set_adcx=2075;
int  pid_bianma,pid_adc;
//float  kp=0,kd=0,ki=0,kp2=3.3,kd2=5,ki2=0,i=0,i2=0;   //kp ±àÂëÆ÷ kp2 adc
float  kp=0,kd=0,ki=0,kp2=4.3,kd2=15.0,ki2=0,i=0,i2=0;   //kp ±àÂëÆ÷ kp2 adc
int pwma=0,pwmb=0;

float pidbianma(void );
float pidadc(void );
u16 Get_Adc_Average(u8 ch,u8 times);

//int Error,Error_Last,Error1,Error1_Last,Target1 = 3000,Target = 535; //515
//float PID_Out,PID_Out1,PID_Out2;
//float Kp =0,Kd = 0,Kp1 = 0,Kp2 = 50,Kd2 =0;
    int main(void)
{        
     //u16 led0pwmval=0;
//u16 adcx,volt;
    u16 temp;
    float jiaodu;
    u8 dir=1;
//    u8 mode=1;
     u16 count;//±àÂëÆ÷¼ÆÊý   PB6 PB7
     
    delay_init();             //ÑÓʱº¯Êý³õʼ»¯      
    NVIC_Configuration();      //ÉèÖÃNVICÖжϷÖ×é2:2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶
    uart_init(9600);     //´®¿Ú³õʼ»¯Îª9600
     LED_Init();                 //LED¶Ë¿Ú³õʼ»¯
    LCD_Init();                 
     Adc_Init();                  //ADC³õʼ»¯
    TIM4_Init();//¶¨Ê±Æ÷±àÂëÆ÷½Ó¿Ú³õʼ»¯

     TIM3_PWM_Init(999,17);     //²»·ÖƵ¡&#163WMƵÂÊ=4Khz
  TIM5_Int_Init(999,1439);  //¶¨Ê± 10ms 719 5ms 1439

    POINT_COLOR=BLUE;//ÉèÖÃ×ÖÌåΪÀ¶É«
    LCD_ShowString(60,130,200,16,16,"ADC_CH0_VAL:");         
    LCD_ShowString(60,150,200,16,16,"ADC_CH0_JDU:");      
       while(1)
    {
//         delay_ms(10);     
//        if(dir)led0pwmval++;
//        else led0pwmval--;

//         if(led0pwmval>300)dir=0;
//        if(led0pwmval==0)dir=1;                                         
//        //TIM_SetCompare2(TIM3,led0pwmval);
        
        if(num>1500) num =1500;
        if(num<500)  num =500;      
        
          adcx=Get_Adc_Average(ADC_Channel_1,10);
            LCD_ShowxNum(156,130,adcx,4,16,0);//&#207;&#212;&#202;&#190;ADC&#181;&#196;&#214;&#181;
          jiaodu=adcx*(360/4096);
            LCD_ShowxNum(156,150,jiaodu ,4,16,0);//&#207;&#212;&#202;&#190;&#181;&#231;&#209;&#185;&#214;&#181;
         
          count = TIM4->CNT/4;//&#187;&#241;&#200;&#161;&#188;&#198;&#202;&#253;&#214;&#181;
          num=count ;
          //delay_ms(500);//&#195;&#191;&#184;&#244;1s&#180;ò&#211;&#161;&#210;&#187;&#180;&#206;±à&#194;&#235;&#198;÷&#189;&#199;&#182;&#200;,&#211;&#195;&#202;&#214;&#200;&#165;&#178;&#166;&#182;&#175;±à&#194;&#235;&#198;÷  &#202;&#185;&#198;&#228;&#194;&#253;&#203;&#217;&#208;&#253;×
          printf ("adcx%d  ",adcx );
//          printf ("%d  ",pid_bianma );
          printf ("%d  ",pwma  );
        printf("count%d ",num  );
            
//            printf("%d ",pwma );
//            printf("%d ",pwmb );
            
            //delay_ms (500);
         
//      if(mode ==1)
//      {               
//                TIM_SetCompare2(TIM3,500);   //TIM3_CH2 PA7
//                TIM_SetCompare1(TIM3,0);     //TIM3_CH1 PA6
//                delay_ms (1000);             //TIM3_CH3 PB0
//                TIM_SetCompare2(TIM3,0);
//                TIM_SetCompare1(TIM3,500);
//                delay_ms (500);               
//      }
//      else if(mode==2)
//      {
//                TIM_SetCompare2(TIM3,0);
//                TIM_SetCompare1(TIM3,300);
//                delay_ms (1000);
//                TIM_SetCompare2(TIM3,800);
//                TIM_SetCompare1(TIM3,0);
//                delay_ms (1000);
//            }
//            else if(mode ==3)
//            {            
////                pwma =500+pid_bianma +pid_adc ;
////                pwmb= 500-pid_bianma -pid_adc ;
//                if(flag >=4)
//                {
//                flag =0;
//                pwma =500-pidbianma()+pidadc() ;
//                pwmb =500+pidbianma()-pidadc() ;
//                }
//                else
//                {
//                    pwma =500+pidadc ();
//                    pwmb =500-pidadc ();
//                    flag ++;
//                }
//               
//                if(pwma >999) pwma =999;
//                if(pwma<0)    pwma =0;
//               if(pwmb >999) pwmb =999;
//                if(pwmb<0)    pwmb =0;   
//               
//                TIM_SetCompare2(TIM3,pwma );   //TIM3_CH2 PA7
//                TIM_SetCompare1(TIM3,pwmb );     //TIM3_CH1 PA6
////                delay_ms (1000);             //TIM3_CH3 PB0
////                TIM_SetCompare2(TIM3,0);
////                TIM_SetCompare1(TIM3,500);
////                delay_ms (500);   
//               
//            }
//            else if(mode ==4)
//            {
//                TIM_SetCompare2(TIM3,0 );   //TIM3_CH2 PA7
//                TIM_SetCompare1(TIM3,0 );     //TIM3_CH1 PA6
//            }
             }
            
        
    }     
// float PID_Cal2()           //??? ???
//{
//Error1 = Target1 -num;        //Target1 = 3000,Target = 515;
//PID_Out2 = Error1*Kp2 + (Error1 - Error1_Last)*Kd2;       //num = 3000
//Error1_Last = Error1;
//return PID_Out2;
//}
        float pidbianma()
        {
            err=set_num-num  ;
            pid_bianma=err*kp+(err-err_last )*kd;
            err_last =err ;
            return pid_bianma ;
        }
        float pidadc()
        {
//         adcx=Get_Adc_Average(ADC_Channel_1,10);
//            err2 =set_adcx - adcx ;
            err2 =set_adcx -Get_Adc_Average(ADC_Channel_1,10) ;
            pid_adc =err2 *kp2 +(err2 -err2_last )*kd2 ;
            err2_last =err2 ;
            return pid_adc ;
        }
void TIM5_IRQHandler(void)   //TIM3&#214;&#208;&#182;&#207;
{
    if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //&#188;ì&#178;é&#214;&#184;&#182;¨&#181;&#196;TIM&#214;&#208;&#182;&#207;·&#162;&#201;ú&#211;&#235;·&#241;:TIM &#214;&#208;&#182;&#207;&#212;&#180;
        {
        TIM_ClearITPendingBit(TIM5, TIM_IT_Update  );  //&#199;&#229;&#179;&#253;TIMx&#181;&#196;&#214;&#208;&#182;&#207;&#180;&#253;&#180;&#166;&#192;í&#206;&#187;:TIM &#214;&#208;&#182;&#207;&#212;&#180;
        LED1=!LED1;
            if(adcx <1690||adcx >2570)//2650 3530   
            {
                mode =4;
            }
            else  mode =3;
            
//            if(mode ==1)
//      {               
//                TIM_SetCompare2(TIM3,500);   //TIM3_CH2 PA7
//                TIM_SetCompare1(TIM3,0);     //TIM3_CH1 PA6
//                delay_ms (1000);             //TIM3_CH3 PB0
//                TIM_SetCompare2(TIM3,0);
//                TIM_SetCompare1(TIM3,500);
//                delay_ms (500);               
//      }
//      else if(mode==2)
//      {
//                TIM_SetCompare2(TIM3,0);
//                TIM_SetCompare1(TIM3,300);
//                delay_ms (1000);
//                TIM_SetCompare2(TIM3,800);
//                TIM_SetCompare1(TIM3,0);
//                delay_ms (1000);
//            }
             if(mode ==3)
            {            
        err2 =set_adcx -adcx  ;
              pid_adc =err2 *kp2 +(err2 -err2_last )*kd2 +i2*ki2 ;
              err2_last =err2 ;
                i2=i2+err2;
               
                err=set_num-num  ;
              pid_bianma=err*kp+(err-err_last )*kd+i*ki;
              err_last =err ;
                i=i+err ;
               
                if(flag >=4)
                {
                flag =0;
//                pwma =500-pidbianma()+pidadc() ;
//                pwmb =500+pidbianma()-pidadc() ;
                    pwma =pid_bianma+pid_adc;
                  pwmb =pid_bianma-pid_adc;
                }
                else
                {
//                    pwma =500+pidadc ();
//                    pwmb =500-pidadc ();
                    pwma =pid_adc;
                  pwmb =-pid_adc;
                    flag ++;
                }
                if(pwma<0)
                {
                    pwma =-pwma ;
                    if(pwma >600) pwma =600;
                    if(pwma<0)    pwma =0;
                    
                    TIM_SetCompare2(TIM3,pwma );   //TIM3_CH2 PA7
                  TIM_SetCompare1(TIM3,0  );     //TIM3_CH1 PA6
                }
                else
                {
                    if(pwma >600) pwma =600;
                    if(pwma<0)    pwma =0;
                    TIM_SetCompare2(TIM3,0 );   //TIM3_CH2 PA7
                  TIM_SetCompare1(TIM3,pwma   );     //TIM3_CH1 PA6
                }
               
//                if(pwma >999) pwma =999;
//                if(pwma<0)    pwma =0;
//               if(pwmb >999) pwmb =999;
//                if(pwmb<0)    pwmb =0;   
//               
//                TIM_SetCompare2(TIM3,pwma );   //TIM3_CH2 PA7
//                TIM_SetCompare1(TIM3,pwmb  );     //TIM3_CH1 PA6
//                delay_ms (1000);             //TIM3_CH3 PB0
//                TIM_SetCompare2(TIM3,0);
//                TIM_SetCompare1(TIM3,500);
//                delay_ms (500);   
               
            }
            else if(mode ==4)
            {
                TIM_SetCompare2(TIM3,0 );   //TIM3_CH2 PA7
                TIM_SetCompare1(TIM3,0 );     //TIM3_CH1 PA6
            }
               
            
            
        }
}



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
14条回答
bruceleegyx
2019-08-17 20:08
18702393252 发表于 2017-7-26 11:18
D是什么  听说过P/PI/PID 没听说单给D

微分(D)控制
在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系. 自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳.其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化.解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零.这就是说,在控制器中仅引入“比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调.所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性.

一周热门 更多>