找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STM32安卓藍(lán)牙遙控二輪自平衡小車全套設(shè)計(jì)資料(APP及源碼PCB)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
Altium Designer畫的二輪自平衡小車電路原理圖和PCB圖如下:(51hei附件中可下載工程文件)



上層和中層亞克力3D圖及CAD圖


安卓藍(lán)牙遙控器APK及源碼



整體BOM表格



02 - 姿態(tài)解算MCU源代碼(STM32F103C8T6)
  1. /* main.c file
  2. 編寫者:lisn3188
  3. 編譯環(huán)境:MDK-Lite  Version: 4.23
  4. 測試: 本程序已在第七實(shí)驗(yàn)室的mini IMU上完成測試
  5. 功能:
  6. 1.初始化各個(gè)傳感器,
  7. 2.運(yùn)行姿態(tài)解算和高度測量
  8. 3.將解算的姿態(tài)和各個(gè)傳感器的輸出上傳到 MiniIMU AHRS 測試軟件
  9. 4.響應(yīng) PC發(fā)送的命令
  10. ------------------------------------*/

  11. /*----------------------------------------------------------------
  12. 修改備忘:(2014.08.28 by flotox)
  13. 1/去掉氣壓傳感器數(shù)據(jù)接口
  14. 2/保持幀格式
  15. 3/數(shù)據(jù)輸出頻率調(diào)整為20hz
  16. 4/調(diào)整機(jī)頭方向
  17. 5/保留陀螺儀標(biāo)零偏
  18. 6/去掉UART1數(shù)據(jù)輸出
  19. 7/只輸出姿態(tài)數(shù)據(jù)結(jié)算幀
  20. 8/在數(shù)據(jù)融合時(shí)去掉磁力計(jì)的影響
  21. 9/上電數(shù)據(jù)即可用,不用等待
  22. ----------------------------------------------------------------*/

  23. #include "common.h"  //包含所有的驅(qū)動(dòng) 頭文件

  24. //上傳數(shù)據(jù)的狀態(tài)機(jī)
  25. #define REIMU  0x01 //上傳解算的姿態(tài)數(shù)據(jù)
  26. #define REMOV  0x02        //上傳傳感器的輸出
  27. #define REHMC  0x03        //上傳磁力計(jì)的標(biāo)定值

  28. #define Upload_Speed  100   //數(shù)據(jù)上傳速度  單位 Hz
  29. #define upload_time (1000000/Upload_Speed)  //計(jì)算上傳的時(shí)間。單位為us

  30. int16_t ax, ay, az;        
  31. int16_t gx, gy, gz;
  32. int16_t hx, hy, hz;
  33. int32_t Temperature = 0, Pressure = 0, Altitude = 0;
  34. uint32_t system_micrsecond;
  35. int16_t hmcvalue[3];
  36. u8 state= REIMU;  //發(fā)送特定幀 的狀態(tài)機(jī)
  37. /**************************實(shí)現(xiàn)函數(shù)********************************************
  38. *函數(shù)原型:                int main(void)
  39. *功  能:                主程序
  40. *******************************************************************************/
  41. int main(void)
  42. {
  43.         int16_t Math_hz=0;
  44.         unsigned char PC_comm; //PC 命令關(guān)鍵字節(jié)         
  45.         float ypr[3]; // yaw pitch roll
  46.         /* 配置系統(tǒng)時(shí)鐘為72M 使用外部8M晶體+PLL*/      
  47.     //SystemInit();
  48.         delay_init(72);                //延時(shí)初始化
  49.     Initial_LED_GPIO();        //初始化STM32-SDK板子上的LED接口
  50.         Initial_PWMLED();
  51.         Initial_UART2(115200L);
  52.         load_config();  //從flash中讀取配置信息 -->eeprom.c
  53.         IIC_Init();         //初始化I2C接口
  54.         delay_ms(300);        //等待器件上電
  55.         //UART1_Put_String("Initialize...\r\n");
  56.         IMU_init(); //初始化IMU和傳感器
  57.         system_micrsecond=micros();
  58.         while(1){        //主循環(huán)
  59.                
  60.         //delay_ms(1); //延時(shí),不要算那么快。
  61.         IMU_getYawPitchRoll(ypr); //姿態(tài)更新
  62.         Math_hz++; //解算次數(shù) ++

  63. //-------------上位機(jī)------------------------------
  64.         //是否到了更新 上位機(jī)的時(shí)間了?
  65.         if((micros()-system_micrsecond)>upload_time){
  66.         switch(state){
  67.         case REIMU:
  68.         UART2_ReportIMU((int16_t)(ypr[0]*10.0),(int16_t)(ypr[1]*10.0),
  69.         (int16_t)(ypr[2]*10.0),Altitude/10,Temperature,Pressure/10,Math_hz*Upload_Speed);
  70.         Math_hz=0;
  71. //        state = REMOV; //更改狀態(tài)。
  72.         break;
  73.         case REMOV:
  74.         MPU6050_getlastMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  75.         HMC58X3_getlastValues(&hx,&hy,&hz);
  76.         UART2_ReportMotion(ax,ay,az,gx,gy,gz,hx,hy,hz);
  77.         state = REIMU;
  78.         if(HMC5883_calib)state = REHMC; //需要發(fā)送當(dāng)前磁力計(jì)標(biāo)定值
  79.         break;
  80.         default:
  81.         UART2_ReportHMC(HMC5883_maxx,HMC5883_maxy,HMC5883_maxz,
  82.                  HMC5883_minx,HMC5883_miny,HMC5883_minz,0);//發(fā)送標(biāo)定值
  83.         state = REIMU;
  84.         break;
  85.         }//switch(state)                          
  86.         system_micrsecond=micros();         //取系統(tǒng)時(shí)間 單位 us
  87.         LED_Change();        //LED1改變亮度
  88.         }
  89. //--------------------------------------------------
  90.         //處理PC發(fā)送來的命令
  91.         if((PC_comm=UART2_CommandRoute())!=0xff)
  92.         {
  93.         switch(PC_comm){ //檢查命令標(biāo)識(shí)
  94.         case Gyro_init:                        MPU6050_InitGyro_Offset(); break; //讀取陀螺儀零偏
  95.         case High_init:                                 break;                //氣壓高度 清零
  96.         case HMC_calib_begin:        HMC5883L_Start_Calib();        break; //開始磁力計(jì)標(biāo)定
  97.         case HMC_calib:                HMC5883L_Save_Calib();        break;   //保存磁力計(jì)標(biāo)定
  98.         }
  99.         }// 處理PC 發(fā)送的命令

  100.         }//主循環(huán) while(1) 結(jié)束

  101. }  //main        

  102. //------------------End of File----------------------------
復(fù)制代碼


01 - 運(yùn)動(dòng)控制MCU源代碼(STM32F103RCT6)
  1. /**---------------------------------------------------------------
  2.         項(xiàng)目:兩輪自平衡小車(Two-Wheels Auto-Balancing Vechile)
  3.         版本:v1.0.0
  4.         文件: Balancing.c
  5.         功能:自平衡計(jì)算
  6.         作者:flotox@yeah.net
  7.         日期:2014.9.5
  8.         更新:2014.9.5
  9. ----------------------------------------------------------------*/

  10. #include "stm32f10x.h"
  11. #include "GlobalVars.h"
  12. #include "MotorDriver.h"

  13. // float                Temp[200] = {0};
  14. // uint32_t        Temp_i = 0;

  15. /**
  16.         *        @brief                自平衡計(jì)算外設(shè)初始化
  17.         *        @param                none
  18.         *        @retval                none
  19.         */
  20. void        Balancing_Init(void){
  21.         
  22.         GPIO_InitTypeDef                                GPIO_InitStructure;
  23.         TIM_TimeBaseInitTypeDef        TIM_TimeBaseStructure;
  24.         NVIC_InitTypeDef                                NVIC_InitStructure;
  25.         
  26.         /*開啟GPIOC外設(shè)時(shí)鐘*/
  27.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  28.         /*開啟TIM4外設(shè)時(shí)鐘*/
  29.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  30.         
  31.         /*配置PC.15端口為Out_PP模式*/
  32.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  33.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  34.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  35.         GPIO_Init(GPIOC, &GPIO_InitStructure);
  36.         
  37.         /*TIM4 NVIC設(shè)置*/
  38.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                                                                                                        //2 bits for pre-emption priority 2 bits for subpriority
  39.         
  40.         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  41.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;                                                                //指定搶占式優(yōu)先級(jí)別,可取0~3
  42.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                                                                                        //指定響應(yīng)式優(yōu)先級(jí)別,可取0~3
  43.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  44.         NVIC_Init(&NVIC_InitStructure);
  45.         
  46.         TIM_DeInit(TIM4);
  47.         
  48.         /*定時(shí)器基本配置*/
  49.         TIM_TimeBaseStructure.TIM_Prescaler = 0;                                                                                                                                //時(shí)鐘預(yù)分頻數(shù)0,TIM4的時(shí)鐘計(jì)數(shù)頻率為72MHz
  50.         TIM_TimeBaseStructure.TIM_Period = 20 - 1;                                                                                                                        //自動(dòng)重裝載寄存器數(shù)20,10ms溢出1次
  51.         TIM_TimeBaseStructure.TIM_ClockDivision = 0;                                                                                                                //采樣分頻
  52.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;                                                        //向上計(jì)數(shù)
  53.         TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  54.         
  55.         TIM_PrescalerConfig(TIM4, 0x8c9f, TIM_PSCReloadMode_Immediate);                                        //時(shí)鐘分頻系數(shù)36000,定時(shí)器時(shí)鐘為2KHz
  56.         TIM_ARRPreloadConfig(TIM4, DISABLE);                                                                                                                                                //禁止ARR預(yù)裝載緩沖器
  57.         TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);                                                                                                                        //使能Update中斷
  58.         
  59.         TIM_Cmd(TIM4, ENABLE);                                                                                                                                                                                                        //開啟時(shí)鐘
  60. }

  61. /**
  62.         *        @brief                自平衡計(jì)算循環(huán)子程序(10ms被調(diào)用一次)
  63.         *        @param                none
  64.         *        @retval                none
  65.         */
  66. void        Balancing_Loop(void){

  67.         uiCount_Led++;
  68.         
  69.         /*Led閃爍*/
  70.         if(uiCount_Led >= 40){
  71.                
  72.                 uiCount_Led = 0;
  73.                 GPIO_WriteBit(GPIOC,GPIO_Pin_15,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_15)));
  74.         }
  75.         
  76.         switch(iMotion_Type){

  77.                 case        MOTION_TYPE_NONE:
  78.                         
  79.                         fTarget_Speed = 0;
  80.                         fTarget_Turn = 0;
  81.                         break;
  82.                
  83.                 case        MOTION_TYPE_FORWARDS:
  84.                         
  85.                         fTarget_Speed = -150;
  86.                         fTarget_Turn = 0;
  87.                         break;
  88.                
  89.                 case        MOTION_TYPE_BACKWARDS:
  90.                         
  91.                         fTarget_Speed = 150;                        //150
  92.                         fTarget_Turn = 0;
  93.                         break;
  94.                
  95.                 case        MOTION_TYPE_TURN_LEFT:
  96.                         
  97.                         fTarget_Speed = 0;
  98.                         fTarget_Turn = -210;
  99.                         break;
  100.                
  101.                 case        MOTION_TYPE_TURN_RIGHT:
  102.                         
  103.                         fTarget_Speed = 0;
  104.                         fTarget_Turn = 210;
  105.                         break;
  106.                
  107.                 case        MOTION_TYPE_FORWARDS_TURN_LEFT:
  108.                         
  109.                         fTarget_Speed = -150;
  110.                         fTarget_Turn = -210;
  111.                         break;
  112.                
  113.                 case        MOTION_TYPE_FORWARDS_TURN_RIGHT:
  114.                         
  115.                         fTarget_Speed = -150;
  116.                         fTarget_Turn = 210;
  117.                         break;
  118.                
  119.                 case        MOTION_TYPE_BACKWARDS_TURN_LEFT:
  120.                         
  121.                         fTarget_Speed = 150;
  122.                         fTarget_Turn = -210;
  123.                         break;
  124.                
  125.                 case        MOTION_TYPE_BACKWARDS_TURN_RIGHT:
  126.                         
  127.                         fTarget_Speed = 150;
  128.                         fTarget_Turn = 210;
  129.                         break;
  130.         }
  131.         
  132.         /*動(dòng)作改變時(shí)增加中間的過度過程,過度過程為50ms*/
  133.         if((iMotion_Type != iMotion_Type_Last) && (iCount_Motion_Type_Change == 0)){
  134.                
  135.                 iCount_Motion_Type_Change = 10;
  136.                 iMotion_Type_Last = iMotion_Type;
  137.         }
  138.         
  139.         if(iCount_Motion_Type_Change != 0){
  140.                
  141.                 iCount_Motion_Type_Change --;
  142.                 fTarget_Speed = 0;
  143.                 fTarget_Turn = 0;
  144.         }
  145.         
  146.         /*速度和位移一階低通濾波*/
  147.         fSpeed_Vechile = (iCount_L + iCount_R) * 0.5;
  148.         fSpeed_Vechile_F = fSpeed_Vechile_F * 0.7 + fSpeed_Vechile * 0.3;
  149.         
  150.         /*累加求位移*/
  151.         fPosition += fSpeed_Vechile_F;

  152.         /*位移調(diào)節(jié)量*/
  153.         fPosition += fTarget_Speed;

  154.         /*位移限制,上下限待調(diào)節(jié)*/
  155.         if(fPosition > 5000){                                                                                                                                //5000
  156.                
  157.                 fPosition = 5000;
  158.         }
  159.         else if(fPosition < -5000){
  160.                
  161.                 fPosition = -5000;
  162.         }
  163.         
  164.         /*左輪和右輪光柵脈沖計(jì)數(shù)器清零*/
  165.         iCount_L = 0;
  166.         iCount_R = 0;
  167.         
  168.         /*角度限制*/
  169.         if( (fPitchAngle < 40.0) && (fPitchAngle > -40.0) ){
  170.                
  171.                
  172.                 /*俯仰角速度,單位deg/s,大于0則角速度方向向前,小于0則角速度方向向后*/
  173.                 fAngle_Vel = -(fPitchAngle - fPitchAngle_Last);
  174.                
  175.                 /*保存此次俯仰角度*/
  176.                 fPitchAngle_Last = fPitchAngle;
  177.                
  178.                 /*計(jì)算PWM輸出控制量*/
  179.                 fPWM =        (-fpid_angle) * fPitchAngle +
  180.                                                 fpid_angle_vel * fAngle_Vel +
  181.                                                 fpid_speed * fSpeed_Vechile_F +
  182.                                                 fPosition * fpid_position;
  183.                
  184.                 /*旋轉(zhuǎn)調(diào)節(jié)量*/
  185.                 fPWM_L = fPWM + fTarget_Turn;
  186.                 fPWM_R = fPWM - fTarget_Turn;
  187.                
  188.                 /*左輪控制*/
  189.                 if(fPWM_L > 0){
  190.                         
  191.                         MotorDriver_L_Turn_Forward();
  192.                 }
  193.                 else{
  194.                         
  195.                         MotorDriver_L_Turn_Reverse();
  196.                         fPWM_L = -fPWM_L;
  197.                 }
  198.                         
  199.                 /*右輪控制*/
  200.                 if(fPWM_R > 0){
  201.                         
  202.                         MotorDriver_R_Turn_Forward();
  203.                 }
  204.                 else{
  205.                         
  206.                         MotorDriver_R_Turn_Reverse();
  207.                         fPWM_R = -fPWM_R;
  208.                 }
  209.                
  210.                 /*加上死區(qū)電壓*/
  211.                 fPWM_L += 40;
  212.                 fPWM_R += 10;
  213.                
  214.                 /*限制PWM*/
  215.                 if(fPWM_L > 1000){
  216.                         
  217.                         fPWM_L = 1000;
  218.                 }
  219.                
  220.                 if(fPWM_R > 1000){
  221.                         
  222.                         fPWM_R = 1000;
  223.                 }
  224.                
  225.                 /*輸出PWM控制量*/
  226.                 TIM_SetCompare2(TIM8, (uint16_t)fPWM_L);                                        //左輪
  227.                 TIM_SetCompare2(TIM1, (uint16_t)fPWM_R);                                        //右輪
  228.         }
  229.         /*傾角過大時(shí)的姿態(tài)數(shù)據(jù)不參與計(jì)算*/
  230.         else{
  231.                
  232.                 TIM_SetCompare2(TIM8, 0);                                                                                                        //左輪
  233.                 TIM_SetCompare2(TIM1, 0);                                                                                                        //右輪
  234.         }
  235.         
  236. }
復(fù)制代碼



全部資料51hei下載地址:
二輪自平衡小車.rar (14.78 MB, 下載次數(shù): 59)


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

使用道具 舉報(bào)

沙發(fā)
ID:1 發(fā)表于 2018-9-30 02:44 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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