找回密码
 立即注册

QQ登录

只需一步,快速开始

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

KEA128电磁直立例程

[复制链接]
跳转到指定楼层
楼主
ID:288295 发表于 2018-5-17 16:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是我上周做的智能车电磁直立例程
单片机源程序如下:
  1. /*!
  2. *
  3. * @file       main.c
  4. * @brief      山外KEA 平台主程序
  5. * @author     山外科技
  6. * @version    v6.0
  7. * @date       2017-12-10
  8. */

  9. #include "common.h"
  10. #include "include.h"

  11. /*!   
  12. *  @brief      main函数   
  13. *  @since      v6.0   
  14. *  @note  **********直立3队***********************
  15.            **********2018年3月4日***********************
  16.            **********电磁直立程序************************  
  17. */

  18. void main(void)
  19. {
  20.     summary_init();
  21.     while(1)
  22.     {
  23. //      electro_data_handle();
  24.       key_scan();
  25.       menu_show();
  26.     }
  27. }
复制代码
  1. #include "electro.h"

  2. /******************编程思想*****************************************************
  3. *******************起跑前寻找最大值和最小值**************************************
  4. *******************电感采集(存入Collect_ADi[9])*********************************
  5. *******************中值滤波(存入AD_filter[2])***********************************
  6. *******************归一化值(存入ADf_returnone[2]和AD_returnone[2])**************
  7. *******************差除和计算***************************************************
  8. *******************各电感配合使用,求偏差,转向PWM*******************************
  9. *******************丢线处理,弯道重叠处理(?????),圆环处理******************************/


  10. uint16 Collect_AD1[5],Collect_AD2[5];//首次采集存入数组

  11. //uint16 Collect_AD[2];
  12. uint16 left_electro,right_electro;
  13. uint16 left_one,right_one;

  14. //归一化参数
  15. uint16 AD_filter[2]={0,0};//电感滤波值
  16. //uint8 AD_returnone[2]={0,0};//归一化值
  17. //float ADf_returnone[2]={0};//归一化值
  18. //uint16 min_v[2]={3000,3000};//起跑前2电感采集最小值
  19. //uint16 max_v[2]={726,726};//起跑前2电感采集最大值

  20. // uint16 elcmin,elcmax;

  21. //uint16 frist_Collect_AD_min[2]={0};
  22. // uint16 frist_Collect_AD_max[2]={0};

  23. uint8 left_flag,right_flag;


  24. float difference_division_sum_data=0;
  25. float last_difference_division_sum_data=0;


  26. void Collect_electro_filter()//电感采集  中值滤波
  27. {
  28.     uint8 i,filter_i,filter_j;
  29.     uint16 temp;
  30.    
  31.     for(i=0;i<5;i++) //L1
  32.     {  
  33.      Collect_AD1[i] =adc_once(ADC0_SE0,ADC_12bit);//A0;
  34.     }
  35.     for(i=0;i<5;i++) //L2
  36.     {  
  37.      Collect_AD2[i] =adc_once(ADC0_SE1,ADC_12bit);//A1;
  38.     }
  39.    
  40.     for(filter_i=0;filter_i<5;filter_i++) //中值为AD[3]
  41.     {
  42.       for(filter_j=0;filter_j<5-filter_i;filter_j++)
  43.       {
  44.         if(Collect_AD1[filter_j]>Collect_AD1[filter_j+1])
  45.            {
  46.               temp=Collect_AD1[filter_j];
  47.               Collect_AD1[filter_j]=Collect_AD1[filter_j+1];
  48.               Collect_AD1[filter_j+1]=temp;
  49.            }
  50.       }
  51.        for(filter_j=0;filter_j<5-filter_i;filter_j++)
  52.       {
  53.         if(Collect_AD2[filter_j]>Collect_AD2[filter_j+1])
  54.            {
  55.                temp=Collect_AD2[filter_j];
  56.                Collect_AD2[filter_j]=Collect_AD2[filter_j+1];
  57.                Collect_AD2[filter_j+1]=temp;
  58.            }
  59.        }            
  60.     }
  61. AD_filter[0]=Collect_AD1[2];
  62. AD_filter[1]=Collect_AD2[2];
  63. left_electro=AD_filter[0];
  64. right_electro=AD_filter[1];
  65. }

  66. /*
  67. void find_L_min()//起跑前找到2电感最小值
  68. {
  69.   uint8 i;
  70.   
  71.   for(i=0;i<10;i++)
  72.   {
  73.     frist_Collect_AD_min[0]=adc_once(ADC0_SE0, ADC_12bit);
  74.     if(frist_Collect_AD_min[0]<min_v[0]) min_v[0]=frist_Collect_AD_min[0];
  75.   }
  76.   
  77.     for(i=0;i<10;i++)
  78.   {
  79.     frist_Collect_AD_min[1]=adc_once(ADC0_SE1, ADC_12bit);
  80.     if(frist_Collect_AD_min[1]<min_v[1]) min_v[1]=frist_Collect_AD_min[1];
  81.   }
  82.   
  83. }
  84. void find_L_max()//起跑前找到2电感最大值
  85. {
  86.   uint32 i;
  87.   DELAY_MS(25);
  88.     for(i=0;i<200000;i++)
  89.   {
  90.     frist_Collect_AD_max[0]=adc_once(ADC0_SE0, ADC_12bit);
  91.     if(frist_Collect_AD_max[0]>max_v[0])max_v[0]=frist_Collect_AD_max[0];
  92.     frist_Collect_AD_max[1]=adc_once(ADC0_SE1, ADC_12bit);
  93.     if(frist_Collect_AD_max[1]>max_v[1])max_v[1]=frist_Collect_AD_max[1];
  94.     //DELAY_MS(3);
  95.   }
  96. //    for(i=0;i<600;i++)
  97. //  {
  98. //    frist_Collect_AD_max[1]=adc_once(ADC0_SE1, ADC_12bit);
  99. //    if(frist_Collect_AD_max[1]>max_v[1])max_v[1]=frist_Collect_AD_max[1];
  100. //    DELAY_MS(3);
  101. //  }
  102.   elcmin=max_v[0];
  103.   elcmax=max_v[1];
  104. }

  105. void sensor_to_one()//电感滤波值归一化处理
  106. {
  107.   uint8 i;

  108.   float sensor_to_one[2];
  109.   for(i=0;i<2;i++)
  110.   {
  111.    sensor_to_one[i]=(float)(AD_filter[i]-min_v[i])/(float)(max_v[i]-min_v[i]);
  112.    if(sensor_to_one[i]<=0.0)
  113.      sensor_to_one[i]=0.001;
  114.    if(sensor_to_one[i]>1.0)
  115.      sensor_to_one[i]=1.0;
  116.    
  117.    ADf_returnone[i]=(100*sensor_to_one[i]);// AD[i]归一后的值。0~100之间
  118.    AD_returnone[i]=(uint8)ADf_returnone[i];
  119.    left_flag=AD_returnone[0];
  120.    right_flag=AD_returnone[1];
  121.    left_one=AD_returnone[0];
  122.    right_one=AD_returnone[1];
  123.   }
  124. }
  125. */

  126. void difference_division_sum()//差除和计算
  127. {
  128.    
  129.     difference_division_sum_data=(float)((AD_filter[0]-AD_filter[1])*(AD_filter[0]-AD_filter[1]))/(float)((AD_filter[0]+AD_filter[1])*(AD_filter[0]+AD_filter[1]));
  130.    
  131.     if(AD_filter[0]>AD_filter[1])
  132.     {
  133.       difference_division_sum_data=-difference_division_sum_data;
  134.     }
  135.     if(AD_filter[0]<AD_filter[1])
  136.     {
  137.       difference_division_sum_data=difference_division_sum_data;
  138.     }

  139.     if(difference_division_sum_data>1) difference_division_sum_data=1;
  140.     if(difference_division_sum_data<-1) difference_division_sum_data=-1;

  141.     if(AD_filter[0]<260)
  142.     difference_division_sum_data=0.34;
  143.    
  144.     if(AD_filter[1]<260)
  145.     difference_division_sum_data=-0.34;

  146. //    last_difference_division_sum_data=difference_division_sum_data;
  147. }

  148. void electro_data_handle()
  149. {
  150.   Collect_electro_filter();
  151. //  sensor_to_one();
  152.   difference_division_sum();
  153. }
复制代码
  1. #include "control.h"

  2. /*************************************************
  3. ****************参数定义*****************
  4. ***********************************************/
  5. float Angle_Middle=9.6;
  6. //float Angle_Middle=10;

  7. float b_kp=1500,b_kd=2.125;

  8. float v_kp=0.006,v_ki=0.000025;
  9. //float v_kp=0,v_ki=0;

  10.   //float t_kp=600.0,t_kd=1.0,t_kg=0.06;
  11. float t_kp=1150,t_kd=7,t_kg=0;

  12. float angle_deviation=0;

  13. int16 Set_velocity=-650;//设定速度必须为负值

  14. int16 Balance_PWM=0,Velocity_PWM=0,Turn_PWM=0;

  15. int16 encoder_right=0,encoder_left=0;

  16. int16 encoder_sum=0;

  17. float velocity_deviation,velocity_proportion,velocity_integral;



  18. /*****************PWM输出********************/
  19. void PWM_out(int16 x11,int16 x12,int16 x21,int16 x22)
  20. {
  21.     if(x11<1)x11=0;if(x11>9999)x11=9999;
  22.     if(x12<1)x12=0;if(x12>9999)x12=9999;
  23.     if(x21<1)x21=0;if(x21>9999)x21=9999;
  24.     if(x22<1)x22=0;if(x22>9999)x22=9999;
  25.     if(x11==0||x12==0)
  26.     {
  27.       if(x21==0||x22==0)
  28.       {
  29.          ftm_pwm_init(FTM2, FTM_CH0,10000,x11);
  30.          ftm_pwm_init(FTM2, FTM_CH1,10000,x12);
  31.          ftm_pwm_init(FTM2, FTM_CH2,10000,x22);
  32.          ftm_pwm_init(FTM2, FTM_CH3,10000,x21);        
  33.       }
  34.     }
  35. }
  36. /****************编码器采集*******************/

  37. void encoder_collect()
  38. {

  39.     encoder_left= ftm_pulse_get(FTM0);
  40.     if(PTB2_IN == 1)
  41.     {
  42.         encoder_left=-encoder_left;
  43.     }
  44.     else
  45.     {
  46.         encoder_left=encoder_left;
  47.     }
  48.     ftm_pulse_clean(FTM0);       //清空计数。
  49.     encoder_right= ftm_pulse_get(FTM1);
  50.     if(PTB3_IN == 1)
  51.     {
  52.         encoder_right=encoder_right;
  53.     }
  54.     else
  55.     {
  56.         encoder_right=-encoder_right;
  57.     }
  58.     ftm_pulse_clean(FTM1);       //清空计数。
  59.    
  60.     if(encoder_left>9999) encoder_left=9999;
  61.     if(encoder_left<-9999) encoder_left=-9999;
  62.    
  63.     if(encoder_right>9999) encoder_right=9999;
  64.     if(encoder_right<-9999) encoder_right=-9999;   
  65.    
  66.   if(encoder_left>5000&&encoder_right<5000)encoder_left =encoder_right;
  67.   if(encoder_left<5000&&encoder_right>5000)encoder_right=encoder_left;
  68.    
  69.     encoder_sum=encoder_left+encoder_right;     
  70. }

  71. /******************速度控制*************************/

  72. float velocity_control(int16 encoder_sum1)//速度闭环控制
  73. {
  74.   int16 encoder_deviation;

  75.   static float last_integral=0;
  76.   
  77.   encoder_deviation=Set_velocity+encoder_sum1;
  78.   velocity_proportion=encoder_deviation*v_kp;//比例   
  79.   
  80.   velocity_integral=encoder_deviation*v_ki;//积分
  81.   velocity_integral+=last_integral;
  82.   
  83.   if(velocity_integral<-1.0)velocity_integral=-1.0;//积分限幅
  84.   if(velocity_integral> 1.0)velocity_integral= 1.0;//积分限幅
  85.   last_integral=velocity_integral;
  86.   
  87.   velocity_deviation=velocity_proportion+velocity_integral;
  88. //  velocity_deviation=velocity_proportion;
  89.   if(velocity_deviation>10)velocity_deviation=10;
  90.   if(velocity_deviation<-10)velocity_deviation=-10;
  91.   return velocity_deviation;

  92. }


  93. /******************************************/

  94. int16 velocity_out(uint8 count,float velocity,float last_velocity)
  95. {
  96.   int16 velocity_pwm;
  97.   float velocity_data;
  98.   
  99.   velocity_data=(velocity-last_velocity)/20.0*count+last_velocity;
  100.   
  101.   velocity_pwm=(int16)(velocity_data);
  102.   
  103.   return velocity_pwm;
  104. }
  105. /**********************************************/
  106. int16 turn_out(uint8 count,float new_turn,float last_turn)
  107. {
  108.   int16 turn_pwm;
  109.   float turn_data;
  110.   
  111.   turn_data=(new_turn-last_turn)/20.0*count+last_turn;
  112.   
  113.   turn_pwm=(int16)(turn_data);
  114.   
  115.   return turn_pwm;
  116. }

  117. /***********平衡速度串级控制*******************/
  118. int16 balance_control(float Angle,float Gyro_Y)
  119. {
  120.   int16 balance;

  121.   static uint8 v_count=1;
  122.   static float last_velocity=0.0;
  123.   static float this_velocity=0.0;
  124.    
  125.   angle_deviation=Angle-Angle_Middle;
  126.   
  127.   v_count++;
  128.   if(v_count==21)
  129.   {
  130.      v_count=1;
  131.      encoder_collect();
  132.      last_velocity=this_velocity;
  133.      this_velocity=velocity_control(encoder_sum);
  134.   }
  135.   Velocity_PWM=velocity_out(v_count,this_velocity,last_velocity);
  136.   balance=(int16)(b_kp*(angle_deviation+Velocity_PWM)+b_kd*Gyro_Y);
  137.   
  138.   //balance=(int16)(b_kp*angle_deviation+b_kd*Gyro_Y);
  139.   if(balance> 9999)balance= 9999;
  140.   if(balance<-9999)balance=-9999;
  141.   
  142.   return balance;
  143. }

  144. /**************转向控制*********************/
  145. int16 turn_control(float turn_deviation,float gyro_turn)
  146. {
  147.   int16 turn;
  148.   float turn_proportion,turn_differential;
  149.   static float last_deviation;
  150.   
  151.   turn_proportion=t_kp*turn_deviation;
  152.   
  153.   turn_differential=t_kd*(turn_deviation-last_deviation);
  154.   last_deviation=turn_deviation;
  155.   
  156.   turn=(int16)(turn_proportion+turn_differential+t_kg*gyro_turn);
  157.    
  158.   return turn;
  159. }

  160. /************输出*****************/

  161. void balance_out(int16 balance_pwm,int16 turn_pwm)    //合成
  162. {
  163.   if(balance_pwm>=0)
  164.   {
  165.     PWM_out((int16)(balance_pwm+turn_pwm),0,(int16)(balance_pwm-turn_pwm),0);
  166.   }
  167.   else if(balance_pwm<0)
  168.   {
  169.     balance_pwm=-balance_pwm;
  170.     PWM_out(0,(int16)(balance_pwm+turn_pwm),0,(int16)(balance_pwm-turn_pwm));
  171.   }
  172. }

  173. /*
  174. void balance_out(int16 balance_pwm,int16 turn_pwm)    //合成
  175. {
  176.   if(balance_pwm>=0)
  177.   {
  178.     if(turn_pwm>=0)
  179.     PWM_out((int16)(balance_pwm-turn_pwm/2),0,(int16)(balance_pwm-turn_pwm),0);
  180.     if(turn_pwm<0)
  181.     PWM_out((int16)(balance_pwm+turn_pwm),0,(int16)(balance_pwm+turn_pwm/2),0);      
  182.   }
  183.   else if(balance_pwm<0)
  184.   {
  185.     balance_pwm=-balance_pwm;
  186.     if(turn_pwm>=0)
  187.     PWM_out(0,(int16)(balance_pwm-turn_pwm/2),0,(int16)(balance_pwm-turn_pwm));
  188.     if(turn_pwm<0)
  189.     PWM_out(0,(int16)(balance_pwm+turn_pwm),0,(int16)(balance_pwm+turn_pwm/2));
  190.   }
  191. }
  192. */

  193. void summary_control()
  194. {
  195.     Balance_PWM=balance_control(Angle_Balance,Gyro_Balance);
  196.     Turn_PWM   =turn_control(difference_division_sum_data,Gyro_Turn);
  197.     balance_out(Balance_PWM,Turn_PWM);
  198. //    led_turn(LED1);                     //LED1翻转
  199. }
复制代码

所有资料51hei提供下载:
电磁直立(KEA).rar (188.69 KB, 下载次数: 69)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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