久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2230|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

基于KEA128處理器的二輪直立程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:427725 發(fā)表于 2018-11-16 15:02 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
簡單粗暴,直接上代
#include "headfile.h"
#define     PIT_FlAG_CLR(PITn)          PIT->CHANNEL[PITn].TFLG |= PIT_TFLG_TIF_MASK        //清中斷標志(寫1 清空標志位)
#define zhongzhi            -17.4           //小車的目標角度
#define PonitSpeed          130
#define Induct_add          200
#define PWMMAX          1500//1800
#define PWMMIN          500//200
void SensorStructurePointerInit(Acc_Type_Def *Acc, Gyro_Type_Def *Gyro, Angle_Type_Def *Angle, Speed_Type_Def *Speed ){ //結(jié)構(gòu)體指針初始化成員

  /*Gyro*/  
  Gyro->X_Final=0;
  Gyro->X_Offset=0;
  Gyro->X_Value[0]=0;
  Gyro->X_Value[1]=0;
  Gyro->X_Value[2]=0;

  Gyro->Z_Final=0;
  Gyro->Z_Offset=0;
  Gyro->Z_Value[0]=0;
  Gyro->Z_Value[1]=0;
  Gyro->Z_Value[2]=0;


  //角度目標值  也就是平衡值  沒有轉(zhuǎn)換成角度值 但是是線性關(guān)系。
  Angle->PiontValue = zhongzhi;

  //速度目標值  沒有轉(zhuǎn)換成真實速度  與速度線性關(guān)系
  Speed->PiontSpeed =        PonitSpeed;


  Speed->PiontSpeedMax=600;

  Speed->PiontSpeedMin=-600;



}


void CarBalanceSystemInit(Gyro_Type_Def *Gyro){//系統(tǒng)初始化
  adc_init(ADC0_SE0);       
  adc_init(ADC0_SE1);       
  adc_init(ADC0_SE2);       
  adc_init(ADC0_SE3);       
  adc_init(ADC0_SE6);
  adc_init(ADC0_SE7);

  OLED_Init();                         //OLED初始化

  IIC_init();                          // 使用數(shù)字陀螺儀要初始化IIC
  InitMPU6050();                                                     //MPU6050的初始化函數(shù)
  systick_delay_ms(10);
  gpio_init(C7,GPO,1);                 // 使能FTM
  //左電機
  ftm_pwm_init(ftm2,ftm_ch0,13000,0);       
  ftm_pwm_init(ftm2,ftm_ch1,13000,0);               

  //右電機  
  ftm_pwm_init(ftm2,ftm_ch2,13000,0);               
  ftm_pwm_init(ftm2,ftm_ch3,13000,0);       

  systick_delay_ms(10);  

  //ftm的計數(shù)引腳可查看KEA128_port_cfg.h文件內(nèi)的FTM0_COUNT_PIN與FTM1_COUNT_PIN的宏定義得知
  //一個ftm同一時間只能實現(xiàn)一種功能,如果用于測速就不能用于輸出PWM       
  ///////////////////////////////////////////////////////////////////////////////////////////////
  ftm_count_init(ftm0);   //對引腳輸入的脈沖進行計數(shù)         接編碼器LSB   
  gpio_init(D3,GPI,0);    //用于判斷方向                    接編碼器DIR
  port_pull(D3);          //IO上拉

  ftm_count_init(ftm1);   //對引腳輸入的脈沖進行計數(shù)         接編碼器LSB
  gpio_init(D4,GPI,0);    //用于判斷方向                    接編碼器DIR
  port_pull(D4);          //IO上拉
  //////////////////////////////////////////////////////////////////////////////////////////////

  //定時器中斷
  pit_init(pit0,0x9000);//1.539ms

  systick_delay_ms(10);  


}


//絕對值函數(shù)   必須要取地址放入形參
void AbsoluteValue(float *Value, float *Return){

  if( (*Value) <0) (*Return) = -1*(*Value);
  else *Value = *Return;
}

/*原始數(shù)據(jù)獲取部分*/
void GetAccelerationValue(Acc_Type_Def *Acc){ //獲取ACC原始數(shù)據(jù)
  Get_AccData();        
  Acc->Z_Value[0] = Acc->Z_Value[1];
  Acc->Z_Value[1] = Acc->Z_Value[2];
  Acc->Z_Value[2] = ACC_Z;//本句是獲取當(dāng)前加速度  上兩句都是 上次值和上上次值
}

void GetAngleSpeedValue(Gyro_Type_Def *Gyro){  //獲取Gyro原始數(shù)據(jù)
  Get_Gyro();  
  Gyro->Z_Value[0] = Gyro->Z_Value[1];
  Gyro->Z_Value[1] = Gyro->Z_Value[2];
  Gyro->Z_Value[2] = GYRO_Z ;             //本句是獲取當(dāng)前Gyro上兩句都是 上次值和上上次值
       
  Gyro->X_Value[0] = Gyro->X_Value[1]; //前前次
  Gyro->X_Value[1] = Gyro->X_Value[2]; //前次
  Gyro->X_Value[2] = GYRO_X ;          //本次
}

//FTM0-E0  FTM1-E7  左右重新確認
void GetSpeedValue(Speed_Type_Def *Speed){ //獲取Speed原始數(shù)據(jù)

  for(uint8 n=0; n<15 ; n++){  //循環(huán)誤差保存   
    //存儲前14次的值  
    Speed->ActualLiftPulse[n] = Speed->ActualLiftPulse[n+1]; //0~14位賦值  
    if( n==14 ){ //當(dāng)前值 15次  最新值
      Speed->ActualLiftPulse[n+1] = ftm_count_get(ftm1)*(-1); //本次 15位賦值        
      ftm_count_clean(ftm1);  //清除ftm1計數(shù)值  
    }//此處一定要修改好 根據(jù)實際的硬件  對應(yīng)好左右輪子  因為編碼器是對著安裝的  那么
    //在車子往前走的時候  左右是相反的  所以要把其中一個負值編碼器變?yōu)檎?br />     //兩個電機存在同樣的問題  都是對著安裝的  
  }   
  //同上
  for(uint8 n=0; n<15 ; n++){  //循環(huán)保存

    Speed->ActualRightPulse[n] = Speed->ActualRightPulse[n+1]; //0~14位賦值  
    if( n==14 ){
      Speed->ActualRightPulse[n+1] = ftm_count_get(ftm0);  //本次 15位賦值
      ftm_count_clean(ftm0);  //清除ftm0計數(shù)值  
    }

  }

  if(gpio_get(D4)) //檢測 ftm1的轉(zhuǎn)向   H6  E1是針對左右編碼器的  要弄清楚 不要到時候改過以后
    //左邊編碼器的方向  去控制右邊編碼器的 正負號   那就完蛋了
    Speed->ActualLiftPulse[15] = -Speed->ActualLiftPulse[15];
  else               
    Speed->ActualLiftPulse[15] = Speed->ActualLiftPulse[15];            


  if(gpio_get(D3))  //檢測 ftm0的轉(zhuǎn)向  
    Speed->ActualRightPulse[15] = -Speed->ActualRightPulse[15];
  else               
    Speed->ActualRightPulse[15] = Speed->ActualRightPulse[15]; //這個負號取決于你車向前走時  編碼器值是否為正      

}

void AngleSoftwareFilter(Acc_Type_Def *Acc, Gyro_Type_Def *Gyro , Angle_Type_Def *Angle)
{ //本函數(shù)用于數(shù)字陀螺儀 通過軟件互補融合濾波解算角度  

        //加速度  角速度采集
  Acc->Z_Final = 0.9*Acc->Z_Value[2] + 0.05*Acc->Z_Value[1] + 0.05*Acc->Z_Value[0];     //權(quán)值低通濾波  
  Gyro->Z_Final = 0.9*Gyro->Z_Value[2] + 0.05*Gyro->Z_Value[1] + 0.05*Gyro->Z_Value[0];//權(quán)值低通濾波
  Gyro->X_Final = 0.92*Gyro->X_Value[2] + 0.05*Gyro->X_Value[1] + 0.03*Gyro->X_Value[0];//權(quán)值低通濾波  
  //此處參數(shù)需要根據(jù)  清華方案里的方法去調(diào)節(jié)參數(shù)  看波形法
  Angle->FinalValue = 0.98*(Angle->FinalValue -0.05*Gyro->Z_Final) + 0.02*(Acc->Z_Final);//融合濾波

}

//void SpeedSoftwareFilter(Speed_Type_Def *Speed){   //速度低通濾波
//   
//  /*警告無視*////編碼器收到的數(shù)據(jù)  在文件前面有函數(shù)讀取
//  Speed->ActualLiftPulse[15]=0.33*Speed->ActualLiftPulse[15] + 0.33*Speed->ActualLiftPulse[14] + 0.33*Speed->ActualLiftPulse[13];
//  Speed->ActualRightPulse[15]=0.33*Speed->ActualRightPulse[15] + 0.33*Speed->ActualRightPulse[14] + 0.33*Speed->ActualRightPulse[13];
//  // 6 2 2
//  
//  //實際速度 = R+L
//  Speed->ActualSpeed[0] = Speed->ActualSpeed[1];
//  Speed->ActualSpeed[1] = Speed->ActualSpeed[2];
//  Speed->ActualSpeed[2] =
//    ((Speed->ActualRightPulse[0]+Speed->ActualLiftPulse[0])+
//    (Speed->ActualRightPulse[1]+Speed->ActualLiftPulse[1])+                    
//    (Speed->ActualRightPulse[2]+Speed->ActualLiftPulse[2])+
//    (Speed->ActualRightPulse[3]+Speed->ActualLiftPulse[3])+
//    (Speed->ActualRightPulse[4]+Speed->ActualLiftPulse[4])+
//    (Speed->ActualRightPulse[5]+Speed->ActualLiftPulse[5])+
//    (Speed->ActualRightPulse[6]+Speed->ActualLiftPulse[6])+
//    (Speed->ActualRightPulse[7]+Speed->ActualLiftPulse[7])+
//    (Speed->ActualRightPulse[8]+Speed->ActualLiftPulse[8])+
//    (Speed->ActualRightPulse[9]+Speed->ActualLiftPulse[9])+
//    (Speed->ActualRightPulse[10]+Speed->ActualLiftPulse[10])+
//    (Speed->ActualRightPulse[11]+Speed->ActualLiftPulse[11])+
//    (Speed->ActualRightPulse[12]+Speed->ActualLiftPulse[12])+
//    (Speed->ActualRightPulse[13]+Speed->ActualLiftPulse[13])+
//    (Speed->ActualRightPulse[14]+Speed->ActualLiftPulse[14])+
//    (Speed->ActualRightPulse[15]+Speed->ActualLiftPulse[15]))/32;
//  
//  //濾波
//  Speed->ActualSpeed[2] = 0.85*Speed->ActualSpeed[2]+0.1*Speed->ActualSpeed[1]+0.05*Speed->ActualSpeed[0];
//  //7 2 1
//   
//  //實際差速  = L-R
//  Speed->ActualDifferential[0] = Speed->ActualDifferential[1];
//  Speed->ActualDifferential[1] = Speed->ActualDifferential[2];
//  Speed->ActualDifferential[2] = Speed->ActualLiftPulse[15]-Speed->ActualRightPulse[15];
//  Speed->ActualDifferential[2] = 0.8*Speed->ActualDifferential[2]+0.15*Speed->ActualDifferential[1]+0.05*Speed->ActualDifferential[0];
//  //實際差速
//  Speed->ActualInstantaneous[0] = Speed->ActualInstantaneous[1];  
//  Speed->ActualInstantaneous[1] = Speed->ActualInstantaneous[2];
//  Speed->ActualInstantaneous[2] = (Speed->ActualLiftPulse[15]+Speed->ActualRightPulse[15] + (Speed->ActualLiftPulse[14]+Speed->ActualRightPulse[14])) ;
//  //瞬時速度計算
//  Speed->ActualAcceleration = Speed->ActualInstantaneous[2] - Speed->ActualInstantaneous[0];
//  //加速度計算
//   
//}

void MotorControlFlow(PWM_Type_Def *PWM, Ramp_Type_Def *Ramp)
{
//電機直接控制

//如測試線序 在此處 對*PWM賦值 測試完畢再注釋

//PWM->LiftValue = 1200;//左輪正傳  往前走
////PWM->LiftValue = 1000;
////PWM->LiftValue = 800;

//PWM->RightValue =1200;//右輪正傳 往前走
// PWM->RightValue = 1000; //PWM->RightValue = 800;

//左邊右邊都給 1000的時候 應(yīng)該是不轉(zhuǎn)的   

  if(PWM->LiftValue>(PWMMAX))PWM->LiftValue = (PWMMAX);
  if(PWM->LiftValue<(PWMMIN))PWM->LiftValue = (PWMMIN);
  if(PWM->RightValue>(PWMMAX))PWM->RightValue = (PWMMAX);
  if(PWM->RightValue<(PWMMIN))PWM->RightValue = (PWMMIN);

  //此處必須先調(diào)整好  保證 PWM值是 >1000時  是前進
  //PWM值< 1000 是后退   而且 兩輪必須一致
  //能改硬件 就改驅(qū)動線  和 電機引線  例如
  //給同樣都是  1200  左邊電機慢速往前  右邊慢速往后 這時候 調(diào)換右電機線
  //如果出現(xiàn)如下情況  給1200  理論上是 正轉(zhuǎn) 20%占空比  但出現(xiàn)轉(zhuǎn)速很快 說明
  //驅(qū)動線序不對   可以在這里調(diào)換 通道  或者 直接改線序

  if(PWM->LiftValue>1000){ //左輪前進  1000~2000
     ftm_pwm_duty(ftm2,ftm_ch1,PWM->LiftValue-1000);
     ftm_pwm_duty(ftm2,ftm_ch0,0);
  }
  else if(PWM->LiftValue<1000){ //左輪是后退  0~1000
     ftm_pwm_duty(ftm2,ftm_ch1,0);
     ftm_pwm_duty(ftm2,ftm_ch0,1000-PWM->LiftValue);   
  }  //如果發(fā)現(xiàn) 此處給定的是  控制 右輪轉(zhuǎn)動 則調(diào)換下硬件驅(qū)動線線序  注意 是兩根兩根的調(diào)換  


  if(PWM->RightValue>1000){ //右輪是前進  1000~2000
     ftm_pwm_duty(ftm2,ftm_ch3,PWM->RightValue-1000);
     ftm_pwm_duty(ftm2,ftm_ch2,0);
  }
  else if(PWM->RightValue<1000){ //右輪是后退  0~1000
     ftm_pwm_duty(ftm2,ftm_ch3,0);
     ftm_pwm_duty(ftm2,ftm_ch2,1000-PWM->RightValue);   
  }   //如果發(fā)現(xiàn) 此處給定的是  控制 左邊輪轉(zhuǎn)動 則調(diào)換下硬件驅(qū)動線線序  注意 是兩根兩根的調(diào)換   

}

/*被控制量處理部分*/
void BalanceFeedbackControl(PID_Type_Def *PID, Angle_Type_Def *Angle, Gyro_Type_Def *Gyro, Ramp_Type_Def *Ramp){ //直立反饋控制

  PID->err = -(Angle->PiontValue-Angle->FinalValue);//硬件
  //偏差  =  角度目標-角度反饋值
  PID->out =   1000 + PID->Kp * PID->err + PID->Kd * Gyro->Z_Final;
  //1000是為了給一個PWM中點   Gyro->Z_Final就是 直立的角速度  也就是D控制  PD
  //一般情況下  調(diào)直立時   先給一個P參數(shù)  D給0   就能立起來   如果發(fā)現(xiàn)不能立瘋轉(zhuǎn)  
  //多半是 pid方向相反    把(Angle->PiontValue-Angle->FinalValue)  里面調(diào)換下位置  即可  
};

//牛頓迭代法 開方運算
float newtonSqrt(float a){  
  int i;  
  float x;  
  x=a;  
  for(i=1;i<=10;i++)  
    x=(x+a/x)/2;  
  return x;  
}

//void DirectionFeedbackControl(PID_Type_Def *PID, Inductor_Type_Def *InductorA, Inductor_Type_Def *InductorB, Gyro_Type_Def *Gyro, Speed_Type_Def *Speed, Ramp_Type_Def *Ramp){ //方向反饋控制
//
//  //調(diào)節(jié)offset 在中間位置的時候讓左邊的電感等于右邊的電感
//  InductorB->LeftFinal = PID->offset*InductorB->LeftFinal;  
//  InductorA->LeftFinal = (2-PID->offset)*InductorA->LeftFinal;
//  //調(diào)整零偏
//  
//  //主要是左右兩個電感
//  PID->err = 10*((newtonSqrt(InductorB->LeftFinal)-newtonSqrt(InductorA->LeftFinal ))/ (InductorB->LeftFinal+InductorA->LeftFinal));
//  //如果和值小于一個數(shù)值可認為沒有偏差 車子繼續(xù)沿著中間路線行駛
//  if(InductorA->AndValues<Induct_add)  PID->err = 0;
//  
// //*************注意PD的極性也就是正負*******************
//  PID->out = PID->Kp * PID->err +PID->Kd * Gyro->X_Final;
//  //轉(zhuǎn)向PID輸出計算 Gyro->X_Final; 是轉(zhuǎn)向角速度 也是D控制
// //*************注意PD的極性也就是正負******************
//  
//  Speed->PiontDifferential = (int16)(PID->out);  //給定差速環(huán)目標值
//  //把轉(zhuǎn)向環(huán)計算出來的輸出值給差速目標環(huán)
//  
//       
//  for(uint8 n=0; n<9 ; n++){  //循環(huán)誤差保存
//   
//    PID->err_k[n] = PID->err_k[n+1]; //0~8位賦值
//   
//    if( n==8 )
//      PID->err_k[n+1] = PID->err;  //本次 9位賦值
//   
//  }
//
//};

////差速環(huán)就是角速度和編碼器的值一起控制
//void DifferentialFeedbackControl(PID_Type_Def *PID, Speed_Type_Def *Speed, Gyro_Type_Def *Gyro){//差速反饋控制
//     
//  //PID->offset只是一個比例分配  PID->offset=2     
//  int16 SpeedDifferentialValue = PID->offset * Speed->ActualDifferential[2] + (1-PID->offset)*(-0.18*Gyro->X_Final);
//  //得到差速值是編碼器和轉(zhuǎn)向角速度共同決定差速反饋值
//   
//  //差速目標-  差速實際值
//  PID->err = ( Speed->PiontDifferential -  SpeedDifferentialValue);
//
//        //誤差積分
//  PID->integral += PID->err;
//  
//  //積分上下限
//  if(PID->integral>50000)PID->integral=50000;
//  
//  if(PID->integral<-50000)PID->integral=-50000;
//  
//  if(Speed->ActualSpeed[2]< 50)PID->integral = 0;
//  //低速積分清零
//  
//  PID->out =  PID->Kp * PID->err + PID->Kd * ( SpeedDifferentialValue + PID->err_k[0]);// + PID->Ki * PID->integral;
//  //PID計算
//  
//       
//       
//  for(uint8 n=0; n<9 ; n++){  //循環(huán)誤差保存
//    PID->err_k[n] = PID->err_k[n+1]; //0~8位賦值
//    if( n==8 )
//      PID->err_k[n+1] = PID->err;  //本次 9位賦值
//  }
//       
//       
//  
//  PID->err_k[0] = SpeedDifferentialValue;//借用一下PID->err_k[0]咯  存入上次值 差速
//  
//  //輸出幅度限制   
//  if(PID->out>2200)PID->out=2200;//1800
//  if(PID->out<-2200)PID->out=-2200;
//
//};

//void SpeedFeedbackControl(PID_Type_Def *PID, Speed_Type_Def *Speed, Ramp_Type_Def *Ramp, Switch_Type_Def *Switch){ //速度反饋控制
//  
//
//  PID->out_k[9] = PID->out;//保存成上一次輸出值
//  
//  PID->out_k[0] = 0;
//  //誤差=實際速度-目標速度
//  PID->err = Speed->ActualSpeed[2] - Speed->PiontSpeed;
//  //誤差積分
//  PID->integral = PID->err_k[0]+PID->err_k[1]+PID->err_k[2]+PID->err_k[3]+PID->err_k[4]+
//  
//                  PID->err_k[5]+PID->err_k[6]+PID->err_k[7]+PID->err_k[8]+PID->err_k[9]+PID->err;
//       
//  PID->out = PID->Kp * PID->err ;//+ PID->Ki * PID->integral;  //速度環(huán)
//  
//  PID->out *= 0.02; //縮小速度環(huán)輸出
//  
//  if(PID->out > 1000) PID->out=   1000 ;
//  
//  if(PID->out < -1000) PID->out= -1000;
//
//   
//  for(uint8 n=0; n<9 ; n++){  //循環(huán)誤差保存
//   
//    PID->err_k[n] = PID->err_k[n+1]; //0~8位賦值   
//    if( n==8 )
//      PID->err_k[n+1] = PID->err;  //本次 9位賦值   
//  }
//  
//};

void PWMFeedbackControl(PWM_Type_Def *PWM, PID_Type_Def *PID_Balance, PID_Type_Def *PID_Speed, PID_Type_Def *PID_Path, PID_Type_Def *PID_Diff, Speed_Type_Def *Speed, Switch_Type_Def *Switch){ //PWM疊加反饋控制


   PID_Speed->out_k[0] += (PID_Speed->out - PID_Speed->out_k[9]) * 0.0625;//分段成1/16分增量
  //PID_Speed->out_k[9]是上次值  , PID_Speed->out是本次值 , PID_Speed->out_k[0] 是平滑輸出增量值
  //疊加的時候把   平滑輸出增量值 + 上次的值 得到16個周期內(nèi) 每4ms周期應(yīng)給的值

  PWM->PiontValue  = (int16)(PID_Balance->out)-(int16)(PID_Speed->out_k[0] + PID_Speed->out_k[9]) ;  //把所有環(huán)輸出相加

  PWM->Differential = (int16)(PID_Diff->out);     //差速PWM
  PWM->Differential = 0;     //差速PWM

  PWM->LiftValue = PWM->PiontValue   +  PWM->Differential;

  PWM->RightValue = PWM->PiontValue  -  PWM->Differential;      

};


//uint8 dat;
////車子失控停車
//void OutOfControlSignal(Inductor_Type_Def *InductorA, Inductor_Type_Def *InductorB){                          
//          //藍牙控制
//
//          //1的ascall碼是49 收到1停止
//                if(dat==49){
//   
//    ftm_pwm_duty(ftm2,ftm_ch0,0);
//    ftm_pwm_duty(ftm2,ftm_ch1,0);
//    ftm_pwm_duty(ftm2,ftm_ch2,0);
//    ftm_pwm_duty(ftm2,ftm_ch3,0);
//   
//    while(1)
//                        {   //2的ascall碼是50 收到2啟動
//                if(dat==50)break;
//      };
//
//    dat=0; //清除標志位
//
//                }
//               
//                //保護程序,沒有檢測到電感值就停下來
//                                        if(InductorA->LeftFinal<3&&InductorB->LeftFinal<3)  
//{
//          ftm_pwm_duty(ftm2,ftm_ch0,0);
//    ftm_pwm_duty(ftm2,ftm_ch1,0);
//    ftm_pwm_duty(ftm2,ftm_ch2,0);
//    ftm_pwm_duty(ftm2,ftm_ch3,0);
//                  
//
//}
//               
//};


/////////////////////////////////////////////////////////////////////////
  uint8 timer3ms = 0, timer4_5ms=0,timer24ms=0 ,timer64ms=0;
  float  OutData[3];                                                   //山外上位機顯示的數(shù)據(jù)
//定義結(jié)構(gòu)體
  PID_Type_Def  PID_Balance, PID_Speed, PID_Path, PID_Diff;
  RUN_Type_Def       RUN;
  Stop_Type_Def      Stop;
  Ramp_Type_Def      Ramp;
  Curve_Type_Def     Curve;
  Acc_Type_Def       Acc;
  Gyro_Type_Def      Gyro;
  Angle_Type_Def     Angle;
  PWM_Type_Def       PWM;
  Speed_Type_Def     Speed;
  Button_Type_Def    Button;
  Switch_Type_Def    Switch;
  Inductor_Type_Def  InductorA, InductorB;       
///////////////////////////////////////////////////////////////////////

int main(void)
{
  //由于本程序閉環(huán)較多  調(diào)試過程比較繁瑣  建議一開始的時候 屏蔽掉其他環(huán)
  //只調(diào)節(jié)最基礎(chǔ)的環(huán)節(jié)  平衡車主要就是對于兩個電機的控制  其中有一個函數(shù)
  //MotorControlFlow函數(shù)是直接控制電機的  這個函數(shù)需要調(diào)試好  其要求就是
  //占空比0~1000退后   1000~2000向前  通過調(diào)換驅(qū)動線  和 調(diào)換電機線  或者
  //調(diào)換程序中 ch2 3 4 5 的  23順序  45順序來  達到最終的效果  兩個電機
  //給1000以上是向前走   1000一下向后走  2000往前最快   0往后最快

  //當(dāng)電機輸出調(diào)整好了以后  再調(diào)節(jié)編碼器反饋  我們在MotorControlFlow函數(shù)里
  //直接給  PWM->LiftValue = 1200;PWM->RightValue = 1200;  讓兩個電機固定占空比
  //轉(zhuǎn)動  這時候 通過IAR在線調(diào)試觀察  編碼器測速值 是否正確  是否對應(yīng)左輪右輪
  //(左電機轉(zhuǎn)動對應(yīng)左編碼器  右電機轉(zhuǎn)動對應(yīng)右邊編碼器  不能錯!)
  //用手阻止一個電機觀察是否是那個電機的編碼器轉(zhuǎn)速下降  確保 編碼器的方向一致!

  //編碼器 和 電機調(diào)整好以后就方便了很多  接下來就是直立  前提是陀螺儀參數(shù)已經(jīng)整定好
  //我們調(diào)試直立的時候  要把其他環(huán)都關(guān)閉 方法如下  函數(shù)PWMFeedbackControl 是把所有環(huán)輸出
  //整合到電機PWM上的函數(shù) 其中  PWM->PiontValue  = (int16)(PID_Balance->out)+ (int16)(PID_Speed->out_k[0] + PID_Speed->out_k[9]) ;
  //這句話是把  三個環(huán)的輸出 疊加在一起  我們只需要保留 直立環(huán)  這樣調(diào)節(jié)直立比較順手
  //其中還有一個 差速 也要給0  對直立就無影響   

  //當(dāng)直立調(diào)節(jié)完畢后  速度環(huán)和直立的融合是比較難的  直立和速度是并環(huán) 需要精心調(diào)試,也可以
  //跳過速度環(huán)的調(diào)試  直接進入轉(zhuǎn)向環(huán)  與差速環(huán)    他們之間是串級PID的關(guān)系  

  //如果出現(xiàn)中斷  跑飛 或者  卡住在ADC死循環(huán)里  說明堆棧溢出  調(diào)整KEA128.ICF文件的  堆棧值 擴大  不超過12K即可
    get_clk();              //獲取時鐘頻率 必須執(zhí)行



    //MPU6050與單片機接線請查看IIC文件最上方注釋
    //OLED接線查看OLED文件最上方
    IIC_init();
    InitMPU6050();
    SensorStructurePointerInit( &Acc, &Gyro, &Angle, &Speed);//傳感器參數(shù)初始化
    OLED_Init();
     CarBalanceSystemInit( &Gyro ); //系統(tǒng).初始化
    //在線調(diào)試查看mpu_gyro_x mpu_gyro_y mpu_gyro_z mpu_acc_x mpu_acc_y mpu_acc_z三個變量即可
      RUN.Flag[4] = 1;//運行出界標志位

  RUN.Flag[5] = 0;//啟動電機標志位

  Stop.Flag[0] = 0;//停止線標志位延時啟動標志位

  Stop.Flag[1] = 0;//停止標志位

  Ramp.Flag[0] = 0;//接近坡道標志位

  Ramp.Flag[1] = 0;//上坡道標志位

  Curve.Flag[1] = 0;//正差速標志位

  Curve.Flag[2] = 0;//反差速標志位

  Curve.Flag[3] = 0;//差速數(shù)目
     while(1){

     //  if( timer4_5ms  ){
//     ftm_pwm_duty(ftm2,ftm_ch3,100);
//      ftm_pwm_duty(ftm2,ftm_ch2,0);
      GetAccelerationValue( &Acc );                                         //加速度原始數(shù)據(jù)采集
      GetAngleSpeedValue( &Gyro );                                          //角速度原始數(shù)據(jù)采集
            GetSpeedValue(&Speed);                                                      //獲取原始數(shù)據(jù)
//            GetInductorValue( &InductorA, &InductorB );                           //電感電壓原始數(shù)據(jù)采集
               
                        AngleSoftwareFilter(&Acc,&Gyro ,&Angle);                              //軟件角度濾波處理
//            SpeedSoftwareFilter( &Speed );                                        //速度遞歸權(quán)值濾波
//                        Get_AD_data(&InductorA, &InductorB);

            BalanceFeedbackControl( &PID_Balance, &Angle, &Gyro, &Ramp );         //平衡度反饋計算       
            //DirectionFeedbackControl( &PID_Path, &InductorA, &InductorB, &Gyro, &Speed, &Ramp );//路徑反饋計算
      //DifferentialFeedbackControl( &PID_Diff, &Speed, &Gyro);              //差速反饋計算
       
      PWMFeedbackControl( &PWM, &PID_Balance, &PID_Speed, &PID_Path, &PID_Diff, &Speed, &Switch );//PWM疊加 直立 方向 速度PWM
      MotorControlFlow( &PWM, &Ramp );                                      //電機PWM輸出控制
//                  OutOfControlSignal(&InductorA, &InductorB);                               //失控保護
//                        OutData[0]=Gyro.X_Final;                                             //山外上位機顯示的數(shù)據(jù)
//                        OutData[1]=Gyro.Z_Final;                                               //山外上位機顯示的數(shù)據(jù)
//                        OutData[2]=Angle.FinalValue;                                          //山外上位機顯示的數(shù)據(jù)
//                        vcan_sendware((uint8 *)OutData,sizeof(OutData));                      //山外調(diào)試助手       
      timer4_5ms = 0;                                                       //清除時間標志位
  //     }

if(timer64ms && timer4_5ms != 1 ){     
       
//        人機交互界面 高速運行不執(zhí)行     
//      OLED_Print_Num1(7, 6,Angle.FinalValue*100);
//                    OLED_Print_Num1(7, 4,         Speed.ActualLiftPulse[15]);
//                    OLED_Print_Num1(7, 5,         Speed.ActualRightPulse[15]);
         //    SpeedFeedbackControl( &PID_Speed, &Speed, &Ramp, &Switch ); //速度環(huán)反饋控制
       
//                         OLED_Print_Num1(7, 1,        InductorA.LeftValue[2]);
//             OLED_Print_Num1(7, 2,        InductorB.LeftValue[2]);
                   OLED_Print_Num1(7, 3,        InductorA.LeftFinal);
             OLED_Print_Num1(7, 4,        InductorB.LeftFinal);

       timer64ms = 0;
    };


  }

}

uint8 count = 0;

void PIT_CH0_IRQHandler(void)
{

  if( count<84 )
    count++;
  else count = 0;


//  if( count%2==0 ) timer3ms = 1;

  if( count%3==0 ) timer4_5ms = 1;

  if( count%16==0 ) timer24ms = 1;

  if( count%42==0 ) timer64ms=1;


  PIT_FlAG_CLR(pit0);//清除中斷標志位

}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:1 發(fā)表于 2018-11-16 15:32 | 只看該作者
補全頭文件工程包者詳細說明一下電路連接即可獲得100+黑幣
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩a级片| 91免费视频观看 | 日韩精品亚洲专区在线观看 | 国产成人区 | 久草在线 | 日韩av在线一区 | 97国产成人| 亚洲风情在线观看 | 亚洲九九| 黄色毛片在线看 | 污视频在线免费观看 | 午夜免费福利片 | 日本精品在线播放 | 午夜影院在线 | 欧美韩一区二区 | 欧美a级成人淫片免费看 | 欧美日韩精品 | 欧洲av一区 | 国产区精品| 第一福利社区1024 | 国产精品久久久久免费 | 国产不卡一| 成人欧美一区二区 | 久草视频在线播放 | 国产精品久久久久久久久久久久久久 | 日韩视频在线播放 | 亚洲第一中文字幕 | 久久午夜电影 | 欧美中文在线 | 色综久久| 天堂在线中文字幕 | 久久99精品国产 | 毛片韩国 | 日韩a在线 | 久久69精品久久久久久国产越南 | 国产日韩精品一区 | 亚洲免费在线视频 | 人人看人人搞 | 国产91色在线 | 亚洲 | 性色视频在线观看 | 一级片视频免费 |