找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1915|回复: 1
打印 上一主题 下一主题
收起左侧

基于KEA128处理器的二轮直立程序

[复制链接]
跳转到指定楼层
楼主
ID:427725 发表于 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 ){ //结构体指针初始化成员

  /*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;


  //角度目标值  也就是平衡值  没有转换成角度值 但是是线性关系。
  Angle->PiontValue = zhongzhi;

  //速度目标值  没有转换成真实速度  与速度线性关系
  Speed->PiontSpeed =        PonitSpeed;


  Speed->PiontSpeedMax=600;

  Speed->PiontSpeedMin=-600;



}


void CarBalanceSystemInit(Gyro_Type_Def *Gyro){//系统初始化
  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();                          // 使用数字陀螺仪要初始化IIC
  InitMPU6050();                                                     //MPU6050的初始化函数
  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的计数引脚可查看KEA128_port_cfg.h文件内的FTM0_COUNT_PIN与FTM1_COUNT_PIN的宏定义得知
  //一个ftm同一时间只能实现一种功能,如果用于测速就不能用于输出PWM       
  ///////////////////////////////////////////////////////////////////////////////////////////////
  ftm_count_init(ftm0);   //对引脚输入的脉冲进行计数         接编码器LSB   
  gpio_init(D3,GPI,0);    //用于判断方向                    接编码器DIR
  port_pull(D3);          //IO上拉

  ftm_count_init(ftm1);   //对引脚输入的脉冲进行计数         接编码器LSB
  gpio_init(D4,GPI,0);    //用于判断方向                    接编码器DIR
  port_pull(D4);          //IO上拉
  //////////////////////////////////////////////////////////////////////////////////////////////

  //定时器中断
  pit_init(pit0,0x9000);//1.539ms

  systick_delay_ms(10);  


}


//绝对值函数   必须要取地址放入形参
void AbsoluteValue(float *Value, float *Return){

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

/*原始数据获取部分*/
void GetAccelerationValue(Acc_Type_Def *Acc){ //获取ACC原始数据
  Get_AccData();        
  Acc->Z_Value[0] = Acc->Z_Value[1];
  Acc->Z_Value[1] = Acc->Z_Value[2];
  Acc->Z_Value[2] = ACC_Z;//本句是获取当前加速度  上两句都是 上次值和上上次值
}

void GetAngleSpeedValue(Gyro_Type_Def *Gyro){  //获取Gyro原始数据
  Get_Gyro();  
  Gyro->Z_Value[0] = Gyro->Z_Value[1];
  Gyro->Z_Value[1] = Gyro->Z_Value[2];
  Gyro->Z_Value[2] = GYRO_Z ;             //本句是获取当前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原始数据

  for(uint8 n=0; n<15 ; n++){  //循环误差保存   
    //存储前14次的值  
    Speed->ActualLiftPulse[n] = Speed->ActualLiftPulse[n+1]; //0~14位赋值  
    if( n==14 ){ //当前值 15次  最新值
      Speed->ActualLiftPulse[n+1] = ftm_count_get(ftm1)*(-1); //本次 15位赋值        
      ftm_count_clean(ftm1);  //清除ftm1计数值  
    }//此处一定要修改好 根据实际的硬件  对应好左右轮子  因为编码器是对着安装的  那么
    //在车子往前走的时候  左右是相反的  所以要把其中一个负值编码器变为正的
    //两个电机存在同样的问题  都是对着安装的  
  }   
  //同上
  for(uint8 n=0; n<15 ; 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计数值  
    }

  }

  if(gpio_get(D4)) //检测 ftm1的转向   H6  E1是针对左右编码器的  要弄清楚 不要到时候改过以后
    //左边编码器的方向  去控制右边编码器的 正负号   那就完蛋了
    Speed->ActualLiftPulse[15] = -Speed->ActualLiftPulse[15];
  else               
    Speed->ActualLiftPulse[15] = Speed->ActualLiftPulse[15];            


  if(gpio_get(D3))  //检测 ftm0的转向  
    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)
{ //本函数用于数字陀螺仪 通过软件互补融合滤波解算角度  

        //加速度  角速度采集
  Acc->Z_Final = 0.9*Acc->Z_Value[2] + 0.05*Acc->Z_Value[1] + 0.05*Acc->Z_Value[0];     //权值低通滤波  
  Gyro->Z_Final = 0.9*Gyro->Z_Value[2] + 0.05*Gyro->Z_Value[1] + 0.05*Gyro->Z_Value[0];//权值低通滤波
  Gyro->X_Final = 0.92*Gyro->X_Value[2] + 0.05*Gyro->X_Value[1] + 0.03*Gyro->X_Value[0];//权值低通滤波  
  //此处参数需要根据  清华方案里的方法去调节参数  看波形法
  Angle->FinalValue = 0.98*(Angle->FinalValue -0.05*Gyro->Z_Final) + 0.02*(Acc->Z_Final);//融合滤波

}

//void SpeedSoftwareFilter(Speed_Type_Def *Speed){   //速度低通滤波
//   
//  /*警告无视*////编码器收到的数据  在文件前面有函数读取
//  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的时候 应该是不转的   

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

  //此处必须先调整好  保证 PWM值是 >1000时  是前进
  //PWM值< 1000 是后退   而且 两轮必须一致
  //能改硬件 就改驱动线  和 电机引线  例如
  //给同样都是  1200  左边电机慢速往前  右边慢速往后 这时候 调换右电机线
  //如果出现如下情况  给1200  理论上是 正转 20%占空比  但出现转速很快 说明
  //驱动线序不对   可以在这里调换 通道  或者 直接改线序

  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);   
  }  //如果发现 此处给定的是  控制 右轮转动 则调换下硬件驱动线线序  注意 是两根两根的调换  


  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);   
  }   //如果发现 此处给定的是  控制 左边轮转动 则调换下硬件驱动线线序  注意 是两根两根的调换   

}

/*被控制量处理部分*/
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
  //一般情况下  调直立时   先给一个P参数  D给0   就能立起来   如果发现不能立疯转  
  //多半是 pid方向相反    把(Angle->PiontValue-Angle->FinalValue)  里面调换下位置  即可  
};

//牛顿迭代法 开方运算
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){ //方向反馈控制
//
//  //调节offset 在中间位置的时候让左边的电感等于右边的电感
//  InductorB->LeftFinal = PID->offset*InductorB->LeftFinal;  
//  InductorA->LeftFinal = (2-PID->offset)*InductorA->LeftFinal;
//  //调整零偏
//  
//  //主要是左右两个电感
//  PID->err = 10*((newtonSqrt(InductorB->LeftFinal)-newtonSqrt(InductorA->LeftFinal ))/ (InductorB->LeftFinal+InductorA->LeftFinal));
//  //如果和值小于一个数值可认为没有偏差 车子继续沿着中间路线行驶
//  if(InductorA->AndValues<Induct_add)  PID->err = 0;
//  
// //*************注意PD的极性也就是正负*******************
//  PID->out = PID->Kp * PID->err +PID->Kd * Gyro->X_Final;
//  //转向PID输出计算 Gyro->X_Final; 是转向角速度 也是D控制
// //*************注意PD的极性也就是正负******************
//  
//  Speed->PiontDifferential = (int16)(PID->out);  //给定差速环目标值
//  //把转向环计算出来的输出值给差速目标环
//  
//       
//  for(uint8 n=0; n<9 ; n++){  //循环误差保存
//   
//    PID->err_k[n] = PID->err_k[n+1]; //0~8位赋值
//   
//    if( n==8 )
//      PID->err_k[n+1] = PID->err;  //本次 9位赋值
//   
//  }
//
//};

////差速环就是角速度和编码器的值一起控制
//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);
//  //得到差速值是编码器和转向角速度共同决定差速反馈值
//   
//  //差速目标-  差速实际值
//  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++){  //循环误差保存
//    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;  //速度环
//  
//  PID->out *= 0.02; //缩小速度环输出
//  
//  if(PID->out > 1000) PID->out=   1000 ;
//  
//  if(PID->out < -1000) PID->out= -1000;
//
//   
//  for(uint8 n=0; n<9 ; 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个周期内 每4ms周期应给的值

  PWM->PiontValue  = (int16)(PID_Balance->out)-(int16)(PID_Speed->out_k[0] + PID_Speed->out_k[9]) ;  //把所有环输出相加

  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];                                                   //山外上位机显示的数据
//定义结构体
  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)
{
  //由于本程序闭环较多  调试过程比较繁琐  建议一开始的时候 屏蔽掉其他环
  //只调节最基础的环节  平衡车主要就是对于两个电机的控制  其中有一个函数
  //MotorControlFlow函数是直接控制电机的  这个函数需要调试好  其要求就是
  //占空比0~1000退后   1000~2000向前  通过调换驱动线  和 调换电机线  或者
  //调换程序中 ch2 3 4 5 的  23顺序  45顺序来  达到最终的效果  两个电机
  //给1000以上是向前走   1000一下向后走  2000往前最快   0往后最快

  //当电机输出调整好了以后  再调节编码器反馈  我们在MotorControlFlow函数里
  //直接给  PWM->LiftValue = 1200;PWM->RightValue = 1200;  让两个电机固定占空比
  //转动  这时候 通过IAR在线调试观察  编码器测速值 是否正确  是否对应左轮右轮
  //(左电机转动对应左编码器  右电机转动对应右边编码器  不能错!)
  //用手阻止一个电机观察是否是那个电机的编码器转速下降  确保 编码器的方向一致!

  //编码器 和 电机调整好以后就方便了很多  接下来就是直立  前提是陀螺仪参数已经整定好
  //我们调试直立的时候  要把其他环都关闭 方法如下  函数PWMFeedbackControl 是把所有环输出
  //整合到电机PWM上的函数 其中  PWM->PiontValue  = (int16)(PID_Balance->out)+ (int16)(PID_Speed->out_k[0] + PID_Speed->out_k[9]) ;
  //这句话是把  三个环的输出 叠加在一起  我们只需要保留 直立环  这样调节直立比较顺手
  //其中还有一个 差速 也要给0  对直立就无影响   

  //当直立调节完毕后  速度环和直立的融合是比较难的  直立和速度是并环 需要精心调试,也可以
  //跳过速度环的调试  直接进入转向环  与差速环    他们之间是串级PID的关系  

  //如果出现中断  跑飞 或者  卡住在ADC死循环里  说明堆栈溢出  调整KEA128.ICF文件的  堆栈值 扩大  不超过12K即可
    get_clk();              //获取时钟频率 必须执行



    //MPU6050与单片机接线请查看IIC文件最上方注释
    //OLED接线查看OLED文件最上方
    IIC_init();
    InitMPU6050();
    SensorStructurePointerInit( &Acc, &Gyro, &Angle, &Speed);//传感器参数初始化
    OLED_Init();
     CarBalanceSystemInit( &Gyro ); //系统.初始化
    //在线调试查看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;//差速数目
     while(1){

     //  if( timer4_5ms  ){
//     ftm_pwm_duty(ftm2,ftm_ch3,100);
//      ftm_pwm_duty(ftm2,ftm_ch2,0);
      GetAccelerationValue( &Acc );                                         //加速度原始数据采集
      GetAngleSpeedValue( &Gyro );                                          //角速度原始数据采集
            GetSpeedValue(&Speed);                                                      //获取原始数据
//            GetInductorValue( &InductorA, &InductorB );                           //电感电压原始数据采集
               
                        AngleSoftwareFilter(&Acc,&Gyro ,&Angle);                              //软件角度滤波处理
//            SpeedSoftwareFilter( &Speed );                                        //速度递归权值滤波
//                        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;                                             //山外上位机显示的数据
//                        OutData[1]=Gyro.Z_Final;                                               //山外上位机显示的数据
//                        OutData[2]=Angle.FinalValue;                                          //山外上位机显示的数据
//                        vcan_sendware((uint8 *)OutData,sizeof(OutData));                      //山外调试助手       
      timer4_5ms = 0;                                                       //清除时间标志位
  //     }

if(timer64ms && timer4_5ms != 1 ){     
       
//        人机交互界面 高速运行不执行     
//      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 ); //速度环反馈控制
       
//                         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空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-11-16 15:32 | 只看该作者
补全头文件工程包者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表