找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 8972|回復(fù): 0
收起左側(cè)

STM32平衡車程序+原理圖(步進(jìn)電機(jī))

[復(fù)制鏈接]
ID:591632 發(fā)表于 2020-8-19 10:43 | 顯示全部樓層 |閱讀模式
自平衡車主控為STM32f103r
平衡車硬件總體設(shè)計(jì),平衡車以STM32為主控芯片,通過(guò)處理從各個(gè)傳感器返回的數(shù)據(jù)使小車達(dá)到動(dòng)態(tài)平衡以及遙控的實(shí)現(xiàn)。
平衡車的軟件結(jié)構(gòu)分為四大部分,各個(gè)部分之間相互關(guān)聯(lián)。軟件總體結(jié)構(gòu):OLED顯示實(shí)時(shí)數(shù)據(jù)、按鍵調(diào)試各項(xiàng)參數(shù)部分;串口和超聲波部分解析有關(guān)指令部分;PID控制器輸出控制部分。在串口和超聲波部分獲取控制指令后,傳輸給PID控制器,最終由PID計(jì)算控制器輸出相應(yīng)PWM值控制電機(jī),以保持平衡車的平衡。主控芯片在接收MPU6050傳感器返回的角度值與角加速度值后,對(duì)返回?cái)?shù)據(jù)進(jìn)行一階互補(bǔ)濾波處理。一階互補(bǔ)濾波算法將角度數(shù)據(jù)進(jìn)行融合,降低MPU6050傳感器的噪聲信號(hào)的影響,從而得到準(zhǔn)確的平衡車當(dāng)前姿態(tài)。STM32主控芯片通過(guò)直立的PD控制器得到較為準(zhǔn)確的PWM輸出控制數(shù)值,控制電機(jī)轉(zhuǎn)動(dòng)使得小車實(shí)現(xiàn)基本平衡。為了減小小車的左右偏移幅度,將MPU6050返回的Z軸轉(zhuǎn)動(dòng)量輸出到轉(zhuǎn)向PD控制器進(jìn)行計(jì)算,再將轉(zhuǎn)向PWM增量值與直立PWM增量進(jìn)行疊加輸出,得到較為準(zhǔn)確的PWM控制值,從而使小車保持直立狀態(tài)。在Android手機(jī)上安裝一個(gè)第三方藍(lán)牙遙控APP,由APP發(fā)出的相應(yīng)控制指令。系統(tǒng)通過(guò)藍(lán)牙模塊接收控制指令,再由串口中斷接收藍(lán)牙模塊控制數(shù)據(jù),之后系統(tǒng)進(jìn)行控制指令的解析得到控制輸出值,控制小車前后左右的行駛動(dòng)作。在實(shí)際的測(cè)試過(guò)程中,發(fā)現(xiàn)藍(lán)牙的有效控制距離為8米左右,并且手機(jī)與藍(lán)牙模塊的容易被各種因素干擾,使小車在控制距離較遠(yuǎn)的位置失去控制。建議大家使用NRF或其它控制信號(hào)較遠(yuǎn)的模塊進(jìn)行通訊,從而實(shí)現(xiàn)相對(duì)較遠(yuǎn)的距離控制。

單片機(jī)源程序如下:
  1. /******************** (C) COPYRIGHT 2014 POWSOS Team **************************
  2. * 文件名  :main.c
  3. * 描述    :     
  4. * 實(shí)驗(yàn)平臺(tái):STM32F103RBT6
  5. * 庫(kù)版本  :ST3.5.0
  6. * 作者    :  Powsos_Team
  7. * 版本    :V2.0
  8. * 日期    :2014.8.23
  9. * 修訂歷史:V2.0
  10. ******************************************************************************/

  11. #include "stm32f10x.h"
  12. #include "iic.h"
  13. #include "timer.h"
  14. #include "usart.h"
  15. #include "mpu6050.h"
  16. #include "filter.h"
  17. #include "calculate.h"
  18. #include "gpio.h"
  19. #include "time_test.h"
  20. #include "hc_sr04.h"
  21. #include "delay.h"
  22. #include <stdio.h>
  23. #include <math.h>


  24. //#define Debug  

  25. #define GX_OFFSET 0x01
  26. #define AX_OFFSET 0x01
  27. #define AY_OFFSET 0x01
  28. #define AZ_OFFSET 0x01


  29. #define duoji_offset  120

  30. extern u8  duoji_flag;
  31. extern u8 duoji_cnt;
  32. extern u16 time;
  33. extern u8 duoji_pwm;

  34. u8 hcsr04_test_flag = 0;
  35. u8 receive_data;
  36. u8 flg_get_senor_data;
  37. u8 out[35]  ={0x5f, 0x60, 0};
  38. u8 Duoji_direction = 1;  /*1,前方,2:左邊   3:右邊,舵機(jī)*/
  39. u8 Move_direcetion = 1;  /*1靜止  2,前方, 3,后退 4:左邊   5:右邊 小車運(yùn)行方向*/
  40. u16 distance =0 ;
  41. int  pulsewidth;
  42. float angle, angle_dot, f_angle, f_angle_dot;
  43. s16 temp;
  44. s16 gx, gy, gz, ax ,ay, az, temperature;

  45. #define FILTER_COUNT  16
  46. s16 gx_buf[FILTER_COUNT], ax_buf[FILTER_COUNT], ay_buf[FILTER_COUNT],az_buf[FILTER_COUNT];
  47. /******************************************************************************/
  48. void delay(u32 count)
  49. {
  50.   for(; count != 0; count--);
  51. }
  52. /*************************************************

  53. 名稱:void acc_filter(void)
  54. 功能:加速度計(jì)數(shù)據(jù)濾波
  55. 輸入?yún)?shù):據(jù)濾波后的數(shù)據(jù)
  56. 輸出參數(shù):無(wú)
  57. 返回值:  無(wú)
  58. **************************************************/
  59. void acc_filter(void)
  60. {
  61.   u8 i;
  62.   s32 ax_sum = 0, ay_sum = 0, az_sum = 0;

  63.   for(i = 1 ; i < FILTER_COUNT; i++)
  64.   {
  65.     ax_buf[i - 1] = ax_buf[i];
  66.         ay_buf[i - 1] = ay_buf[i];
  67.         az_buf[i - 1] = az_buf[i];
  68.   }

  69.   ax_buf[FILTER_COUNT - 1] = ax;
  70.   ay_buf[FILTER_COUNT - 1] = ay;
  71.   az_buf[FILTER_COUNT - 1] = az;

  72.   for(i = 0 ; i < FILTER_COUNT; i++)
  73.   {
  74.     ax_sum += ax_buf[i];
  75.         ay_sum += ay_buf[i];
  76.         az_sum += az_buf[i];
  77.   }

  78.   ax = (s16)(ax_sum / FILTER_COUNT);
  79.   ay = (s16)(ay_sum / FILTER_COUNT);
  80.   az = (s16)(az_sum / FILTER_COUNT);
  81. }

  82. /* I/O口模擬輸出PWM控制舵機(jī),50hz */
  83. void servopulse(int myangle)//定義一個(gè)脈沖函數(shù)
  84. {
  85.          // EA = 0;
  86.         //  pulsewidth = (((myangle+duoji_offset)*25)+500)/1000;;// 舵機(jī)中心值可能會(huì)偏,修改20,做調(diào)整
  87.         pulsewidth =myangle;

  88. }

  89. /*****************************************************************************/
  90. int main(void)
  91. {
  92.         SystemInit();
  93.         delay_init(72);
  94.         gpio_init();       
  95.         delay(0x80000);
  96.     usart_init();                                          
  97.     iic_init();
  98.     timer_init();
  99.     TIM1_Configuration();
  100.     HCSR04_Init();
  101.     motor_init();
  102.         mpu6050_init();
  103.         STOP_TIME;
  104.         duoji_flag =1;
  105.         duoji_cnt = 0;
  106.         servopulse(3);/*上電將舵機(jī)放至中間*/
  107.          while (1)
  108.         {
  109.             if(flg_get_senor_data)
  110.             {
  111.               flg_get_senor_data = 0;
  112.               mpu6050_get_data(&gx, &gy, &gz, &ax, &ay , &az, &temperature);
  113.                   acc_filter();       

  114.                   gx-=  GX_OFFSET;
  115.                   ax -= AX_OFFSET;
  116.                   ay -=        AY_OFFSET;
  117.                   az -= AZ_OFFSET;

  118.             angle_dot = gx * GYRO_SCALE;  //+-2000  0.060975 °/LSB   //陀螺儀
  119.               angle = atan(ay / sqrt(ax * ax + az * az ));
  120.              
  121.              angle = angle * 57.295780;    //180/pi


  122.                  kalman_filter(angle, angle_dot, &f_angle, &f_angle_dot);//     加速度計(jì)計(jì)算的角度, 陀螺儀角速度 , 融合后的角度, 融合后的角速度
  123.                    receive_parameter(receive_data);

  124.                    pid(f_angle, f_angle_dot);

  125. #ifdef  Debug
  126.                               temp = (s16)(f_angle * 100);
  127.              
  128.                                  out[2] = (u8)(gx >> 8);
  129.                     out[3] = (u8)(gx);
  130.                                  out[4] = (u8)(gy >> 8);
  131.                                  out[5] = (u8)(gy);
  132.                                  out[6] = (u8)(gz >> 8);
  133.                                  out[7] = (u8)(gz);
  134.                                  out[8] = (u8)(ax >> 8);
  135.                                  out[9] = (u8)(ax);
  136.                                  out[10] = (u8)(ay >> 8);
  137.                                  out[11] = (u8)(ay);
  138.                                  out[12] = (u8)(az >> 8);
  139.                                  out[13] = (u8)(az);
  140.                            out[14] = (u8)(temp >> 8);
  141.                                  out[15] = (u8)(temp);

  142.                                 USART_SendStringData(USART1,&out[0],16);

  143. #endif
  144.           
  145.                        
  146.             }  //end if               
  147.        
  148.                
  149.     if(hcsr04_test_flag)
  150.     {
  151.                  hcsr04_test_flag=0;                 
  152.                  measure_distance(receive_data);
  153.                                          
  154.                  switch(Duoji_direction)
  155.                  {
  156.                         case Duoji_Front:        USART_printf(USART2,"Front_distance: %d cm\r\n",distance);break;
  157.                         case Duoji_Left:        USART_printf(USART2,"Left_distance: %d cm\r\n",distance);break;
  158.                         case Duoji_Right:        USART_printf(USART2,"Right_distance: %d cm\r\n",distance);break;
  159.                  }
  160.                  
  161.                  
  162.         }
  163.         #if  0
  164.         /*若前方距離小于100,并且小車行駛方向是往前的,此時(shí)小車需要停止*/       
  165.         if((distance<50)&&(Move_direcetion==Move_front))
  166.         {                               
  167.                 receive_data ='s';
  168.         }
  169.                
  170.         #endif

  171.   }  
  172.        
  173. }

  174. /*****************END OF FILE************************************************************/
復(fù)制代碼

下載: STM32平衡車程序+原理圖(步進(jìn)電機(jī)).7z (588.1 KB, 下載次數(shù): 173)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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