久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5222|回復: 6
打印 上一主題 下一主題
收起左側

51單片機平衡小車6軸MPU6050+互補濾波+PWM電機參考程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:479765 發表于 2019-6-1 11:55 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
51平衡小車 mpu650 參考程序

單片機源程序如下:
  1. /***********************************************************************
  2. // 兩輪自平衡車最終版控制程序(6軸MPU6050+互補濾波+PWM電機)
  3. // 單片機STC12C5A60S2
  4. // 晶振:20M
  5. ***********************************************************************/

  6. #include <REG52.H>        
  7. #include <math.h>     
  8. #include <stdio.h>   
  9. #include <INTRINS.H>

  10. typedef unsigned char  uchar;
  11. typedef unsigned short ushort;
  12. typedef unsigned int   uint;

  13. //******功能模塊頭文件*******

  14. #include "DELAY.H"                    //延時頭文件
  15. #include "STC_ISP.H"            //程序燒錄頭文件
  16. #include "SET_SERIAL.H"                //串口頭文件
  17. #include "SET_PWM.H"                //PWM頭文件
  18. #include "MOTOR.H"                        //電機控制頭文件
  19. #include "MPU6050.H"                //MPU6050頭文件



  20. //******角度參數************

  21. float Gyro_y;        //Y軸陀螺儀數據暫存
  22. float Angle_gy;      //由角速度計算的傾斜角度
  23. float Accel_x;             //X軸加速度值暫存
  24. float Angle_ax;      //由加速度計算的傾斜角度
  25. float Angle;         //小車最終傾斜角度
  26. uchar value;                 //角度正負極性標記        

  27. //******PWM參數*************

  28. int   speed_mr;                 //右電機轉速
  29. int   speed_ml;                 //左電機轉速
  30. int   PWM_R;         //右輪PWM值計算
  31. int   PWM_L;         //左輪PWM值計算
  32. float PWM;           //綜合PWM計算
  33. float PWMI;                         //PWM積分值

  34. //******電機參數*************

  35. float speed_r_l;        //電機轉速
  36. float speed;        //電機轉速濾波
  37. float position;            //位移

  38. //******藍牙遙控參數*************
  39. uchar remote_char;
  40. char  turn_need;
  41. char  speed_need;

  42. //*********************************************************
  43. //定時器100Hz數據更新中斷
  44. //*********************************************************

  45. void Init_Timer1(void)        //10毫秒@20MHz,100Hz刷新頻率
  46. {
  47.         AUXR &= 0xBF;                //定時器時鐘12T模式
  48.         TMOD &= 0x0F;                //設置定時器模式
  49.         TMOD |= 0x10;                //設置定時器模式
  50.         TL1 = 0xE5;                    //設置定時初值
  51.         TH1 = 0xBE;                    //設置定時初值
  52.         TF1 = 0;                    //清除TF1標志
  53.         TR1 = 1;                    //定時器1開始計時
  54. }



  55. //*********************************************************
  56. //中斷控制初始化
  57. //*********************************************************

  58. void Init_Interr(void)         
  59. {
  60.         EA = 1;     //開總中斷
  61.     EX0 = 1;    //開外部中斷INT0
  62.     EX1 = 1;    //開外部中斷INT1
  63.     IT0 = 1;    //下降沿觸發
  64.     IT1 = 1;    //下降沿觸發
  65.         ET1 = 1;    //開定時器1中斷
  66. }



  67. //******卡爾曼參數************
  68.                
  69. float code Q_angle=0.001;  
  70. float code Q_gyro=0.003;
  71. float code R_angle=0.5;
  72. float code dt=0.01;                          //dt為kalman濾波器采樣時間;
  73. char  code C_0 = 1;
  74. float xdata Q_bias, Angle_err;
  75. float xdata PCt_0, PCt_1, E;
  76. float xdata K_0, K_1, t_0, t_1;
  77. float xdata Pdot[4] ={0,0,0,0};
  78. float xdata PP[2][2] = { { 1, 0 },{ 0, 1 } };


  79. //*********************************************************
  80. // 卡爾曼濾波
  81. //*********************************************************

  82. //Kalman濾波,20MHz的處理時間約0.77ms;

  83. void Kalman_Filter(float Accel,float Gyro)               
  84. {
  85.         Angle+=(Gyro - Q_bias) * dt; //先驗估計

  86.         
  87.         Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先驗估計誤差協方差的微分

  88.         Pdot[1]=- PP[1][1];
  89.         Pdot[2]=- PP[1][1];
  90.         Pdot[3]=Q_gyro;
  91.         
  92.         PP[0][0] += Pdot[0] * dt;   // Pk-先驗估計誤差協方差微分的積分
  93.         PP[0][1] += Pdot[1] * dt;   // =先驗估計誤差協方差
  94.         PP[1][0] += Pdot[2] * dt;
  95.         PP[1][1] += Pdot[3] * dt;
  96.                
  97.         Angle_err = Accel - Angle;        //zk-先驗估計
  98.         
  99.         PCt_0 = C_0 * PP[0][0];
  100.         PCt_1 = C_0 * PP[1][0];
  101.         
  102.         E = R_angle + C_0 * PCt_0;
  103.         
  104.         K_0 = PCt_0 / E;
  105.         K_1 = PCt_1 / E;
  106.         
  107.         t_0 = PCt_0;
  108.         t_1 = C_0 * PP[0][1];

  109.         PP[0][0] -= K_0 * t_0;                 //后驗估計誤差協方差
  110.         PP[0][1] -= K_0 * t_1;
  111.         PP[1][0] -= K_1 * t_0;
  112.         PP[1][1] -= K_1 * t_1;
  113.                
  114.         Angle        += K_0 * Angle_err;         //后驗估計
  115.         Q_bias        += K_1 * Angle_err;         //后驗估計
  116.         Gyro_y   = Gyro - Q_bias;         //輸出值(后驗估計)的微分=角速度

  117. }



  118. //*********************************************************
  119. // 傾角計算(卡爾曼融合)
  120. //*********************************************************

  121. void Angle_Calcu(void)         
  122. {
  123.         //------加速度--------------------------

  124.         //范圍為2g時,換算關系:16384 LSB/g
  125.         //角度較小時,x=sinx得到角度(弧度), deg = rad*180/3.14
  126.         //因為x>=sinx,故乘以1.3適當放大

  127.         Accel_x  = GetData(ACCEL_XOUT_H);          //讀取X軸加速度
  128.         Angle_ax = (Accel_x - 1100) /16384;   //去除零點偏移,計算得到角度(弧度)
  129.         Angle_ax = Angle_ax*1.2*180/3.14;     //弧度轉換為度,


  130.     //-------角速度-------------------------

  131.         //范圍為2000deg/s時,換算關系:16.4 LSB/(deg/s)

  132.         Gyro_y = GetData(GYRO_YOUT_H);              //靜止時角速度Y軸輸出為-30左右
  133.         Gyro_y = -(Gyro_y + 30)/16.4;         //去除零點偏移,計算角速度值,負號為方向處理
  134.         //Angle_gy = Angle_gy + Gyro_y*0.01;  //角速度積分得到傾斜角度.        

  135.         
  136.         //-------卡爾曼濾波融合-----------------------

  137.         Kalman_Filter(Angle_ax,Gyro_y);       //卡爾曼濾波計算傾角


  138.         /*//-------互補濾波-----------------------

  139.         //補償原理是取當前傾角和加速度獲得傾角差值進行放大,然后與
  140.     //陀螺儀角速度疊加后再積分,從而使傾角最跟蹤為加速度獲得的角度
  141.         //0.5為放大倍數,可調節補償度;0.01為系統周期10ms        
  142.                
  143.         Angle = Angle + (((Angle_ax-Angle)*0.5 + Gyro_y)*0.01);*/
  144.                                                                                                                           
  145. }  



  146. //*********************************************************
  147. //電機轉速和位移值計算
  148. //*********************************************************

  149. void Psn_Calcu(void)         
  150. {
  151.         
  152.         speed_r_l =(speed_mr + speed_ml)*0.5;
  153.         speed *= 0.7;                                  //車輪速度濾波
  154.         speed += speed_r_l*0.3;        
  155.         position += speed;                          //積分得到位移
  156.         position += speed_need;
  157.         if(position<-6000) position = -6000;
  158.         if(position> 6000) position =  6000;

  159.          
  160. }


  161. static float code Kp  = 9.0;       //PID參數
  162. static float code Kd  = 2.6;            //PID參數
  163. static float code Kpn = 0.01;      //PID參數
  164. static float code Ksp = 2.0;            //PID參數

  165. //*********************************************************
  166. //電機PWM值計算
  167. //*********************************************************

  168. void PWM_Calcu(void)         
  169. {
  170.    
  171.         if(Angle<-40||Angle>40)               //角度過大,關閉電機
  172.         {  
  173.           CCAP0H = 0;
  174.       CCAP1H = 0;
  175.           return;
  176.         }
  177.         PWM  = Kp*Angle + Kd*Gyro_y;          //PID:角速度和角度
  178.         PWM += Kpn*position + Ksp*speed;      //PID:速度和位置
  179.         PWM_R = PWM + turn_need;
  180.         PWM_L = PWM - turn_need;
  181.         PWM_Motor(PWM_L,PWM_R);
  182.          
  183. }




  184. //*********************************************************
  185. //手機藍牙遙控
  186. //*********************************************************

  187. void Bluetooth_Remote(void)         
  188. {

  189.         remote_char = receive_char();                                   //接收藍牙串口數據

  190.         if(remote_char ==0x02) speed_need = -80;           //前進
  191.         else if(remote_char ==0x01) speed_need = 80;   //后退
  192.              else speed_need = 0;                                           //不動

  193.     if(remote_char ==0x03) turn_need = 15;                   //左轉
  194.         else if(remote_char ==0x04) turn_need = -15;   //右轉
  195.              else turn_need = 0;                                           //不轉
  196.          
  197. }


  198. /*=================================================================================*/

  199. //*********************************************************
  200. //main
  201. //*********************************************************
  202. void main()
  203. {

  204.         delaynms(500);           //上電延時
  205.         Init_PWM();               //PWM初始化
  206.     Init_Timer0();     //初始化定時器0,作為PWM時鐘源
  207.         Init_Timer1();     //初始化定時器1
  208.         Init_Interr();     //中斷初始化
  209.         Init_Motor();           //電機控制初始化
  210.         Init_BRT();                   //串口初始化(獨立波特率)
  211.         InitMPU6050();     //初始化MPU6050
  212.         delaynms(500);            

  213.         while(1)
  214.         {
  215.            
  216.          Bluetooth_Remote();

  217.         }
  218. }


  219. /*=================================================================================*/

  220. //********timer1中斷***********************

  221. void Timer1_Update(void) interrupt 3
  222. {
  223.   
  224.    TL1 = 0xE5;                    //設置定時初值10MS
  225.    TH1 = 0xBE;
  226.    
  227.    //STC_ISP();                    //程序下載
  228.    Angle_Calcu();                  //傾角計算
  229.    Psn_Calcu();                    //電機位移計算
  230.    PWM_Calcu();                    //計算PWM值
  231.    
  232.    speed_mr = speed_ml = 0;         

  233. }


  234. //********右電機中斷***********************

  235. void INT_L(void) interrupt 0
  236. {

  237.    if(SPDL == 1)  { speed_ml++; }                 //左電機前進
  238.    else                      { speed_ml--; }                 //左電機后退
  239.    LED = ~LED;

  240. }


  241. //********左電機中斷***********************

  242. void INT_R(void) interrupt 2
  243. {

  244.    if(SPDR == 1)  { speed_mr++; }                 //右電機前進
  245.    else                      { speed_mr--; }                 //右電機后退
  246.    LED = ~LED;

  247. }
復制代碼

所有資料51hei提供下載:
51_MPU6050_Kalman_PWM_remote.rar (56.26 KB, 下載次數: 157)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:205015 發表于 2019-7-3 09:00 | 只看該作者
一個月了,竟然無人來頂貼,,樓主是否成功了,后續交流學習下哦。
回復

使用道具 舉報

板凳
ID:591400 發表于 2019-7-27 19:53 | 只看該作者
角度漂移情況如何?
回復

使用道具 舉報

地板
ID:233015 發表于 2019-8-24 08:07 來自手機 | 只看該作者
頂,樓主是否成功了。
回復

使用道具 舉報

5#
ID:479765 發表于 2019-8-24 12:07 | 只看該作者
brave_ruan 發表于 2019-8-24 08:07
頂,樓主是否成功了。

我用stm32做了 已成功
回復

使用道具 舉報

6#
ID:253767 發表于 2019-8-25 07:40 | 只看該作者
謝謝分享!!!
回復

使用道具 舉報

7#
ID:479765 發表于 2019-8-25 12:25 | 只看該作者
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩欧美在线视频 | 中文字幕精品一区 | 欧美激情久久久 | 中文字幕蜜臀 | 久久久女女女女999久久 | 国产精品成人在线 | 中文字幕一级毛片 | 色婷婷九月 | 成人精品一区二区三区中文字幕 | 欧美1区| www四虎影视| 国产精品人人做人人爽 | chinese中国真实乱对白 | 五月天天丁香婷婷在线中 | 久久久99国产精品免费 | 久久国产精品视频 | 亚洲狠狠爱 | 91国自视频 | 在线欧美一区 | 欧美精品区 | 日韩欧美在线播放 | www国产成人 | 国产乱码久久久 | 夜夜草视频 | 国产农村一级国产农村 | 九一在线观看 | 国产不卡一区 | 亚洲91| 国产精品永久免费视频 | 欧美成人精品 | 亚洲va欧美va天堂v国产综合 | 做a视频 | 免费看一级毛片 | 激情免费视频 | 欧美三级免费观看 | 久久精品99 | 欧美极品在线 | 日韩电影中文字幕 | 精品久久久久国产免费第一页 | 天天干天天干 | 久久久久久美女 |