找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STM32F411+MPU6050控制平衡小车,在获取姿态时,如果不加IF判断,程序就会卡死在DMP...

[复制链接]
跳转到指定楼层
楼主
本帖最后由 hgfhgfddd 于 2021-6-4 19:43 编辑

本人使用的是HAL库来编程,在移植MPU6050的DMP库时,遇到了一个问题,希望有大佬指导一下。

在获取姿态时,如果不加IF判断,程序就会卡死在DMP库中的某个地方。
注意,不要打开文件中的STM32CUBEMX工程,那个是错的,不能用!!!
程序部分代码如下
  1. #include "control.h"
  2. #include "inv_mpu.h"
  3. #include "inv_mpu_dmp_motion_driver.h"
  4. #include "mpu6050.h"
  5. #include "main.h"
  6. #include "stdio.h"
  7. #include "motor.h"
  8. #include "protocol.h"

  9. #define PID_ASSISTANT_EN    1   // 1:使用PID调试助手显示波形,0:使用串口直接打印数据
  10. #define N 5
  11. #define turnzhi 1.5
  12.         
  13.         //float Turn_Kp = 3;
  14.         
  15.         float
  16.                 Turn_Kd=turnzhi,//转向环KP、KD
  17.                 Turn_Kp=30;

  18.         #define SPEED_Y 600 //俯仰(前后)最大设定速度
  19.         #define SPEED_Z 80//偏航(左右)最大设定速度
  20.         
  21.         
  22.         int Vertical_out,Velocity_out = 0,Turn_out = 0;//直立环&速度环&转向环 的输出变量
  23.         
  24.         int i,j;
  25.                 int b = 5;
  26.         short Accel[3];
  27.         short Gyro[3];
  28.         float Temp;
  29.         
  30.         
  31.         char value_buff[N];
  32.         char k = 0;
  33.         
  34.         
  35. //        short filter()
  36. //        {
  37. //                int count;
  38. //                int sum = 0;
  39. //                value_buff[k++] = gyroz;
  40. //               
  41. //                if(k == N)
  42. //                        k = 0;
  43. //                for(count = 0;count < N;count ++)
  44. //                        sum += value_buff[count];
  45. //                return (short)(sum/N);
  46. //        }
  47. //        
  48.         
  49.         int Vertical(float Med,float Angle,float gyro_Y);//函数声明
  50.         int Velocity(float Target_Speed,int encoder_left,int encoder_right);
  51.         int Turn(int gyro_Z,int RC);
  52.         

  53.         void angle_even(float pitch);

  54. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  55. {
  56.         unsigned long a = 20;
  57.         int PWM_out;
  58.         if(GPIO_Pin == GPIO_PIN_5)
  59.         {
  60.                 if(mpu_dmp_get_data(&pitch,&roll,&yaw) == 0)
  61.                 {                                       
  62.                         mpu_get_gyro_reg(Accel,&a);
  63.                         MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);
  64.                         //Temp = MPU_Get_Temperature();
  65.                 }
  66.                 if(j >= 10)
  67.                 {
  68.                                 j = 0;
  69.                                 Encoder_Left = Read_Speed(3);
  70.                                 Encoder_Right = - Read_Speed(4);                        
  71.                 }
  72.                 j++;
  73.                
  74.         /*前后*/
  75.                 if((Fore==0)&&(Back==0))Target_Speed=0;//未接受到前进后退指令-->速度清零,稳在原地
  76.                 if(Fore==1)Target_Speed-=5;//前进1标志位拉高-->需要前进
  77.                 if(Back==1)Target_Speed+=5;//
  78.                 Target_Speed=Target_Speed>SPEED_Y?SPEED_Y:(Target_Speed<-SPEED_Y?(-SPEED_Y):Target_Speed);//限幅
  79.                
  80.                 /*左右*/
  81.                 if((Left==0)&&(Right==0))Turn_Speed=0;
  82.                 if(Left==1)Turn_Speed+=1;        //左转
  83.                 if(Right==1)Turn_Speed-=1;        //右转
  84.                 Turn_Speed=Turn_Speed>SPEED_Z?SPEED_Z:(Turn_Speed<-SPEED_Z?(-SPEED_Z):Turn_Speed);//限幅( (20*100) * 100   )
  85.                
  86.                 /*转向约束*/
  87.                 if((Left==0)&&(Right==0))Turn_Kd=turnzhi;//若无左右转向指令,则开启转向约束
  88.                 else if((Left==1)||(Right==1))Turn_Kd=0;//若左右转向指令接收到,则去掉转向约束
  89.                
  90.                 Vertical_out=Vertical(Med_Angle,pitch,gyroy);                                //直立环
  91.                 Velocity_out=Velocity(Target_Speed,Encoder_Left,Encoder_Right);        //速度环
  92.                 Turn_out=Turn(gyroz,Turn_Speed);
  93.                 //转向环
  94.                 PWM_out=Vertical_out-Vertical_Kp*Velocity_out;//最终输出
  95.                
  96.                 MOTO1=PWM_out-Turn_out;//左电机
  97.                 MOTO2=PWM_out+Turn_out;//右电机
  98.                 Limit(&MOTO1,&MOTO2);         //PWM限幅
  99.                 angle_even(pitch);               
  100.                 Load(MOTO1,MOTO2);                 //加载到电机上。
  101.                
  102.                
  103.                 i ++;
  104.                 if(i >= 30)
  105.                 {
  106.                
  107.                                 i = 0;
  108.                                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
  109. //                        #if defined(PID_ASSISTANT_EN)
  110. //                                set_computer_value(SEND_PERIOD_CMD, CURVES_CH1, &b, 1);     // 给通道 1 目标值值
  111. //                        #endif
  112. //                        
  113. //                                a= (int)pitch;
  114. //                        #if defined(PID_ASSISTANT_EN)
  115. //                                set_computer_value(SEND_FACT_CMD, CURVES_CH1, &a, 1);     // 给通道 1 发送实际值
  116. //                        #endif
  117.                         printf("Pitch:%8.2f",pitch);
  118.                         printf(" YAW:%8.2f",yaw);
  119.                         printf(" Gyro:%8d Z:%8d",gyroy,gyroz);
  120.                         printf("     EL:%d, ER:%d",Encoder_Left,Encoder_Right);
  121.                         printf("     PWM:%d\r\n",MOTO1);        
  122.                         //printf("Temp: %2.2f\r\n",Temp);                        
  123.                 }

  124.                
  125.         }
  126. }


  127. /*********************
  128. 直立环PD控制器:Kp*Ek+Kd*Ek_D

  129. 入口:期望角度、真实角度、真实角速度
  130. 出口:直立环输出
  131. *********************/
  132. //int Vertical(float Med,float Angle,float gyro1_Y)
  133. //{
  134. //        int PWM_out;
  135. //        
  136. //        PWM_out=Vertical_Kp*(Angle-Med)+Vertical_Kd*(gyro1_Y-0);
  137. //        return PWM_out;
  138. //}

  139. void angle_even(float pitch)
  140. {
  141.         if(pitch > (40) || pitch < (-40) )
  142.         {
  143.                 MOTO1 = 0;
  144.                 MOTO2 = 0;
  145.                 PB12(H);PB13(H);
  146.                 PB14(H);PB15(H);
  147.         }
  148.                
  149. }

  150. //int PI_Balance(int encoder_left,int encoder_right)
  151. //{
  152. //          static float Velocity,Encoder_Least,Encoder,Movement;
  153. //          static float Encoder_Integral;
  154. //        
  155. //                Movement = 0;
  156. //        
  157. //           //=============速度PI控制器=======================//        
  158. //                Encoder_Least =(Encoder_Left+Encoder_Right)-0;                    //===获取最新速度偏差==测量速度(左右编码器之和)-目标速度(此处为零)
  159. //                Encoder *= 0.8;                                                                //===一阶低通滤波器      
  160. //                Encoder += Encoder_Least*0.2;                                            //===一阶低通滤波器   
  161. //                Encoder_Integral +=Encoder;                                       //===积分出位移 积分时间:10ms
  162. //                Encoder_Integral=Encoder_Integral-Movement;                       //===接收遥控器数据,控制前进后退
  163. //                if(Encoder_Integral>10000)          Encoder_Integral=10000;             //===积分限幅
  164. //                if(Encoder_Integral<-10000)                Encoder_Integral=-10000;            //===积分限幅        
  165. //                Velocity=Encoder*velocity_KP+Encoder_Integral*velocity_KI;        //===速度控制        
  166. //          if(pitch < -40 || pitch > 40)                         Encoder_Integral=0;                                                     //===电机关闭后清除积分
  167. //          return Velocity;

  168. //}
  169. /*********************
  170. 直立环PD控制器:Kp*Ek+Kd*Ek_D

  171. Med:机械中值
  172. Angle:真实角度
  173. gyro_Y:真实角度的加速度
  174. *********************/
  175. int Vertical(float Med,float Angle,float gyro_Y)
  176. {
  177.         int PWM_out;
  178.         PWM_out=Vertical_Kp*(Angle - Med)+Vertical_Kd*(gyro_Y-0);//【1】
  179.         return PWM_out;
  180. }



  181. /*********************
  182. 速度环PI:Kp*Ek+Ki*Ek_S
  183. *********************/
  184. int Velocity(float Target_Speed,int encoder_left,int encoder_right)
  185. {
  186.         static int PWM_out,Encoder_Err,Encoder_S,EnC_Err_Lowout,EnC_Err_Lowout_last;//【2】
  187.         float a=0.7;//【3】
  188.         
  189.         //1.计算速度偏差
  190.         Encoder_Err=(encoder_left+encoder_right)-Target_Speed;//舍去误差
  191.         //2.对速度偏差进行低通滤波
  192.         //low_out=(1-a)*Ek+a*low_out_last;
  193.         EnC_Err_Lowout=(1-a)*Encoder_Err+a*EnC_Err_Lowout_last;//使得波形更加平滑,滤除高频干扰,防止速度突变。
  194.         EnC_Err_Lowout_last=EnC_Err_Lowout;//防止速度过大的影响直立环的正常工作。
  195.         //3.对速度偏差积分,积分出位移
  196.         Encoder_S+=EnC_Err_Lowout;//【4】
  197.         //4.积分限幅
  198.         Encoder_S=Encoder_S>10000?10000:(Encoder_S<(-10000)?(-10000):Encoder_S);
  199.         //5.速度环控制输出计算
  200.         PWM_out=Velocity_Kp*EnC_Err_Lowout+Velocity_Ki*Encoder_S;//【5】
  201.         
  202.         if(pitch < (-40) || pitch > (40)) Encoder_S = 0;
  203.         return PWM_out;
  204. }



  205. ///*********************
  206. //转向环:系数*Z轴角速度
  207. //*********************/
  208. //int Turn(int gyro_Z)
  209. //{
  210. //        int PWM_out;
  211. //        
  212. //        PWM_out=Turn_Kp*gyro_Z;
  213. //        return PWM_out;
  214. //}

  215. /*********************
  216. 转向环:系数*Z轴角速度+系数*遥控数据
  217. *********************/
  218. int Turn(int gyro_Z,int RC)
  219. {
  220.         int PWM_out;
  221.         //这不是一个严格的PD控制器,Kd针对的是转向的约束,但Kp针对的是遥控的转向。
  222.         PWM_out=Turn_Kd*gyro_Z + Turn_Kp*RC;
  223.         return PWM_out;
  224. }


复制代码

硬件部分见附件 开发环境.docx (4.38 MB, 下载次数: 18)



未命名.gif (6.29 MB, 下载次数: 105)

未命名.gif

F411MPU6050.7z

7.73 MB, 下载次数: 36

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

使用道具 举报

沙发
ID:855730 发表于 2021-8-19 20:13 | 只看该作者
我也是调用MPU_Get_Gyroscope死机
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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