找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于STM32F103C8T6單片機(jī)的PID平衡小車程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:734163 發(fā)表于 2021-12-28 00:36 | 只看該作者 |只看大圖 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
基于STM32F103C8T6的平衡小車
工程包含:程序、原理圖、移植文件


單片機(jī)源程序如下:
  1. #include "sys.h"

  2. //期望角度(機(jī)械中值——>不一定為0)
  3. float Mid_angle = 0;

  4. //直立環(huán)(Kp、Kd)與速度環(huán)(Kp、Ki)的PID參數(shù)
  5. float
  6. //        Vertical_Kp = 400,                 //直立環(huán)Kp
  7. //        Vertical_Kd = 1;                 //直立環(huán)Kd
  8.         Vertical_Kp = 240,                 //直立環(huán)Kp
  9.         Vertical_Kd = 0.6;                 //直立環(huán)Kd
  10. float
  11.         Velocity_Kp = 0.38,                 //速度環(huán)Kp
  12.         Velocity_Ki = 0.0019;                 //速度環(huán)Ki
  13. float
  14.         Turn_Kp = 1.1;                        //轉(zhuǎn)向環(huán)Kp

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

  17. //聲明函數(shù)
  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)                //判斷是否為低電平(外部中斷下降沿觸發(fā))
  27.         {
  28.             EXTI_ClearITPendingBit(EXTI_Line5);

  29. //1.1、采集編碼器數(shù)據(jù)
  30.             Encoder_left = -Read_Speed(2);                //讀取編碼器2數(shù)據(jù)
  31.             Encoder_right = Read_Speed(4);                //讀取編碼器4數(shù)據(jù)

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

  36. //2、帶入?yún)?shù)進(jìn)行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推導(dǎo)公式(速度環(huán)與直立環(huán))
  41.                                        
  42. //3、將PID輸出值賦給電機(jī)
  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. //速度環(huán)                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 為低通濾波器的系數(shù)
  69.    
  70. //1、計(jì)算速度偏差
  71.     Encoder_err = (encoder_left + encoder_right) - 0;                //除以2會造成舍去誤差
  72. //                Encoder_err = (Encoder_left + Encoder_right) / 2 - 0;                //0表示為期望速度

  73. //2、對速度偏差進(jìn)行低通濾波
  74.                 //(濾除高頻干擾,使得波形更加平滑,防止速度突變影響直立環(huán)的正常工作)
  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、對速度偏差進(jìn)行積分,得到位移
  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、速度環(huán)輸出
  84.     PWM_out = Velocity_Kp * Encoder_err_low_out + Velocity_Ki * Encoder_S;

  85.     return PWM_out;
  86. }


  87. //直立環(huán) PD控制
  88. /*
  89.         輸入:
  90.                                 Mid_angle                 期望角度(中值角度)
  91.                                 Real_angle        真實(shí)角度
  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. //轉(zhuǎn)向環(huán) 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. }
復(fù)制代碼


所有資料51hei附件下載:
平衡小車.7z (364 KB, 下載次數(shù): 181)

評分

參與人數(shù) 1黑幣 +10 收起 理由
admin + 10 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報(bào)

沙發(fā)
ID:881546 發(fā)表于 2022-2-6 21:44 | 只看該作者
想問下這個用的是正點(diǎn)家的mpu6050么?
回復(fù)

使用道具 舉報(bào)

板凳
ID:734163 發(fā)表于 2022-11-22 22:34 | 只看該作者
續(xù)我心弦 發(fā)表于 2022-2-6 21:44
想問下這個用的是正點(diǎn)家的mpu6050么?

我是某一個寶隨便買的一個6050模塊
回復(fù)

使用道具 舉報(bào)

地板
ID:1054191 發(fā)表于 2022-11-27 12:01 | 只看該作者
攢積分,還不能下載
回復(fù)

使用道具 舉報(bào)

5#
ID:766282 發(fā)表于 2024-3-23 14:03 來自手機(jī) | 只看該作者
這個不錯,試試看
回復(fù)

使用道具 舉報(bào)

6#
ID:1114752 發(fā)表于 2024-4-14 13:29 | 只看該作者
抱歉,我想問一下,樓主用的什么型號的板子,我用的stm32f103c8t6,沒有GPIOE,就GPIOA,B,C三個
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表