找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

超詳細雙輪平衡小車原理分析 附STM32源碼

  [復制鏈接]
跳轉到指定樓層
樓主
ID:380054 發(fā)表于 2018-9-19 23:06 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
手中有些關于雙輪平衡小車的資料,特與大家分享,一同學習進步。

一、平衡小車原理

平衡原理

平衡小車是通過兩個電機運動下實現(xiàn)小車不倒下直立行走的多功能智能小,在外力的推拉下小車依然保持不倒下。這么一說可能還沒有很直觀的了解 究竟什么是平衡小車不過這個平衡小車實現(xiàn)的原理其實是在人們生活中的經(jīng)驗 得來的如果通過簡單的練習,一般人可以通過自己的手指把木棒直立而不倒的
放在指尖上,所以練習的時候需要學會的兩個條件一是放在指尖上可以移動, 二是通過眼睛觀察木棒傾斜角傾斜趨勢(角速度。通過手指的移動去 木棒傾斜的角度和趨勢,使得木棒能直立不倒。這樣的條件是不可以缺一的, 實際上加入這兩個條件,控制過程中就是負反饋機制。

而世界上沒有任何一個人可以蒙眼不看,就可以直立木棒的因為沒有眼睛的負反饋,就不知道筆的傾斜角度和趨勢。這整個過程可以用一個執(zhí)行式表達:


平衡小車也是這樣的過程
,通過負反饋實現(xiàn)平衡。與上面保持木棒直立比較則相對簡單因為小車有兩個輪子著地,車體只會在輪子滾動的方向上發(fā)生 傾斜。控制輪子轉動,抵消在一個維度上傾斜的趨勢便可以保持車體平衡了。





所以根據(jù)上述的原理,通過測量小車的傾角和傾角速度控制小車車輪的加
速度來消除小車的傾角因此,小車傾角以及傾角速度的測量成為控制小車直立 的關鍵我們的亞博智能平衡小車使用了測量傾角和傾角速度的集成傳感器陀螺 儀-MPU6050(模塊詳細介紹在亞博智能平衡小車光盤資料3.硬件資料中)。






二、角度(物理分
PD 算法)


控制平衡小車,使得它作加速運動。這樣站在小車上(非慣性系,以車輪 作為坐標原點)分析倒立擺受力,就會受到額外的慣性,該力與車輪的加 速度方向相反,大小成正。這樣倒立(如 2)所受到的回復力為:公 1
F = mg sin θ-ma cos θ≈mg θ-mk1θ 1 ,由θ很小,所以進行了線 性化。假設負反饋控制是車輪加速 a 與偏角θ成正比,比例 k1。如果比例k1>g,g 是重力加速度)那么回復力的方向便于位移方向相反。

而為了讓倒立擺能夠盡快回到垂直置穩(wěn)定下來,還需要增加阻尼。 加的阻尼力與偏角的速度成正比,方向相反,因此公1可改F = mg θ-mk1 θ -mk2 θ` 按照上述倒立擺的模型,可得控制小車車輪加速度的算
a =k1θ+k2θ` 式中θ為小車角度,θ`為角速度。k1 k2都是比例系數(shù) 根據(jù)上述內容,建立速度的比例微分負反控制,根據(jù)基本控制理論討論小車通過閉環(huán)控制保持穩(wěn)定的條這里需要對控制理論有基本了)。 起車產(chǎn)速度xt。沿直于, 模傾atxt動方 如圖3所示。

圖3

在角度反饋控制,與角度成比例的控制量是稱為比例控 角速度成比例的控制量稱微分控制(角速度是角度的微分。因此 上面系數(shù) k1,k2 分別稱比例控制參數(shù)。其中微分參數(shù)相當于 阻尼力可以有效抑制車模震蕩。通過微分抑制控制震蕩的思想在后 面的速度和方向控制中也同樣適用。 總結控制車模直立穩(wěn)定的條件如下:
1)能夠精確測量車模傾角θ的大小和角速度θ'的大;


2)可以控制車輪的加速度。

上述控制實際結果是小車與地面不是嚴格垂,而是存在一個對 應的傾。重力的作用下,
小車會朝著一個方面加速前。為了保 持小車靜止或者勻速運需要這個安裝誤差在實際小車制作 過程中需要進機械調軟件參數(shù)設。另外需要通過軟件中的速 度控制來實現(xiàn)速度的穩(wěn)定性。在小車角度控制中出現(xiàn)的小車傾角偏 使得小車在傾斜的方向上產(chǎn)生加速。這個結果可以用來進行小車 的速度控制。下面將利用這個原理來調節(jié)小車的速度。


三、測速(物理模 立數(shù)學模 傳遞函數(shù) PD 法) 假設小車在上直立控制調節(jié)下已經(jīng)能夠保持平衡了,但是由于
安裝誤差,傳感器實際測量的角度與車模角度有偏因此小車實際 不是保持與地面垂直,而是存在個傾角。在重力的作用下,小車就 朝傾斜的方向加速前控制速只要通過控制小車的傾角就可以 實現(xiàn)了。具體實現(xiàn)需要解決三個問題:
1)如何測量小車速度?

2)如何通過小車直立控制實現(xiàn)小車傾角的改變?

3)如何根據(jù)速度誤差控制小車傾角? 第一個問題可以通過安裝在電機輸出軸上光碼來測量得到
小車的車輪速度。 4 所示。利用控制單片機計數(shù)器測量在固定 時間間隔內速脈沖信號的個數(shù)可以反映電機的轉速。




圖4

第二個問題可以通過角度控制給定值來解決。
給定小車直立控制 的設定值在角度控制調節(jié),小車將會自動維持在一個角度 前面小車直立控制算法可以知道,小傾角最終是跟蹤重力加速Z 軸的角度。因此小車傾角給定值重力加速度Z軸角度相減,便可 以最終決定小車傾角
第三個問題分析起來相對比較困難遠比直觀進行速度負反饋分 析復雜。首先對一個簡單例子進行分假設小車開始保持靜止, 后增加給定速度,為此需要小車往前傾斜以便獲得加速度。 立控制下,為了能夠有一個往前傾斜角度,往后運動, 樣會引起車輪速度下降(因為車輪往負方向運動了)。由于負反, 使得小車往前傾角需要更。此循環(huán),小車很快就傾倒。原本利 用負反饋進行速度控制反而成“正”反饋。
為什么負反饋控制在這兒失了呢?原來在直立控制下的小車 速度與小車傾角之間傳遞函數(shù)具非最小相位特性(在此省略了分 析),在反饋控制下容易造成系統(tǒng)不穩(wěn)定。
為了保證系統(tǒng)穩(wěn),往往取的小車傾角控時間常數(shù)Tz很大 樣便會引起系統(tǒng)產(chǎn)生兩個共軛極,而且極點的實部變得很小使得系統(tǒng)的速度控制會產(chǎn)生震蕩現(xiàn)。這個現(xiàn)象在實際參數(shù)整的時候可以觀察到。那么如何消除速度控制過程中的震蕩呢? 要解決控制震蕩問題,在前面的車角度控制中已經(jīng)有了經(jīng),那就是在控制反饋中增速度微分控但由于車輪的速度反饋信號 中往往存在噪聲,對速度進行微分運算會進一步加大噪聲的影響。 為此需要對上面控制方法進改進原系統(tǒng)中傾角調整過程時間常數(shù) 往往很大因此可以將該系統(tǒng)近似為一積分環(huán)節(jié)。將原來微分環(huán) 節(jié)和這個積分環(huán)節(jié)合并,形成一個比例控制環(huán)節(jié)。這樣可以保持系統(tǒng) 控制傳遞函數(shù)不變,同時避免了微分計算。
但在控制反饋中,只是使用反饋信號的比例和微分 積分,所以最終這個速度控制有殘差的控制但是直接引入誤差積 分控制環(huán)節(jié),會增加系統(tǒng)的復雜度為此就不再增加積分控制, 通過與角度控相結合后在進行。

要求小車在原地停止,速度為0。但是由于采用的是比例控, 如果此時陀螺儀,或者加速度傳感器安裝有誤差,最終小車傾 角不會最終調整0,小車會朝著斜的方向恒速運行下去。注意此 時車模不會像沒有速度控制那樣加速運行,但是速度不會最終為0。 為了消除這個誤可以將小車傾角設定量直接積分補償在角度控制 輸出中,這樣就會徹底消除速度控制誤第二點,由于加入了速度 控制可以補償陀螺儀和重力加速度漂移和誤差。所以此時重力 加速度傳感器實際上沒有必要了。
此時小車在控制啟動的時候,需保持小車的垂直狀態(tài)。此時陀螺儀的積分角度也初始化0。當然如果電路中已經(jīng)包括了重力加速度傳感器,也可以保留這部分,從而提高小車的穩(wěn)定性。后面的 最終給定的控制方案中,保留了這部分的控制回路。

四、轉向控制PD 算法) 通過左右電
速度差驅動小車轉向消除小車距離道路中心的偏
。通過調整小車的方向再加上車前行運動,可以逐步消除小車距 離中心線的距離差別個過程是一個積分過,因此小車差動控制 一般只需要進簡單的比例控制就可以完成小車方向控制。但是由于 小車本身安裝有電池等比較重的物體具有很大轉動慣,在調整 過程中會出現(xiàn)小車轉現(xiàn)象如果不加抑制,會使得小車過度 轉向而倒下。根據(jù)前面控制的經(jīng)驗,為了消除小車方向控 制中的過沖,需要增微分控制。



五、全方案整合 通過上面介紹,將車模直立行主要的控制算法集中起如圖5


圖5


為了實現(xiàn)小車直立行,需要采集如下信號:


(1)小車傾角速陀螺儀信號,獲得小車的傾角和角速度。

(2 重力加速度信號

(z軸信號),補償陀螺儀的漂。該信號可以省略,有速度控制替 代。
(3 小車電機轉速脈沖信,獲得小車運動速度,進行速度控制。

(4 小車轉動速度陀螺儀信獲得小車轉向角速, 制。


在小車控制中的直立、方向控制三個環(huán)節(jié)中,都使用 PD,這三種控制算法的輸出量最終通疊加通過電機 運動來完成。
(1)小車直立控制:使用小車傾角PD(比例、微分)控制;


g_fAngleControlOut =              g_fCarAngle * g_fCarAngle_P + \

gyro[0] * g_fCarAngle_D ;

(2)小車速度控制:使PD(比例、微分)控制;

g_fSpeedControlOutNew = (CAR_SPEED_SET - g_fCarSpeed) *

g_fCarSpeed_P +\

(CAR_POSITION_SET - g_fCarPosition) * g_fCarSpeed_I;

(3)小車方向控制:使PD(比例、微分)控制。

speednow=-speedtarget*3.4 -gyro[2]*0.0015 ;

可通過單片機軟件實現(xiàn)上述控制算法。 在上面控制過程車模的角度控制和方向控制都是直接將輸出電壓 疊加后控制電機的轉速實現(xiàn)。而車模的速度控制本質上是通過調節(jié) 車模的傾角實現(xiàn),由于車模是一個非最小相位系統(tǒng)因此該反饋控 制如果比例和速度過大,很容易形成正反饋,使得車模失控,造成系 統(tǒng)的不穩(wěn)定性。因此速度的調節(jié)過程需要非常緩慢和平滑。

六、PID 算法




6
控制相關的軟件函數(shù)包括:
1.AngleCalculate小車傾角計算函數(shù)
。根據(jù)采集到的陀螺儀和重力加速度傳感器的數(shù)值 計算小車角度和角速度。如果這部分的算法由外部一個運放實現(xiàn),那么采集得到的直接是小車的角度和角速度,這部分算法可以省略。該函數(shù)是 5 毫秒調用一次
2.AngelControl小車控制函數(shù)。根據(jù)小車角度和角速度計算小車電機的控制量 立控制是 5 毫秒調用一次。
3.SpeedControl小車度控函數(shù)。根據(jù)小車采集到的電機轉速和速度設定值,計算電 機的控制量。該函數(shù)是 100 毫秒調用一次。
4.SpeedControlOutput速度輸出平滑函數(shù)。由于速度是每 100 毫秒進行一次計算 了使得速度控制更加平滑,該函數(shù)將速度輸出變化量平均分配到 20 5 毫秒的控制周期中。
5.DirectionControlOutput向控函數(shù)輸出平滑函數(shù)。將方向控制的輸出變化量平 均分配到 2 5 毫秒的控制周期中。
6.MotorOutput電機輸出量匯集函數(shù)。根據(jù)前面的控制、向控所得 到的控制量進行疊加分別得到左右兩個電極的輸出電壓控制量。對疊加后的輸出量進行飽
和處理。函數(shù)調用周期 5 毫秒。在此請大家注意速度控制量疊加的極性是負。
7.MotorSpeedOut:電機 PWM 輸出計算函數(shù)。根據(jù)左右兩個電極的輸出控制量的正負 極性,疊加上一個小的死區(qū)數(shù)值,克服車模機械靜態(tài)摩擦力。函數(shù)調用周期 5 毫秒。
8.SetMotorVoltagePWM 輸出函數(shù):根據(jù)兩個電機的輸出量,計算出 PWM 控制寄存 器的數(shù)值,設置四個 PWM 控制寄存器的數(shù)值。函數(shù)調用周期 1 毫秒。
以上 9 個函數(shù)都是在 1 毫秒中斷服務中進行被相互調用的下圖顯示了這些函數(shù)之間的調用
與參數(shù)傳遞關系。在個函數(shù)附近也表明了調用的周期。
9.Chaoshengbo加入超聲波壁障模塊:根據(jù)前方障礙物的距離檢測,一旦檢測到后, 通過直接 PWM 值輸 g_fchaoshengbooutput相障礙物反方上運動,無需算法實現(xiàn)。
30 毫秒調用一次。



7


(注以上函數(shù)框圖為未添加旋轉及超,添加方法與融合速度方式一樣)


七、程序(只給出一部分內容)

1 時序總算法

1

單片機源程序如下:
  1. #include "upstandingcar.h"
  2. #include "I2C_MPU6050.h"
  3. #include "MOTOR.h"
  4. #include "led.h"
  5. #include "USART.H"
  6. #include "MPU6050.H"
  7. #include "UltrasonicWave.h"
  8. #include "stm32f10x_gpio.h"
  9. #include "math.h"
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>

  13. /*****************************************/
  14. u8 newLineReceived = 0;
  15. u8 inputString[80] = {0};

  16. u8 ProtocolString[80] = {0};
  17. /*小車運行狀態(tài)枚舉*/
  18. enum{
  19.   enSTOP = 0,
  20.   enRUN,
  21.   enBACK,
  22.   enLEFT,
  23.   enRIGHT,
  24.   enTLEFT,
  25.   enTRIGHT
  26. }enCarState;

  27. #define         run_car     '1'//按鍵前
  28. #define         back_car    '2'//按鍵后
  29. #define         left_car    '3'//按鍵左
  30. #define         right_car   '4'//按鍵右
  31. #define         stop_car    '0'//按鍵停


  32. int g_newcarstate = enSTOP; //  1前2后3左4右0停止


  33. char returntemp[] = "$0,0,0,0,0,0,0,0,0,0,0,0cm,8.2V#";
  34. char piddisplay[50] ="$AP";
  35. char manydisplay[80] ={0};
  36. char updata[80] ={0};


  37. /*****************多數(shù)據(jù)************************/

  38. u8 BST_u8MainEventCount;                                                  //主循環(huán)判斷計數(shù)  在SysTick_Handler(void)中使用 每1ms加1
  39. u8 BST_u8SpeedControlCount;                                                  //速度控制循環(huán)計數(shù)  在SysTick_Handler(void)中使用 每5ms加1
  40. u8 BST_u8SpeedControlPeriod;
  41. u8 BST_u8DirectionControlPeriod;
  42. u8 BST_u8DirectionControlCount;                                          //轉向控制循環(huán)計數(shù)  在SysTick_Handler(void)中使用 每5ms加1
  43. u8 BST_u8trig;
  44. u8 ucBluetoothValue;                      //藍牙接收數(shù)據(jù)
  45. float volt = 12.0;



  46. /******電機控制參數(shù)******/
  47. float BST_fSpeedControlOut;                                                   //速度控制PWM
  48. float BST_fSpeedControlOutOld;
  49. float BST_fSpeedControlOutNew;
  50. float BST_fAngleControlOut;
  51. float BST_fLeftMotorOut;
  52. float BST_fRightMotorOut;

  53. float BST_fCarAngle;                                                 //角度控制PWM
  54. float gyro_z;
  55. float gyrx;
  56. float gy0;

  57. /*-----角度環(huán)和速度環(huán)PID控制參數(shù)-----*///以下參考為重點調試參考,同電池電壓有關,建議充好電再調試
  58. float  BST_fCarAngle_P =91.3;//        91.3 //調大小時會左右擺,調大時會振動  請調到基本能夠站立 P=91.3是用于給小車在運動過程使用
  59. float  BST_fCarAngle_D =0.21;        // 0.001 0.002 0.004 0.008 0.0010 0.011         調小時反應慢,調大時會干擾

  60. float  BST_fCarSpeed_P=5.1;
  61. float  BST_fCarSpeed_I=0.10;

  62. const double PID_Original[4] ={91.3, 0.21, 5.1, 0.10};
  63. char  alldata[80];
  64. char *iap;

  65. /******速度控制參數(shù)******/
  66. s16   BST_s16LeftMotorPulse;                                          //左電機脈沖數(shù)
  67. s16          BST_s16RightMotorPulse;                                           //右電機脈沖數(shù)

  68. s32   BST_s32LeftMotorPulseOld;
  69. s32   BST_s32RightMotorPulseOld;
  70. s32   BST_s32LeftMotorPulseSigma;                                  //50ms左電機疊加值
  71. s32   BST_s32RightMotorPulseSigma;                                 //50ms右電機疊加值

  72. float BST_fCarSpeed;                                                         //測速碼盤得出的車速
  73. float BST_fCarSpeedOld;

  74. float BST_fCarPosition;                                                   //測速碼盤通過計算得到的小車位移

  75. /*-----懸停參數(shù)-----*/
  76. int leftstop=0;
  77. int rightstop=0;
  78. int stopflag=0;

  79. /******超聲波********/

  80. float fchaoshengbo = 0;                                                           //超聲波輸出量
  81. float juli = 0;                                                                         //超聲波距離

  82. /******藍牙控制參數(shù)******/                                                                                                                                       
  83. float BST_fBluetoothSpeed;                                                //藍牙控制車速
  84. float BST_fBluetoothDirectionNew;                            //用于平緩輸出車速使用
  85. float BST_fBluetoothDirectionSL;                            //左轉標志位  由于PWM轉向輸出使用判斷輸出方式 固需要標志位
  86. float BST_fBluetoothDirectionSR;                           //右轉標志位          由于PWM轉向輸出使用判斷輸出方式 固需要標志位
  87. int chaoflag=0;
  88. int x,y1,z1,y2,z2,flagbt;
  89. int g_autoup = 0;
  90. int g_uptimes = 5000;  //自動上報間隔
  91. char charkp[10],charkd[10],charksp[10],charksi[10];
  92. char lspeed[10],rspeed[10],daccel[10],dgyro[10],csb[10],vi[10];
  93. char kp,kd,ksp,ksi;
  94. float dac = 0,dgy = 0;


  95. /************旋轉*****************/
  96. float BST_fBluetoothDirectionL;                                   //左旋轉標志位  由于PWM旋轉輸出使用判斷輸出方式 固需要標志位
  97. float BST_fBluetoothDirectionR;                                   //右旋轉標志位  由于PWM旋轉輸出使用判斷輸出方式 固需要標志位
  98. int driectionxco=800;


  99. //******卡爾曼參數(shù)************
  100.                
  101. float  Q_angle=0.001;  
  102. float  Q_gyro=0.003;
  103. float  R_angle=0.5;
  104. float  dt=0.005;                          //dt為kalman濾波器采樣時間;
  105. char   C_0 = 1;
  106. float  Q_bias, Angle_err;
  107. float  PCt_0=0, PCt_1=0, E=0;
  108. float  K_0=0, K_1=0, t_0=0, t_1=0;
  109. float  Pdot[4] ={0,0,0,0};
  110. float  PP[2][2] = { { 1, 0 },{ 0, 1 } };


  111. void SendAutoUp(void);

  112. /**********延時子函數(shù)****************/
  113. void delay_nms(u16 time)
  114. {   
  115.    u16 i=0;  
  116.    while(time--)
  117.    {
  118.       i=12000;  //自己定義
  119.       while(i--) ;   
  120.    }
  121. }
  122. /***********************************/


  123. /***************************************************************
  124. ** 函數(shù)名稱: CarUpstandInit
  125. ** 功能描述: 全局變量初始化函數(shù)

  126. ***************************************************************/
  127. void CarUpstandInit(void)
  128. {
  129.         
  130.         
  131.         BST_s16LeftMotorPulse = BST_s16RightMotorPulse = 0;                                          //左右脈沖值   初始化
  132.         BST_s32LeftMotorPulseSigma = BST_s32RightMotorPulseSigma = 0;                  //疊加脈沖數(shù)         初始化

  133.         BST_fCarSpeed = BST_fCarSpeedOld = 0;                                                                   //平衡小車車速        初始化
  134.         BST_fCarPosition = 0;                                                                                                  //平衡小車位移量        初始化
  135.         BST_fCarAngle    = 0;                                                                                                  //平衡小車車速        初始化

  136.         BST_fAngleControlOut = BST_fSpeedControlOut = BST_fBluetoothDirectionNew = 0;        //角度PWM、車速PWM、藍牙控制PWM         初始化
  137.         BST_fLeftMotorOut    = BST_fRightMotorOut   = 0;                                                                //左右車輪PWM輸出值                          初始化
  138.         BST_fBluetoothSpeed  = 0;                                                                                                                //藍牙控制車速值                 初始化
  139.         BST_fBluetoothDirectionL =BST_fBluetoothDirectionR= 0;                                                    //藍牙控制左右旋轉標志位         初始化
  140.         BST_fBluetoothDirectionSL =BST_fBluetoothDirectionSR= 0;                                                //藍牙控制左右轉向標志位         初始化
  141.         
  142.     BST_u8MainEventCount=0;                                                                                                                        //用于5ms定時器子程序SysTick_Handler(void)中總中斷計數(shù)位
  143.         BST_u8SpeedControlCount=0;                                                                                                                //用于5ms定時器子程序SysTick_Handler(void)中50ms速度平衡融入計數(shù)位
  144.     BST_u8SpeedControlPeriod=0;                                                                                                                //用于5ms定時器子程序SysTick_Handler(void)中50ms速度平衡融入計數(shù)位

  145.         fchaoshengbo=0;                                                                                        //用于5ms定時器子程序SysTick_Handler(void)中超聲波平衡融入計數(shù)位
  146.   
  147.         

  148. }

  149. void ResetPID()
  150. {        
  151.         if(BST_fCarAngle_P != PID_Original[0])
  152.         {
  153.                 BST_fCarAngle_P = PID_Original[0];
  154.         }
  155.         if(BST_fCarAngle_D != PID_Original[1])
  156.         {
  157.                 BST_fCarAngle_D = PID_Original[1];
  158.         }
  159.         if(BST_fCarSpeed_P != PID_Original[2])
  160.         {
  161.                 BST_fCarSpeed_P = PID_Original[2];
  162.         }
  163.         if(BST_fCarSpeed_I != PID_Original[3])
  164.         {
  165.                 BST_fCarSpeed_I = PID_Original[3];
  166.         }

  167. }        

  168. /***************************************************************
  169. ** 函數(shù)名稱: AngleControl
  170. ** 功能描述: 角度環(huán)控制函數(shù)

  171. ***************************************************************/
  172. void AngleControl(void)         
  173. {
  174.         if(flagbt==1)
  175.         {
  176.                 BST_fCarAngle_P=0;
  177.                 BST_fCarAngle_P=y1*1.71875;
  178.         }
  179.                 if(flagbt==2)
  180.         {
  181.                 BST_fCarAngle_D=0;
  182.                 BST_fCarAngle_D=(z1-64)*0.15625;
  183.         }
  184.         dac=accel[2];
  185.         dgy=gyro[2];
  186.         
  187.         BST_fCarAngle = Roll - CAR_ZERO_ANGLE;                                                                                                           //DMP ROLL滾動方向角度與預設小車傾斜角度值的差得出角度   
  188.         BST_fAngleControlOut =  BST_fCarAngle * BST_fCarAngle_P + gyro[0] * BST_fCarAngle_D ;          //角度PD控制                                                           
  189. }

  190. /***************************************************************
  191. ** 函數(shù)名稱: SetMotorVoltageAndDirection
  192. ** 功能描述: 電機轉速            

  193. ***************************************************************/
  194. void SetMotorVoltageAndDirection(s16 s16LeftVoltage,s16 s16RightVoltage)
  195. {
  196.           u16 u16LeftMotorValue;
  197.           u16 u16RightMotorValue;
  198.         
  199.     if(s16LeftVoltage<0)                                                                                 //當左電機PWM輸出為負時 PB14設為正 PB15設為負 (PB14 15 分別控制TB6612fng驅動芯片,邏輯0 1可控制左電機正轉反轉)
  200.     {        
  201.             GPIO_SetBits(GPIOB, GPIO_Pin_14 );                                    
  202.       GPIO_ResetBits(GPIOB, GPIO_Pin_15 );
  203.       s16LeftVoltage = (-s16LeftVoltage);
  204.     }
  205.     else
  206.     {        
  207.       GPIO_SetBits(GPIOB, GPIO_Pin_15 );                                             //當左電機PWM輸出為正時 PB14設為負 PB15設為正 (PB14 15 分別控制TB6612fng驅動芯片,邏輯0 1可控制左電機正轉反轉)
  208.       GPIO_ResetBits(GPIOB, GPIO_Pin_14 );
  209.       s16LeftVoltage = s16LeftVoltage;
  210.     }

  211.     if(s16RightVoltage<0)
  212.     {                                                                                                                         //當右電機PWM輸出為負時 PB12設為正 PB13設為負 (PB12 13 分別控制TB6612fng驅動芯片,邏輯0 1可控制左電機正轉反轉)
  213.       GPIO_SetBits(GPIOB, GPIO_Pin_13 );                                    
  214.       GPIO_ResetBits(GPIOB, GPIO_Pin_12 );
  215.       s16RightVoltage = (-s16RightVoltage);
  216.     }
  217.     else                                                                                                                //當右電機PWM輸出為正時 PB12設為負 PB13設為正 (PB12 13 分別控制TB6612fng驅動芯片,邏輯0 1可控制左電機正轉反轉)
  218.     {
  219.             GPIO_SetBits(GPIOB, GPIO_Pin_12 );                                    
  220.       GPIO_ResetBits(GPIOB, GPIO_Pin_13 );        
  221.      
  222.       s16RightVoltage = s16RightVoltage;
  223.     }
  224.                
  225.            u16RightMotorValue= (u16)s16RightVoltage;
  226.            u16LeftMotorValue = (u16)s16LeftVoltage;


  227.         TIM_SetCompare3(TIM2,u16LeftMotorValue);                          //TIM2與 u16RightMotorValue對比,不相同則翻轉波形,調節(jié)PWM占空比
  228.         TIM_SetCompare4(TIM2,u16RightMotorValue);                          //TIM3與 u16LeftMotorValue對比,不相同則翻轉波形,調節(jié)PWM占空比

  229. #if 1         /*判斷車輛 是否懸停或跌倒,調試用*/
  230.                
  231.   if(Pitch>10||Pitch<-10&BST_fBluetoothDirectionSR==0&BST_fBluetoothDirectionSL==0)
  232.         {               
  233.                 TIM_SetCompare3(TIM2,0);
  234.                 TIM_SetCompare4(TIM2,0);
  235.                 stopflag=1;               
  236.         }
  237.         else stopflag=0;
  238.         
  239.         if(BST_fCarAngle > 50 || BST_fCarAngle < (-50))
  240.         {
  241.                 TIM_SetCompare3(TIM2,0);
  242.                 TIM_SetCompare4(TIM2,0);  
  243.                 stopflag=1;        
  244.         }
  245.         else stopflag=0;

  246. #endif
  247. }

  248. /***************************************************************
  249. ** 函數(shù)名稱: MotorOutput
  250. ** 功能描述: 電機輸出函數(shù)
  251.              將直立控制、速度控制、方向控制的輸出量進行疊加,并加
  252.                          入死區(qū)常量,對輸出飽和作出處理。

  253. ***************************************************************/
  254. void MotorOutput(void)                                                                                                                                                                          //電機PWM輸出函數(shù)
  255. {           
  256.                         //右電機轉向PWM控制融合平衡角度、速度輸出

  257.         BST_fLeftMotorOut  = BST_fAngleControlOut +BST_fSpeedControlOutNew + BST_fBluetoothDirectionNew;//+directionl - BST_fBluetoothDirectionNew;                        //左電機轉向PWM控制融合平衡角度、速度輸出        
  258.     BST_fRightMotorOut = BST_fAngleControlOut +BST_fSpeedControlOutNew - BST_fBluetoothDirectionNew;//-directionl+ BST_fBluetoothDirectionNew;                        //右電機轉向PWM控制融合平衡角度、速度輸出

  259.                
  260.         if((s16)BST_fLeftMotorOut  > MOTOR_OUT_MAX)        BST_fLeftMotorOut  = MOTOR_OUT_MAX;
  261.         if((s16)BST_fLeftMotorOut  < MOTOR_OUT_MIN)        BST_fLeftMotorOut  = MOTOR_OUT_MIN;
  262.         if((s16)BST_fRightMotorOut > MOTOR_OUT_MAX)        BST_fRightMotorOut = MOTOR_OUT_MAX;
  263.         if((s16)BST_fRightMotorOut < MOTOR_OUT_MIN)        BST_fRightMotorOut = MOTOR_OUT_MIN;
  264.         
  265.     SetMotorVoltageAndDirection((s16)BST_fLeftMotorOut,(s16)BST_fRightMotorOut);
  266.    
  267. }

  268. void GetMotorPulse(void)              //采集電機速度脈沖
  269. {
  270.         //////////////////////////////////此部分為外部中斷計算脈沖/////////////////////////////////////
  271.         uint16_t u16TempLeft;
  272.   uint16_t u16TempRight;
  273.         
  274.   u16TempLeft = TIM_GetCounter(TIM3);   //  TIM3定時器計算調用
  275.   u16TempRight= TIM_GetCounter(TIM4);        //         TIM4定時器計算調用
  276.         leftstop=u16TempLeft;
  277.         rightstop=u16TempRight;
  278.   TIM_SetCounter(TIM3,0);//TIM3->CNT = 0;
  279.   TIM_SetCounter(TIM4,0);//TIM4->CNT = 0;   //清零
  280.         BST_s16LeftMotorPulse=u16TempLeft;
  281.   BST_s16RightMotorPulse=(-u16TempRight);
  282.                
  283.   BST_s32LeftMotorPulseSigma  +=BST_s16LeftMotorPulse;                 //脈沖值疊加 40ms疊加值
  284.   BST_s32RightMotorPulseSigma +=BST_s16RightMotorPulse;          //脈沖值疊加 40ms疊加值
  285. }
  286. /***************************************************************
  287. ** 函數(shù)名稱: SpeedControl
  288. ** 功能描述: 速度環(huán)控制函數(shù)
  289. ***************************************************************/

  290. void SpeedControl(void)
  291. {
  292.   

  293.         BST_fCarSpeed = (BST_s32LeftMotorPulseSigma  + BST_s32RightMotorPulseSigma );// * 0.5 ;                  //左右電機脈沖數(shù)平均值作為小車當前車速
  294.         BST_s32LeftMotorPulseSigma =BST_s32RightMotorPulseSigma = 0;          //全局變量 注意及時清零               
  295.         BST_fCarSpeedOld *= 0.7;
  296.         BST_fCarSpeedOld +=BST_fCarSpeed*0.3;
  297.         
  298.         BST_fCarPosition += BST_fCarSpeedOld;                  //路程  即速度積分           1/11 3:03
  299.         BST_fCarPosition += BST_fBluetoothSpeed;   //融合藍牙給定速度
  300.         BST_fCarPosition +=        fchaoshengbo;                   //融合超聲波給定速度
  301.         if(stopflag==1)
  302.         {
  303.                 BST_fCarPosition=0;
  304.                
  305.         }
  306.         

  307.         //積分上限設限//
  308.         if((s32)BST_fCarPosition > CAR_POSITION_MAX)    BST_fCarPosition = CAR_POSITION_MAX;
  309.         if((s32)BST_fCarPosition < CAR_POSITION_MIN)    BST_fCarPosition = CAR_POSITION_MIN;
  310.         
  311.                 if(flagbt==3)
  312.         {
  313.                 BST_fCarSpeed_P=0;
  314.                 BST_fCarSpeed_P=(y2-128)*0.46875;
  315.         }
  316.                 if(flagbt==4)
  317.         {
  318.                 BST_fCarSpeed_I=0;
  319.                 BST_fCarSpeed_I=(z2-192)*0.15625;
  320.         }
  321.         

  322.                                                                                                                                                                                                   
  323.         BST_fSpeedControlOutNew = (BST_fCarSpeedOld -CAR_SPEED_SET ) * BST_fCarSpeed_P + (BST_fCarPosition - CAR_POSITION_SET ) * BST_fCarSpeed_I; //速度PI算法 速度*P +位移*I=速度PWM輸出

  324.         
  325. }



  326. /***************************************************************
  327. ** 函數(shù)名稱: BluetoothControl
  328. ** 功能描述: 藍牙控制函數(shù)
  329.              手機發(fā)送內容
  330.                          前:0x01    后:0x02
  331.              左:0x04    右:0x03
  332.              停止:0x07
  333.              功能鍵:(旋轉)
  334.              左旋轉:0x05      右旋轉:0x06
  335.                     停轉:0x07
  336. ** 輸 入:   
  337. ** 輸 出:   
  338.                   switch (x)
  339.                 {
  340.                         case 0x00 : BST_fCarAngle_P=BST_fCarAngle_D=BST_fCarSpeed_P=BST_fCarSpeed_I=0;
  341.                         case 0x01 : BST_fBluetoothSpeed =   3000 ;chaoflag=1; break;           //向前速度 250
  342.                         case 0x02 : BST_fBluetoothSpeed = (-3000);chaoflag=1;  break;           //后退速度 -250
  343.                         case 0x03 : BST_fBluetoothDirectionNew= -300; chaoflag=1;break ;//左旋
  344.                         case 0x04 : BST_fBluetoothDirectionNew= 300; chaoflag=1;break ;//右旋轉
  345.                         case 0x05 : BST_fBluetoothDirectionNew= driectionxco; chaoflag=1;break ;//左旋
  346.                         case 0x06 : BST_fBluetoothDirectionNew= -driectionxco; chaoflag=1;break ;//右旋轉
  347.                         case 0x07 : BST_fBluetoothDirectionL  =0; BST_fBluetoothDirectionR = 0; BST_fBluetoothDirectionSL =0; BST_fBluetoothDirectionSR = 0;fchaoshengbo=0;BST_fBluetoothDirectionNew=0;chaoflag=0;   break; //停
  348.                         case 0x08 : BST_fBluetoothDirectionSL =0; BST_fBluetoothDirectionSR = 0; fchaoshengbo=0;BST_fBluetoothDirectionNew=0;chaoflag=0;break; //停旋轉
  349.                         case 0x09 : BST_fBluetoothSpeed =   0 ;  break;
  350.                 case 0x0A : flagbt=1;break;
  351.                 case 0x0B : flagbt=2;break;
  352.                 case 0x0C : flagbt=3;break;
  353.                 case 0x0D : flagbt=4;break;                                 
  354.                         default : BST_fBluetoothSpeed = 0;flagbt=0; BST_fBluetoothDirectionL=BST_fBluetoothDirectionR = 0;BST_fBluetoothDirectionSR=BST_fBluetoothDirectionSL=0;chaoflag=0;break;        
  355.                 }

  356. ***************************************************************/
  357. int num = 0;
  358. u8 startBit = 0;
  359. int int9num =0;

  360. void USART3_IRQHandler(void)
  361. {  
  362.         u8 uartvalue = 0;

  363.         if (USART_GetFlagStatus(USART3, USART_FLAG_ORE) != RESET)//注意!不能使用if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)來判斷  
  364.     {  
  365.                 USART_ClearFlag(USART3, USART_FLAG_ORE); //讀SR其實就是清除標志
  366.                USART_ReceiveData(USART3);                  
  367.     }
  368.                
  369.         if(USART_GetFlagStatus(USART3,USART_FLAG_RXNE)!=RESET)
  370.         {
  371.             USART_ClearITPendingBit(USART3, USART_IT_RXNE);

  372.                 uartvalue = USART3->DR;
  373.             if(uartvalue == '
  374. )
  375.             {
  376.                       startBit = 1;
  377.                     num = 0;
  378.             }
  379.             if(startBit == 1)
  380.             {
  381.                        inputString[num] = uartvalue;     
  382.             }  
  383.             if (startBit == 1 && uartvalue == '#')
  384.             {
  385.                     
  386.                         newLineReceived = 1;
  387.                         startBit = 0;
  388.                         int9num = num;        
  389.                
  390.             }
  391.                 num++;
  392.                 if(num >= 80)
  393.                 {
  394.                         num = 0;
  395.                         startBit = 0;
  396.                         newLineReceived        = 0;
  397.                 }         
  398.         
  399.         }
  400.         

  401. }         


  402. /**********************超聲波距離計算***************************/
  403. void chaoshengbo(void)
  404. {  
  405.         if(chaoflag==0)
  406.         {
  407.         
  408.               juli=TIM_GetCounter(TIM1)*5*34/200.0;
  409.                
  410.             if(juli <= 4.00)                                                                  //判斷若距離小于8cm,小車輸出向后PWM值。
  411.                 {
  412.                     fchaoshengbo= (-300);
  413.             }
  414.                 else if(juli >= 5 & juli <= 8)
  415.                 {
  416.                         fchaoshengbo=500;
  417.                 }
  418.             else
  419.                 {
  420.                         fchaoshengbo=0;                                                 //距離大于8cm ,超聲波PWM輸出為0
  421.              }
  422.           }
  423.         
  424.         //寄生此上報數(shù)據(jù)
  425.         //增加自動上報  10ms進一次,故10*50ms = 500ms
  426.     //SendAutoUp();
  427. }

  428. /*計算上報的數(shù)據(jù)*/
  429. void CalcUpData()
  430. {
  431.         float ls, rs, sLence;
  432.         short s_Acc, s_Gyro;

  433.         
  434.         if(g_autoup == 1)
  435.         {
  436.                 //CLI();
  437.                 ls = BST_fLeftMotorOut;
  438.                 rs = BST_fRightMotorOut;
  439.                 s_Acc = accel[1];
  440.                 s_Gyro = gyro[0];
  441.                 sLence = juli;
  442.                 //SEI();
  443.                
  444.                 dac=(s_Acc/16384.0f)*9.8f;
  445.                 dgy=((s_Gyro-128.1f)/131.0f);
  446.                
  447.                 ls=ls/3.91;
  448.                 rs=rs/3.91;
  449.         
  450.                 memset(manydisplay, 0x00, 80);
  451.                 memcpy(manydisplay, "$LV", 4);
  452.         
  453.                 memset(lspeed, 0x00, sizeof(lspeed));
  454.                 memset(rspeed, 0x00, sizeof(rspeed));
  455.                 memset(daccel, 0x00, sizeof(daccel));
  456.                 memset(dgyro, 0x00, sizeof(dgyro));
  457.                 memset(csb, 0x00, sizeof(csb));
  458.                 memset(vi, 0x00, sizeof(vi));
  459.         
  460.                 if((ls <= 1000) && (ls >= -1000))
  461.                         sprintf(lspeed,"%3.2f",ls);
  462.                 else
  463.                 {
  464.                         //sprintf(str,"$AutoUpError!ls=%3.2f#",ls);
  465.                         //UART3_Send_Char(str); //返回協(xié)議數(shù)據(jù)包        
  466.                         return;
  467.                 }
  468.                         
  469.                
  470.                 if((rs <= 1000) && (rs >= -1000))
  471.                         sprintf(rspeed,"%3.2f",rs);
  472.                 else
  473.                 {
  474.                         //sprintf(str,"$AutoUpError!rs=%3.2f#",rs);
  475.                         //UART3_Send_Char(str); //返回協(xié)議數(shù)據(jù)包        
  476.                         return;
  477.                 }
  478.                
  479.                 if((dac > -20) && (dac < 20))
  480.                         sprintf(daccel,"%3.2f",dac);
  481.                 else
  482.                 {
  483.                         //sprintf(str,"$AutoUpError!dac=%3.2f#",dac);
  484.                         //UART3_Send_Char(str); //返回協(xié)議數(shù)據(jù)包        
  485.                         return;
  486.                 }
  487.                
  488.                 if((dgy > -3000) && (dgy < 3000))
  489.                         sprintf(dgyro,"%3.2f",dgy);
  490.                 else
  491.                 {
  492.                         //sprintf(str,"$AutoUpError!dgy=%3.2f#",dgy);
  493.                         //UART3_Send_Char(str); //返回協(xié)議數(shù)據(jù)包        
  494.                         return;
  495.                 }
  496.         
  497.                 if((sLence >= 0) && (sLence < 10000))
  498.                         sprintf(csb,"%3.2f",sLence);
  499.                 else
  500.                 {
  501.                         //sprintf(str,"$AutoUpError!juli=%3.2f#",juli);
  502.                         //UART3_Send_Char(str); //返回協(xié)議數(shù)據(jù)包        
  503.                         return;
  504.                 }
  505.         
  506.                 if((volt >= 0) && (volt < 20))
  507.                         sprintf(vi,"%3.2f",volt);
  508.                 else
  509.                 {
  510.                         //sprintf(str,"$AutoUpError!volt=%3.2f#",volt);
  511.                         //UART3_Send_Char(str); //返回協(xié)議數(shù)據(jù)包        
  512.                         return;
  513.                 }
  514.         
  515.                 strcat(manydisplay,lspeed);
  516.                 strcat(manydisplay,",RV");
  517.                 strcat(manydisplay,rspeed);
  518.                 strcat(manydisplay,",AC");
  519.                 strcat(manydisplay,daccel);
  520.                 strcat(manydisplay,",GY");
  521.                 strcat(manydisplay,dgyro);
  522.                 strcat(manydisplay,",CSB");
  523.                 strcat(manydisplay,csb);
  524.                 strcat(manydisplay,",VT");
  525.                 strcat(manydisplay,vi);
  526.                 strcat(manydisplay,"#");
  527.                 memset(updata, 0x00, 80);
  528.                 memcpy(updata, manydisplay, 80);
  529.         }
  530.         
  531. }

  532. /*
  533. 自動上報
  534. */
  535. void SendAutoUp(void)
  536. {
  537.         g_uptimes --;
  538.         if ((g_autoup == 1) && (g_uptimes == 0))
  539.         {
  540.                 CalcUpData();
  541.                 UART3_Send_Char(updata); //返回協(xié)議數(shù)據(jù)包        
  542.         }
  543.         if(g_uptimes == 0)
  544.                  g_uptimes = 5000;

  545. }

  546. int StringFind(const char *pSrc, const char *pDst)  
  547. {  
  548.     int i, j;  
  549.     for (i=0; pSrc[i]!='\0'; i++)  
  550.     {  
  551.         if(pSrc[i]!=pDst[0])  
  552.             continue;         
  553.         j = 0;  
  554.         while(pDst[j]!='\0' && pSrc[i+j]!='\0')  
  555.         {  
  556.             j++;  
  557.             if(pDst[j]!=pSrc[i+j])  
  558.             break;  
  559.         }  
  560.         if(pDst[j]=='\0')  
  561.             return i;  
  562.     }  
  563.     return -1;  
  564. }  

  565. void CarStateOut(void)
  566. {
  567.         switch (g_newcarstate)
  568.         {
  569.                 case enSTOP: //停止
  570.                 {

  571.                         BST_fBluetoothSpeed = 0;
  572.                         fchaoshengbo=0;
  573.                         BST_fBluetoothDirectionNew=0;
  574.                         chaoflag=0;

  575.                 } break;                                            

  576.                 case enRUN: //向前速度 800
  577.                 {
  578.                         BST_fBluetoothDirectionNew= 0;         
  579.                         //BST_fSpeedControlOutNew=0;
  580.                         BST_fBluetoothSpeed =  800 ;
  581.                         chaoflag=1;

  582.                 }break;           

  583.                 case enLEFT://左轉
  584.                 {

  585.                         BST_fBluetoothDirectionNew= -300;
  586.                         chaoflag=1;

  587.                 }break;   
  588.                
  589.                 case enRIGHT: //右轉
  590.                 {

  591.                         BST_fBluetoothDirectionNew= 300;
  592.                         chaoflag=1;

  593.                 }break;        
  594.                
  595.                 case enBACK: //后退速度 -800
  596.                 {
  597.                         BST_fBluetoothDirectionNew= 0;
  598.                         //BST_fSpeedControlOutNew=0;                        
  599.                         BST_fBluetoothSpeed = (-800);
  600.                         chaoflag=1;  

  601.                 }break;
  602.                
  603.                 case enTLEFT: //左旋
  604.                 {
  605.                         BST_fBluetoothDirectionNew = -driectionxco;
  606.                         chaoflag=1;

  607.                 }break;
  608.                 case enTRIGHT: //右旋
  609.                 {
  610.                         BST_fBluetoothDirectionNew = driectionxco;
  611.                         chaoflag=1;
  612.                 }break;
  613.                
  614.                 default: BST_fBluetoothSpeed = 0; break;                                            //停止
  615.         }
  616. }

  617. void ProtocolGetPID(void)
  618. {
  619.         memset(piddisplay, 0x00, sizeof(piddisplay));
  620.         memcpy(piddisplay, "$AP", 4);

  621.         if(BST_fCarAngle_P >= 0 && BST_fCarAngle_P <= 100)
  622.         {
  623.                 sprintf(charkp,"%3.2f",BST_fCarAngle_P);
  624.         }
  625.         else
  626.         {        
  627.                 UART3_Send_Char("$GetPIDError#"); //返回協(xié)議數(shù)據(jù)包
  628.                 return;
  629.         }

  630.         
  631.         if(BST_fCarAngle_D >= 0 && BST_fCarAngle_D <= 100)
  632.         {
  633.                 sprintf(charkd,"%3.2f",BST_fCarAngle_D);
  634.         }
  635.         else
  636.         {        
  637.                 UART3_Send_Char("$GetPIDError#"); //返回協(xié)議數(shù)據(jù)包
  638.                 return;
  639.         }
  640.         
  641.         if(BST_fCarSpeed_P >= 0 && BST_fCarSpeed_P <= 100)
  642.         {
  643.                 sprintf(charksp,"%3.2f",BST_fCarSpeed_P);
  644.         }
  645.         else
  646.         {        
  647.                 UART3_Send_Char("$GetPIDError#"); //返回協(xié)議數(shù)據(jù)包
  648.                 return;
  649.         }

  650.         if(BST_fCarSpeed_I >= 0 && BST_fCarSpeed_I <= 100)
  651.         {
  652.                 sprintf(charksi,"%3.2f",BST_fCarSpeed_I);
  653.         }
  654.         else
  655.         {        
  656.                 UART3_Send_Char("$GetPIDError#"); //返回協(xié)議數(shù)據(jù)包
  657.                 return;
  658.         }
  659.         
  660.         
  661.         strcat(piddisplay,charkp);
  662.         strcat(piddisplay,",AD");
  663.         strcat(piddisplay,charkd);
  664.         strcat(piddisplay,",VP");
  665.         strcat(piddisplay,charksp);
  666.         strcat(piddisplay,",VI");
  667.         strcat(piddisplay,charksi);
  668.         strcat(piddisplay,"#");
  669.         
  670.         UART3_Send_Char(piddisplay); //返回協(xié)議數(shù)據(jù)包

  671. }

  672. void ProtocolCpyData(void)
  673. {
  674.         memcpy(ProtocolString, inputString, num+1);
  675.         memset(inputString, 0x00, sizeof(inputString));
  676. }
  677. /***************************************************************************
  678. 串口協(xié)議數(shù)據(jù)解析
  679. ***************************************************************************/
  680. void Protocol(void)
  681. {
  682.         //USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);//禁能接收中斷

  683.         //判斷數(shù)據(jù)包有效性

  684.                
  685.         
  686.         switch (ProtocolString[1])
  687.         {
  688.                 case run_car:         g_newcarstate = enRUN; UART3_Send_Char(returntemp);break;
  689.                 case back_car:  g_newcarstate = enBACK; UART3_Send_Char(returntemp);break;
  690.                 case left_car:  g_newcarstate = enLEFT; UART3_Send_Char(returntemp);break;
  691.                 case right_car: g_newcarstate = enRIGHT; UART3_Send_Char(returntemp);break;
  692.                 case stop_car:  g_newcarstate = enSTOP; UART3_Send_Char(returntemp);break;
  693.                 default: g_newcarstate = enSTOP; break;
  694.                
  695.         }

  696.         /*防止數(shù)據(jù)丟包*/
  697.         if(strlen((const char *)ProtocolString)<21)
  698.         {
  699.                 newLineReceived = 0;  
  700.                 memset(ProtocolString, 0x00, sizeof(ProtocolString));  
  701.                 //USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//使能接收中斷
  702.                 UART3_Send_Char("$ReceivePackError#"); //返回協(xié)議數(shù)據(jù)包
  703.                 return;
  704.         }

  705.         if (ProtocolString[3] == '1') //左搖
  706.         {
  707.                 g_newcarstate = enTLEFT;
  708.                 UART3_Send_Char(returntemp); //返回協(xié)議數(shù)據(jù)包         
  709.                
  710.         }
  711.         
  712.         
  713.         if (ProtocolString[3] == '2') //右搖
  714.         {
  715.                 g_newcarstate = enTRIGHT;
  716.                 UART3_Send_Char(returntemp); //返回協(xié)議數(shù)據(jù)包         
  717. ……………………

  718. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
源碼: STM32平衡車.rar (697.14 KB, 下載次數(shù): 1306)
平衡小車原理分析.pdf (622.92 KB, 下載次數(shù): 1081)
STM32總算法流程圖.doc (19.03 KB, 下載次數(shù): 726)





評分

參與人數(shù) 7黑幣 +80 收起 理由
s3587688 + 10 學習到了
51hei用戶2107193 + 10 共享資料的黑幣獎勵!
shenchaobiao + 12 贊一個!
xufumin + 12
1109 + 15 贊一個!
ko44 + 11 共享資料的黑幣獎勵!
songfengyi + 10

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:328014 發(fā)表于 2018-9-20 04:26 | 只看該作者
好資料,51黑有你更精彩!!!
講得比較通俗易懂,很好
補第2個無法下載的文件: 平衡小車原理分析.7z (545.26 KB, 下載次數(shù): 267)
回復

使用道具 舉報

板凳
ID:348697 發(fā)表于 2018-10-13 19:30 | 只看該作者
很不錯,正要學平衡車來著
回復

使用道具 舉報

地板
ID:409435 發(fā)表于 2018-10-14 14:21 | 只看該作者
好資料
回復

使用道具 舉報

5#
ID:400629 發(fā)表于 2018-10-15 10:41 來自手機 | 只看該作者
內容豐富!資料很齊全,謝謝樓主的分享!
回復

使用道具 舉報

6#
ID:315083 發(fā)表于 2019-1-18 21:30 | 只看該作者
頂上,謝謝樓主分享
回復

使用道具 舉報

7#
ID:471436 發(fā)表于 2019-2-19 09:38 | 只看該作者
請問,您自己做出來過嗎?
回復

使用道具 舉報

8#
ID:69072 發(fā)表于 2019-2-19 13:13 | 只看該作者
這種 詳細解釋的 優(yōu)秀帖 非常好
回復

使用道具 舉報

9#
ID:478263 發(fā)表于 2019-2-19 21:05 | 只看該作者
這個資料講的很細
回復

使用道具 舉報

10#
ID:407977 發(fā)表于 2019-3-1 21:25 | 只看該作者
謝謝樓主分享
回復

使用道具 舉報

11#
ID:407977 發(fā)表于 2019-3-1 21:25 | 只看該作者
謝謝樓主分享,小弟正在學習這個。
回復

使用道具 舉報

12#
ID:394789 發(fā)表于 2019-3-6 15:54 | 只看該作者
好資料
回復

使用道具 舉報

13#
ID:380985 發(fā)表于 2019-3-27 23:58 來自手機 | 只看該作者
好資料。。。。
回復

使用道具 舉報

14#
ID:496582 發(fā)表于 2019-4-25 07:03 | 只看該作者
謝謝樓主
回復

使用道具 舉報

15#
ID:536258 發(fā)表于 2019-5-12 16:56 來自手機 | 只看該作者
謝謝分享
回復

使用道具 舉報

16#
ID:72134 發(fā)表于 2019-5-12 18:41 | 只看該作者
有空一定好好研究一下
回復

使用道具 舉報

17#
ID:537504 發(fā)表于 2019-5-13 23:17 | 只看該作者
這個源碼應該用什么軟件打開呢?
回復

使用道具 舉報

18#
ID:302850 發(fā)表于 2019-5-13 23:24 來自手機 | 只看該作者
mark一些,等有金幣了下載!
回復

使用道具 舉報

19#
ID:397503 發(fā)表于 2019-5-28 11:20 | 只看該作者
很棒的資料
回復

使用道具 舉報

20#
ID:260463 發(fā)表于 2019-6-2 09:16 來自手機 | 只看該作者
好資料,講的通俗易懂
回復

使用道具 舉報

21#
ID:560891 發(fā)表于 2019-6-12 14:31 | 只看該作者
不錯,最近在學習,準備做個 小車
回復

使用道具 舉報

22#
ID:574674 發(fā)表于 2019-6-29 17:48 | 只看該作者
謝謝,分享
回復

使用道具 舉報

23#
ID:356717 發(fā)表于 2019-7-3 08:37 | 只看該作者
感謝樓主
回復

使用道具 舉報

24#
ID:486894 發(fā)表于 2019-7-4 19:37 | 只看該作者
下載了顯示資料不存在,這下好了,黑幣不夠了
回復

使用道具 舉報

25#
ID:20345 發(fā)表于 2019-7-4 23:39 | 只看該作者
優(yōu)秀帖 非常好!
回復

使用道具 舉報

26#
ID:282095 發(fā)表于 2019-7-6 22:21 | 只看該作者
感謝分享
回復

使用道具 舉報

27#
ID:82588 發(fā)表于 2019-7-10 22:36 | 只看該作者
分享是一種美德,謝謝
回復

使用道具 舉報

28#
ID:585945 發(fā)表于 2019-7-18 17:26 | 只看該作者
感謝樓主!!資料十分有用
回復

使用道具 舉報

29#
ID:278096 發(fā)表于 2019-7-19 08:18 | 只看該作者
第二個文件下載不了,已經(jīng)浪費我10個黑幣了
回復

使用道具 舉報

30#
ID:511461 發(fā)表于 2019-7-20 17:16 | 只看該作者
為什么資料不存在
回復

使用道具 舉報

31#
ID:560018 發(fā)表于 2019-7-22 15:20 | 只看該作者
感謝分享
回復

使用道具 舉報

32#
ID:482599 發(fā)表于 2019-8-6 19:45 | 只看該作者
謝謝分享
回復

使用道具 舉報

33#
ID:365823 發(fā)表于 2019-9-1 20:59 | 只看該作者
感謝分享
回復

使用道具 舉報

34#
ID:623135 發(fā)表于 2019-10-13 02:59 | 只看該作者
很不錯。。。
回復

使用道具 舉報

35#
ID:142891 發(fā)表于 2019-10-13 10:47 | 只看該作者
原理分析下不了。
回復

使用道具 舉報

36#
ID:65480 發(fā)表于 2019-10-13 15:27 | 只看該作者
謝謝分享!學習一下。
回復

使用道具 舉報

37#
ID:605571 發(fā)表于 2019-10-23 17:27 | 只看該作者
樓主你的平衡小車能急剎車嗎,如果能你是怎么克服慣性的
回復

使用道具 舉報

38#
ID:629247 發(fā)表于 2019-10-25 09:38 | 只看該作者
厲害了,絕對的厲害!
回復

使用道具 舉報

39#
ID:629540 發(fā)表于 2019-11-3 18:02 | 只看該作者
怎么下載鏈接不存在?
回復

使用道具 舉報

40#
ID:516350 發(fā)表于 2019-11-4 14:14 | 只看該作者
剛好在做這個,非常感謝
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表