找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于STM32F103C8T6单片机的PID平衡小车程序

  [复制链接]
跳转到指定楼层
楼主
基于STM32F103C8T6的平衡小车
工程包含:程序、原理图、移植文件


单片机源程序如下:
  1. #include "sys.h"

  2. //期望角度(机械中值——>不一定为0)
  3. float Mid_angle = 0;

  4. //直立环(Kp、Kd)与速度环(Kp、Ki)的PID参数
  5. float
  6. //        Vertical_Kp = 400,                 //直立环Kp
  7. //        Vertical_Kd = 1;                 //直立环Kd
  8.         Vertical_Kp = 240,                 //直立环Kp
  9.         Vertical_Kd = 0.6;                 //直立环Kd
  10. float
  11.         Velocity_Kp = 0.38,                 //速度环Kp
  12.         Velocity_Ki = 0.0019;                 //速度环Ki
  13. float
  14.         Turn_Kp = 1.1;                        //转向环Kp

  15. //PID控制输出
  16. int Velocity_out, Vertical_out, Turn_out;

  17. //声明函数
  18. int Velocity_PI(int Encoder_left, int Encoder_right);
  19. int Vertical_PD(float Mid_angle, float Real_angle, float gyro_y);
  20. int Turn_P(int gyro_z);

  21. void EXTI9_5_IRQHandler()
  22. {
  23.     if(EXTI_GetITStatus(EXTI_Line5) != 0 )
  24.     {
  25.                                 int PWM_out;
  26.         if(PBin(5) == 0)                //判断是否为低电平(外部中断下降沿触发)
  27.         {
  28.             EXTI_ClearITPendingBit(EXTI_Line5);

  29. //1.1、采集编码器数据
  30.             Encoder_left = -Read_Speed(2);                //读取编码器2数据
  31.             Encoder_right = Read_Speed(4);                //读取编码器4数据

  32. //1.2、采集MPU6050数据
  33.             mpu_dmp_get_data(&Pitch, &Roll, &Yaw);
  34.             MPU_Get_Gyroscope(&gyrox, &gyroy, &gyroz);
  35.             MPU_Get_Accelerometer(&aacx, &aacy, &aacz);

  36. //2、带入参数进行PID控制
  37.                                                 Vertical_out = Vertical_PD(Mid_angle, Pitch, gyroy);                                //前后移动由Pitch控制
  38.             Velocity_out = Velocity_PI(Encoder_left, Encoder_right);
  39.             Turn_out = Turn_P(gyroz);
  40.                                                 PWM_out = Vertical_out - Vertical_Kp * Velocity_out;                //串级PID推导公式(速度环与直立环)
  41.                                        
  42. //3、将PID输出值赋给电机
  43.                                                 Motor_1 = PWM_out - Turn_out;
  44.                                                 Motor_2 = PWM_out + Turn_out;
  45.                                                 Limit(&Motor_1, &Motor_2);
  46.                                                 Load(Motor_1, Motor_2);
  47.         }
  48.     }
  49. }


  50. //速度环                PI控制
  51. /*
  52.         输入:
  53.                                 Encoder_left                 左编码器速度
  54.                                 Encoder_right                右编码器速度
  55.         输出:
  56.                                 PWM值
  57. */
  58. int Velocity_PI(int encoder_left, int encoder_right)
  59. {
  60.     static int
  61.                         PWM_out,
  62.                         Encoder_err,         //Encoder_err 为编码器速度偏差
  63.                         Encoder_S;                //Encoder_S 为编码器速度的积分值
  64.     static int
  65.                         Encoder_err_low_out,                                 //Encoder_err_low_out 为低通滤波器输出
  66.                         Encoder_err_low_out_last;                //Encoder_err_low_out_last 为上一次低通滤波器输出
  67.                 float        
  68.                         a = 0.7;                        //a 为低通滤波器的系数
  69.    
  70. //1、计算速度偏差
  71.     Encoder_err = (encoder_left + encoder_right) - 0;                //除以2会造成舍去误差
  72. //                Encoder_err = (Encoder_left + Encoder_right) / 2 - 0;                //0表示为期望速度

  73. //2、对速度偏差进行低通滤波
  74.                 //(滤除高频干扰,使得波形更加平滑,防止速度突变影响直立环的正常工作)
  75.     Encoder_err_low_out = (1 - a) * Encoder_err + a * Encoder_err_low_out_last;
  76.     Encoder_err_low_out_last = Encoder_err_low_out;

  77. //3、对速度偏差进行积分,得到位移
  78.     Encoder_S += Encoder_err_low_out;
  79.         
  80. //4、积分限幅
  81.                 Encoder_S = Encoder_S > 10000 ? 10000 : (Encoder_S < (-10000) ? (-10000) : Encoder_S);
  82.                
  83. //5、速度环输出
  84.     PWM_out = Velocity_Kp * Encoder_err_low_out + Velocity_Ki * Encoder_S;

  85.     return PWM_out;
  86. }


  87. //直立环 PD控制
  88. /*
  89.         输入:
  90.                                 Mid_angle                 期望角度(中值角度)
  91.                                 Real_angle        真实角度
  92.                                 gyro_y                        真是角速度
  93.         输出:
  94.                                 PWM值
  95. */
  96. int Vertical_PD(float Mid_angle, float Real_angle, float gyro_y)
  97. {
  98.     int PWM_out;

  99.     PWM_out = Vertical_Kp * (Real_angle - Mid_angle) + Vertical_Kd * (gyro_y - 0);

  100.     return PWM_out;
  101. }

  102. //转向环 P控制
  103. int Turn_P(int gyro_z)
  104. {
  105.     int PWM_out;

  106.     PWM_out = Turn_Kp * gyro_z;

  107.     return PWM_out;
  108. }
复制代码


所有资料51hei附件下载:
平衡小车.7z (364 KB, 下载次数: 168)

评分

参与人数 1黑币 +10 收起 理由
admin + 10 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:881546 发表于 2022-2-6 21:44 | 只看该作者
想问下这个用的是正点家的mpu6050么?
回复

使用道具 举报

板凳
ID:734163 发表于 2022-11-22 22:34 | 只看该作者
续我心弦 发表于 2022-2-6 21:44
想问下这个用的是正点家的mpu6050么?

我是某一个宝随便买的一个6050模块
回复

使用道具 举报

地板
ID:1054191 发表于 2022-11-27 12:01 | 只看该作者
攒积分,还不能下载
回复

使用道具 举报

5#
ID:766282 发表于 2024-3-23 14:03 来自手机 | 只看该作者
这个不错,试试看
回复

使用道具 举报

6#
ID:1114752 发表于 2024-4-14 13:29 | 只看该作者
抱歉,我想问一下,楼主用的什么型号的板子,我用的stm32f103c8t6,没有GPIOE,就GPIOA,B,C三个
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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