欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

          標題: 用stc12可以做平衡車嗎?? [打印本頁]

          作者: JACKLI    時間: 2018-3-24 22:38
          標題: 用stc12可以做平衡車嗎??
          我之前用stc12做過,但是一直做不出來,請問你們有沒有做過呢?是不是要用像adunio那樣更高級的單片機才能做出來。能不能分享下經(jīng)驗。

          作者: admin    時間: 2018-3-25 02:49
          這個可以做,我看過別人做的例子
          作者: angmall    時間: 2018-3-25 07:15
          1. /***********************************************************************
          2. // 兩輪自平衡車最終版控制程序(6軸MPU6050+互補濾波+PWM電機)
          3. // 單片機STC12C5A60S2
          4. // 晶振:20M
          5. // 日期:2014.11.26 - ?
          6. ***********************************************************************/

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

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

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

          15. #include "DELAY.H"    //延時頭文件
          16. //--------------------------------------------
          17. #include "STC_ISP.H"    //程序燒錄頭文件
          18. #include "SET_SERIAL.H"//串口頭文件

          19. #include "SET_PWM.H"//PWM頭文件
          20. #include "MOTOR.H"//電機控制頭文件
          21. #include "MPU6050.H"//MPU6050頭文件
          22. //-----------------這些文件---------------------------



          23. //******角度參數(shù)************

          24. float Gyro_y;        //Y軸陀螺儀數(shù)據(jù)暫存

          25. //--------------加速度和角度的轉(zhuǎn)化------------------


          26. float Angle_gy;      //由角速度計算的傾斜角度
          27. //陀螺儀直接反應(yīng)角度

          28. float Accel_x;     //X軸加速度值暫存
          29. float Angle_ax;      //由加速度計算的傾斜角度 、

          30. float Angle;         //小車最終傾斜角度
          31. uchar value; //角度正負極性標記

          32. //******PWM參數(shù)*************

          33. int   speed_mr; //右電機  轉(zhuǎn)速//這個的測量---------轉(zhuǎn)盤
          34. int   speed_ml; //左電機  轉(zhuǎn)速
          35. int   PWM_R;         //右輪PWM值計算
          36. int   PWM_L;         //左輪PWM值計算
          37. float PWM;           //綜合PWM計算
          38. float PWMI; //PWM積分值

          39. //******電機參數(shù)*************

          40. float speed_r_l;//電機轉(zhuǎn)速
          41. float speed;        //電機轉(zhuǎn)速濾波
          42. float position;    //位移

          43. //******藍牙遙控參數(shù)*************
          44. uchar remote_char;
          45. char  turn_need;
          46. char  speed_need;

          47. //*********************************************************
          48. //定時器100Hz數(shù)據(jù)更新中斷 T1定時器
          49. //*********************************************************

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



          60. //*********************************************************
          61. //中斷控制初始化
          62. //*********************************************************

          63. void Init_Interr(void)
          64. {
          65.         EA = 1;     //開總中斷
          66.         EX0 = 1;    //開外部中斷INT0
          67.         EX1 = 1;    //開外部中斷INT1
          68.         IT0 = 1;    //下降沿觸發(fā)
          69.         IT1 = 1;    //下降沿觸發(fā)
          70.         ET1 = 1;    //開定時器1中斷
          71. }



          72. //******卡爾曼參數(shù)************

          73. float code Q_angle=0.001;  
          74. float code Q_gyro=0.003;
          75. float code R_angle=0.5;
          76. float code dt=0.01;                  //dt為kalman濾波器采樣時間;
          77. char  code C_0 = 1;
          78. float xdata Q_bias, Angle_err;
          79. float xdata PCt_0, PCt_1, E;
          80. float xdata K_0, K_1, t_0, t_1;
          81. float xdata Pdot[4] ={0,0,0,0};
          82. float xdata PP[2][2] = { { 1, 0 },{ 0, 1 } };

          83. //*********************************************************
          84. // 卡爾曼濾波
          85. //*********************************************************

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

          87. void Kalman_Filter(float Accel,float Gyro)  // 濾波,輸出標準的方波驅(qū)動電機
          88. {
          89.         Angle+=(Gyro - Q_bias) * dt; //先驗估計陀螺角度


          90.         Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先驗估計誤差協(xié)方差的微分

          91.         Pdot[1]=- PP[1][1];
          92.         Pdot[2]=- PP[1][1];
          93.         Pdot[3]=Q_gyro;

          94.         PP[0][0] += Pdot[0] * dt;   // Pk-先驗估計誤差協(xié)方差微分的積分
          95.         PP[0][1] += Pdot[1] * dt;   // =先驗估計誤差協(xié)方差
          96.         PP[1][0] += Pdot[2] * dt;
          97.         PP[1][1] += Pdot[3] * dt;

          98.         Angle_err = Accel - Angle;//zk-先驗估計

          99.         PCt_0 = C_0 * PP[0][0];
          100.         PCt_1 = C_0 * PP[1][0];

          101.         E = R_angle + C_0 * PCt_0;

          102.         K_0 = PCt_0 / E;
          103.         K_1 = PCt_1 / E;

          104.         t_0 = PCt_0;
          105.         t_1 = C_0 * PP[0][1];

          106.         PP[0][0] -= K_0 * t_0; //后驗估計誤差協(xié)方差
          107.         PP[0][1] -= K_0 * t_1;
          108.         PP[1][0] -= K_1 * t_0;
          109.         PP[1][1] -= K_1 * t_1;

          110.         Angle+= K_0 * Angle_err; //后驗估計
          111.         Q_bias+= K_1 * Angle_err; //后驗估計
          112.         Gyro_y   = Gyro - Q_bias; //輸出值(后驗估計)的微分=角速度

          113. }



          114. //*********************************************************
          115. // 傾角計算(卡爾曼融合)
          116. //*********************************************************

          117. void Angle_Calcu(void)
          118. {
          119.         //------加速度--------------------------

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

          123.         Accel_x  = GetData(ACCEL_XOUT_H);  //讀取X軸加速度         存在ACCEL_XOUT_H 寄存器
          124.         Angle_ax = (Accel_x - 1100) /16384;   //去除零點偏移,計算得到角度(弧度)
          125.         Angle_ax = Angle_ax*1.2*180/3.14;     //弧度轉(zhuǎn)換為度,


          126.         //-------角速度-------------------------

          127.         //范圍為2000deg/s時,換算關(guān)系:16.4 LSB/(deg/s)

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


          131.         //-------卡爾曼濾波融合-----------------------

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


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

          134. //補償原理是取當前傾角和加速度獲得傾角差值進行放大,然后與
          135.         //陀螺儀角速度疊加后再積分,從而使傾角最跟蹤為加速度獲得的角度
          136. //0.5為放大倍數(shù),可調(diào)節(jié)補償度;0.01為系統(tǒng)周期10ms

          137. Angle = Angle + (((Angle_ax-Angle)*0.5 + Gyro_y)*0.01);*/

          138. }  



          139. //*********************************************************
          140. //電機轉(zhuǎn)速和位移值計算
          141. //*********************************************************

          142. void Psn_Calcu(void)
          143. {

          144.         speed_r_l =(speed_mr + speed_ml)*0.5;
          145.         speed *= 0.7;//上一次的                  //車輪速度濾波
          146.         speed += speed_r_l*0.3;
          147.         position += speed;                  //積分得到位移
          148.         position += speed_need;//加上藍牙位移,等于總的移動
          149.         if(position<-6000) position = -6000;
          150.         if(position> 6000) position =  6000;


          151. }


          152. static float code Kp  = 9.0;       //PID參數(shù)
          153. static float code Kd  = 2.6;    //PID參數(shù)
          154. static float code Kpn = 0.01;      //PID參數(shù)
          155. static float code Ksp = 2.0;    //PID參數(shù)

          156. //*********************************************************
          157. //電機PWM值計算
          158. //*********************************************************

          159. void PWM_Calcu(void)
          160. {

          161.         if(Angle<-40||Angle>40)               //角度過大,關(guān)閉電機
          162.         {  
          163.                 CCAP0H = 0;
          164.                 CCAP1H = 0;
          165.                 return;
          166.         }
          167.         PWM  = Kp*Angle + Kd*Gyro_y;          //PID:角速度和角度
          168.         PWM += Kpn*position + Ksp*speed;      //PID:速度和位置
          169.         PWM_R = PWM + turn_need;
          170.         PWM_L = PWM - turn_need;   //藍牙的傾斜,
          171.         PWM_Motor(PWM_L,PWM_R);

          172. }




          173. //*********************************************************
          174. //手機藍牙遙控
          175. //*********************************************************

          176. void Bluetooth_Remote(void)
          177. {

          178.         remote_char = receive_char();   //接收藍牙串口數(shù)據(jù)

          179.         if(remote_char ==0x02) speed_need = -80;   //前進
          180.         else if(remote_char ==0x01) speed_need = 80;   //后退
          181.         else speed_need = 0;   //不動

          182.         if(remote_char ==0x03) turn_need = 15;   //左轉(zhuǎn)
          183.         else if(remote_char ==0x04) turn_need = -15;   //右轉(zhuǎn)
          184.         else turn_need = 0;   //不轉(zhuǎn)

          185. }


          186. /*=================================================================================*/

          187. //*********************************************************
          188. //main
          189. //*********************************************************
          190. void main()
          191. {

          192.         delaynms(500);   //上電延時
          193.         Init_PWM();       //PWM初始化
          194.         Init_Timer0();     //初始化定時器0,作為PWM時鐘源
          195.         Init_Timer1();     //初始化定時器1
          196.         Init_Interr();     //中斷初始化
          197.         Init_Motor();   //電機控制初始化
          198.         Init_BRT();   //串口初始化(獨立波特率)
          199.         InitMPU6050();     //初始化MPU6050
          200.         delaynms(500);   

          201.         while(1)
          202.         {

          203.                 Bluetooth_Remote();

          204.         }
          205. }


          206. /*=================================================================================*/

          207. //********timer1中斷***********************

          208. void Timer1_Update(void) interrupt 3
          209. {

          210.         TL1 = 0xE5;    //設(shè)置定時初值10MS
          211.         TH1 = 0xBE;

          212.         //STC_ISP();                    //程序下載
          213.         Angle_Calcu();                  //傾角計算
          214.         Psn_Calcu();                    //電機位移計算
          215.         PWM_Calcu();                    //計算PWM值

          216.         speed_mr = speed_ml = 0;

          217. }


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

          219. void INT_L(void) interrupt 0
          220. {

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

          224. }


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

          226. void INT_R(void) interrupt 2
          227. {

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

          231. }

          復制代碼

          作者: 1334988150    時間: 2018-3-25 09:09
          可以做啊
          作者: luohe2010    時間: 2018-3-25 09:11
          可以做,可以參考STC官網(wǎng)的一些程序
          作者: 21陳小羊    時間: 2018-3-25 09:16
          可以做的,Arduino是單片機二次開發(fā)的產(chǎn)物。普通單片機只是散件,硬件的設(shè)計和軟件設(shè)計都得你自己來。而且arduino是半成品,你只要把相應(yīng)的模塊組合在一起,再寫一寫甚至直接復制別人程序就能行了。
          作者: JACKLI    時間: 2018-3-25 09:58
          1334988150 發(fā)表于 2018-3-25 09:09
          可以做啊

          可以不可以分享一下你的經(jīng)驗?
          作者: JACKLI    時間: 2018-3-25 10:00
          angmall 發(fā)表于 2018-3-25 07:15

          這是你自己寫的代碼嗎?
          作者: JACKLI    時間: 2018-3-25 10:01
          admin 發(fā)表于 2018-3-25 02:49
          這個可以做,我看過別人做的例子

          噢 噢 噢 。
          作者: JACKLI    時間: 2018-3-25 10:02
          luohe2010 發(fā)表于 2018-3-25 09:11
          可以做,可以參考STC官網(wǎng)的一些程序

          好,等下過去看看
          作者: JACKLI    時間: 2018-3-25 10:13
          21陳小羊 發(fā)表于 2018-3-25 09:16
          可以做的,Arduino是單片機二次開發(fā)的產(chǎn)物。普通單片機只是散件,硬件的設(shè)計和軟件設(shè)計都得你自己來。而且a ...

          是啊,我看別人做平衡車大多都是用arduino做的,用51做的人很少,我之前找資料都很難找到,然后就一直到現(xiàn)在還沒弄好。。。。
          作者: 哥倫比亞    時間: 2018-3-25 11:04
          能不能分享下經(jīng)驗。
          作者: wcwt560    時間: 2018-3-25 11:47
          可以,論壇里應(yīng)該有資料
          作者: muxu    時間: 2018-3-25 16:21
          可以,你可以看一下正點原子的教程
          作者: 愛愛愛    時間: 2018-3-25 17:03
          嗯  可以的只要是代碼的問題

          作者: JACKLI    時間: 2018-3-25 20:05
          wcwt560 發(fā)表于 2018-3-25 11:47
          可以,論壇里應(yīng)該有資料

          好的
          作者: JACKLI    時間: 2018-3-25 20:06
          muxu 發(fā)表于 2018-3-25 16:21
          可以,你可以看一下正點原子的教程

          嗯嗯   ,好的
          作者: JACKLI    時間: 2018-3-25 21:10
          愛愛愛 發(fā)表于 2018-3-25 17:03
          嗯  可以的只要是代碼的問題

          對啊! 那些PID算法看得頭暈,然后就很絕望了
          作者: JACKLI    時間: 2018-3-25 23:38
          angmall 發(fā)表于 2018-3-25 07:15

          可以分享一下頭文件嗎?
          作者: angmall    時間: 2018-3-26 21:11
          1. /*--------------------------------------------------------------------------
          2. DELAY.H

          3. 延時函數(shù) 頭文件
          4. --------------------------------------------------------------------------*/

          5. #ifndef __DELAY_H__
          6. #define __DELAY_H__

          7. #define uchar unsigned char
          8. #define uint  unsigned int


          9. //------函數(shù)(聲明)--------------------------------
          10. void Delay400Ms(void);        //延時400mS函數(shù)(子程序)
          11. void delay1ms(void);        //延時1mS函數(shù)(子程序)
          12. void delaynms(uchar n);    //延時n mS函數(shù)(子程序)



          13. //***********************************************************************************/
          14. //延時400ms

          15. void Delay400Ms(void)
          16. {

          17.         uchar TempCycA = 30;//1周期MPU用30,  12周期MPU用5
          18.         uint TempCycB;
          19.         while(TempCycA--)
          20.         {

          21.                 TempCycB=7269;
          22.                 while(TempCycB--);

          23.         };

          24. }



          25. //***********************************************************************************/
          26. //延時1ms

          27. void delay1ms()
          28. {

          29.         uchar i,j;
          30.         for(i=0;i<10;i++)
          31.                 for(j=0;j<33;j++)
          32.                 ;

          33. }



          34. //***********************************************************************************/
          35. //延時n*ms

          36. void delaynms(uchar n)
          37. {

          38.         uchar i;
          39.         for(i=0;i<n;i++) delay1ms();


          40. }

          41. #endif

          復制代碼

          1. /*****************************************************

          2. 普通IO模擬I2C通信
          3. STC12C5A60S2  IT單片機   AXTL;11.0592MHz

          4. *****************************************************/

          5. #ifndef  __I2C_H__
          6. #define  __I2C_H__


          7. #include <REG52.H>
          8. #include <math.h>    //Keil library  
          9. #include <stdio.h>   //Keil library
          10. #include <INTRINS.H>



          11. //********端口定義**********************************
          12. sbit    SCL=P2^1;//IIC時鐘引腳定義
          13. sbit    SDA=P2^0;//IIC數(shù)據(jù)引腳定義

          14. #defineSlaveAddress 0xD0   //IIC寫入時的地址字節(jié)數(shù)據(jù),+1為讀取


          15. //********函數(shù)初始定義******************************
          16. void  Delay5us();
          17. void  I2C_Start();
          18. void  I2C_Stop();
          19. void  I2C_SendACK(bit ack);
          20. bit   I2C_RecvACK();
          21. void  I2C_SendByte(uchar dat);
          22. uchar I2C_RecvByte();
          23. void  I2C_ReadPage();
          24. void  I2C_WritePage();
          25. void  display_ACCEL_x();
          26. void  display_ACCEL_y();
          27. void  display_ACCEL_z();
          28. uchar Single_ReadI2C(uchar REG_Address);//讀取I2C數(shù)據(jù)
          29. void  Single_WriteI2C(uchar REG_Address,uchar REG_data);    //向I2C寫入數(shù)據(jù)





          30. //**************************************
          31. //延時5微秒(STC12C5A60S2@12M)
          32. //不同的工作環(huán)境,需要調(diào)整此函數(shù)
          33. //此延時函數(shù)是使用1T的指令周期進行計算,與傳統(tǒng)的12T的MCU不同
          34. //**************************************/
          35. void Delay5us()
          36. {

          37.         uchar n = 4;

          38.         while (n--)
          39.         {

          40.                 _nop_();
          41.                 _nop_();
          42.                
          43.         }

          44. }



          45. //**************************************
          46. //I2C起始信號
          47. //**************************************
          48. void I2C_Start()
          49. {

          50.         SDA = 1;                    //拉高數(shù)據(jù)線
          51.         SCL = 1;                    //拉高時鐘線
          52.         Delay5us();                 //延時
          53.         SDA = 0;                    //產(chǎn)生下降沿
          54.         Delay5us();                 //延時
          55.         SCL = 0;                    //拉低時鐘線

          56. }



          57. //**************************************
          58. //I2C停止信號
          59. //**************************************
          60. void I2C_Stop()
          61. {

          62.         SDA = 0;                    //拉低數(shù)據(jù)線
          63.         SCL = 1;                    //拉高時鐘線
          64.         Delay5us();                 //延時
          65.         SDA = 1;                    //產(chǎn)生上升沿
          66.         Delay5us();                 //延時

          67. }



          68. //**************************************
          69. //I2C發(fā)送應(yīng)答信號
          70. //入口參數(shù):ack (0:ACK 1:NAK)
          71. //**************************************
          72. void I2C_SendACK(bit ack)
          73. {

          74.         SDA = ack;                  //寫應(yīng)答信號
          75.         SCL = 1;                    //拉高時鐘線
          76.         Delay5us();                 //延時
          77.         SCL = 0;                    //拉低時鐘線
          78.         Delay5us();                 //延時

          79. }



          80. //**************************************
          81. //I2C接收應(yīng)答信號
          82. //**************************************
          83. bit I2C_RecvACK()
          84. {

          85.         SCL = 1;                    //拉高時鐘線
          86.         Delay5us();                 //延時
          87.         CY = SDA;                   //讀應(yīng)答信號
          88.         SCL = 0;                    //拉低時鐘線
          89.         Delay5us();                 //延時
          90.         return CY;

          91. }



          92. //**************************************
          93. //向I2C總線發(fā)送一個字節(jié)數(shù)據(jù)
          94. //**************************************
          95. void I2C_SendByte(uchar dat)
          96. {

          97.         uchar i;
          98.         for (i=0; i<8; i++)         //8位計數(shù)器
          99.         {

          100.                 dat <<= 1;              //移出數(shù)據(jù)的最高位
          101.                 SDA = CY;               //送數(shù)據(jù)口
          102.                 SCL = 1;                //拉高時鐘線
          103.                 Delay5us();             //延時
          104.                 SCL = 0;                //拉低時鐘線
          105.                 Delay5us();             //延時
          106.                
          107.         }
          108.         I2C_RecvACK();

          109. }


          110. //**************************************
          111. //從I2C總線接收一個字節(jié)數(shù)據(jù)
          112. //**************************************
          113. uchar I2C_RecvByte()
          114. {

          115.         uchar i;
          116.         uchar dat = 0;
          117.         SDA = 1;                    //使能內(nèi)部上拉,準備讀取數(shù)據(jù),
          118.         for (i=0; i<8; i++)         //8位計數(shù)器
          119.         {

          120.                 dat <<= 1;
          121.                 SCL = 1;                //拉高時鐘線
          122.                 Delay5us();             //延時
          123.                 dat |= SDA;             //讀數(shù)據(jù)               
          124.                 SCL = 0;                //拉低時鐘線
          125.                 Delay5us();             //延時
          126.                
          127.         }
          128.         return dat;

          129. }



          130. //**************************************
          131. //向I2C設(shè)備寫入一個字節(jié)數(shù)據(jù)
          132. //**************************************
          133. void Single_WriteI2C(uchar REG_Address,uchar REG_data)
          134. {

          135.         I2C_Start();                  //起始信號
          136.         I2C_SendByte(SlaveAddress);   //發(fā)送設(shè)備地址+寫信號
          137.         I2C_SendByte(REG_Address);    //內(nèi)部寄存器地址
          138.         I2C_SendByte(REG_data);       //內(nèi)部寄存器數(shù)據(jù)
          139.         I2C_Stop();                   //發(fā)送停止信號

          140. }



          141. //**************************************
          142. //從I2C設(shè)備讀取一個字節(jié)數(shù)據(jù)
          143. //**************************************
          144. uchar Single_ReadI2C(uchar REG_Address)
          145. {

          146.         uchar REG_data;
          147.         I2C_Start();                   //起始信號
          148.         I2C_SendByte(SlaveAddress);    //發(fā)送設(shè)備地址+寫信號
          149.         I2C_SendByte(REG_Address);     //發(fā)送存儲單元地址,從0開始
          150.         I2C_Start();                   //起始信號
          151.         I2C_SendByte(SlaveAddress+1);  //發(fā)送設(shè)備地址+讀信號
          152.         REG_data=I2C_RecvByte();       //讀出寄存器數(shù)據(jù)
          153.         I2C_SendACK(1);                //接收應(yīng)答信號
          154.         I2C_Stop();                    //停止信號
          155.         return REG_data;

          156. }


          157. #endif

          復制代碼

          1. /*********************************************************
          2. STC_12C5A60S2免斷電燒錄程序
          3. *********************************************************/


          4. #ifndef   _STC_ISP_H_
          5. #define   _STC_ISP_H_



          6. #include<REG52.h>

          7. sfr IAP_CONTR   = 0xC7; //IAP Control Register

          8. sbit  IN_OFF=P3^0;//串口接收端



          9. //**************************************************

          10. void STC_ISP()
          11. {

          12.        
          13.         IN_OFF=1; //――2

          14.         if(!IN_OFF){
          15.                 IAP_CONTR=0x60;
          16.         } //判斷串口是否有數(shù)據(jù)過來


          17. }


          18. #endif

          復制代碼

          1. /**********************************************************************
          2. 串口收發(fā)程序(頭文件)
          3. 波特率:9600Hz
          4. 可選定時器1或獨立波特率作為串口時鐘
          5. **********************************************************************/


          6. #ifndef __SET_SERIAL_H__
          7. #define __SET_SERIAL_H__


          8. sfr AUXR = 0x8E;
          9. sfr BRT = 0x9C;


          10. //***********************************************************************************/
          11. //定時器1初始化
          12. /*void Init_Timer1()
          13. {

          14.         // set timer1 mode
          15. TMOD |= 0x20;    //設(shè)置timer1為8位自動重載模式
          16. SCON = 0x50;     // 設(shè)定串行口工作方式
          17. PCON &= 0xef; // 波特率不倍增
          18. TH1=TL1=0xFD; //9600 Hz
          19. TR1 = 1; //開啟Timer1


          20. }*/



          21. //***********************************************************************************/
          22. //獨立波特率初始化

          23. void Init_BRT()////9600bps@20MHz
          24. {


          25.         PCON &= 0x7F;//波特率不倍速
          26.         SCON = 0x50;    //8位數(shù)據(jù),可變波特率
          27.         AUXR |= 0x04;//獨立波特率發(fā)生器時鐘為Fosc,即1T
          28.         BRT = 0xBF;    //設(shè)定獨立波特率發(fā)生器重裝值
          29.         AUXR |= 0x01;//串口1選擇獨立波特率發(fā)生器為波特率發(fā)生器
          30.         AUXR |= 0x10;//啟動獨立波特率發(fā)生器


          31. }



          32. //***********************************************************************************/
          33. //串口接收程序

          34. receive_char() //receive data
          35. {

          36.         unsigned char rxd;
          37.         if(RI)     
          38.         {

          39.                 RI = 0;
          40.                 rxd = SBUF;
          41.                 return(rxd);

          42.         }

          43. }



          44. //***********************************************************************************/
          45. //串口發(fā)送子程序

          46. void send_char(unsigned char txd) //sent out data
          47. {

          48.         SBUF = txd;
          49.         while(!TI);
          50.         TI = 0;

          51. }



          52. #endif

          復制代碼


          1. /*********************************************************************************************

          2.     兩路PWM輸出控制設(shè)置

          3. /*********************************************************************************************/

          4. #ifndef __SET_PWM_H__
          5. #define __SET_PWM_H__


          6. //Declare SFR associated with the PCA

          7. sfr   CCON    = 0xD8;      //PCA control register
          8. sbit  CCF0    = CCON^0;    //PCA module-0 interrupt flag
          9. sbit  CCF1    = CCON^1;    //PCA module-1 interrupt flag
          10. sbit  CR      = CCON^6;    //PCA timer run control bit
          11. sbit  CF      = CCON^7;    //PCA timer overflow flag
          12. sfr   CMOD    = 0xD9;      //PCA mode register
          13. sfr   CL      = 0xE9;      //PCA base timer LOW
          14. sfr   CH      = 0xF9;      //PCA base timer HIGH
          15. sfr   CCAPM0  = 0xDA;      //PCA module-0 mode register
          16. sfr   CCAP0L  = 0xEA;      //PCA module-0 capture register LOW
          17. sfr   CCAP0H  = 0xFA;      //PCA module-0 capture register HIGH
          18. sfr   CCAPM1  = 0xDB;      //PCA module-1 mode register
          19. sfr   CCAP1L  = 0xEB;      //PCA module-1 capture register LOW
          20. sfr   CCAP1H  = 0xFB;      //PCA module-1 capture register HIGH
          21. sfr   PCAPWM0 = 0xf2;
          22. sfr   PCAPWM1 = 0xf3;



          23. //***********************************************************************************/
          24. //PWM模式設(shè)置

          25. void Init_PWM()
          26. {

          27.    // set PWM mode
          28.   CCON = 0;                  //Initial PCA control register(PCA timer stop,Clear CF flag,Clear all module interrupt flag)
          29.   CL = 0;                    //Reset PCA base timer
          30.   CH = 0;
          31.   CMOD = 0x04;               //Set PCA timer clock source as timer0 overflow,Disable PCA timer overflow interrupt
          32.   CCAP0H = CCAP0L = 255;     //PWM0 port output X% duty cycle square wave
          33.   CCAPM0 = 0x42;             //PCA module-0 work in 8-bit PWM mode and no PCA interrupt
          34.   CCAP1H = CCAP1L = 255;     //PWM1 port output X% duty cycle square wave
          35.   CCAPM1 = 0x42;             //PCA module-1 work in 8-bit PWM mode and no PCA interrupt
          36.   CR = 1;                    //PCA timer start run
          37.   
          38. }



          39. //***********************************************************************************/
          40. //設(shè)置Timer0為8位自動重載模式,作為PWM時鐘源

          41. void Init_Timer0()
          42. {

          43.     // set timer0 mode
          44.   AUXR = 0x00;               //timer0 work in 12T mode
          45.   TMOD|= 0x02;    //set timer0 counter mode2 (8-bit auto-reload)
          46.   TH0=TL0=130; //PWM 50Hz
          47.   TR0 = 1; //timer0 start running(as PWM clk)

          48.    
          49. }



          50. #endif

          復制代碼

          1. /****************************************

          2. 平衡車兩路直流減速電機PWM控制

          3. ****************************************/


          4. #ifndef__MOTOR_H__
          5. #define __MOTOR_H__

          6. #include <REG52.H>
          7. #include "SET_PWM.H"//PWM頭文件


          8. //電機PWM控制端口定義
          9. sbit LED = P0^0;  //LED
          10. sbit EN12 = P1^3;     //L298電機(左)驅(qū)動使能
          11. sbit EN34 = P1^4;     //L298電機(右)驅(qū)動使能
          12. sbit M1= P1^1;  //電機驅(qū)動(M1=1,M2=0,右電機后退)
          13. sbit M2= P1^2;  //電機驅(qū)動(M1=0,M2=1,右電機前進)
          14. sbit M3= P1^5;  //電機驅(qū)動(M3=1,M4=0,左電機前進)
          15. sbit M4= P1^0;  //電機驅(qū)動(M3=0,M4=1,左電機后退)

          16. sbit SPDR = P3^4; //右電機B相測速,用來判斷電機轉(zhuǎn)向
          17. sbit SPDL = P3^5; //左電機B相測速,用來判斷電機轉(zhuǎn)向

          18. //變量定義
          19. bit flg_direc;  //電機運動方向標志



          20. /*********函數(shù)區(qū)************************/

          21. //**************************************
          22. //電機初始化
          23. //**************************************
          24. void Init_Motor()
          25. {

          26.    CCAP0H = 255;      //關(guān)閉PWM0輸出
          27.    CCAP1H = 255;      //關(guān)閉PWM1輸出
          28.    EN12 = 0;  //關(guān)閉左電機
          29.    EN34 = 0;  //關(guān)閉右電機

          30. }



          31. //**************************************
          32. //電機控制
          33. //**************************************
          34. void PWM_Motor(int pwm_l,int pwm_r)
          35. {


          36.    if(pwm_l<0)
          37.    {

          38.      M1 = 1;      //右電機后退
          39.      M2 = 0;
          40. pwm_l = -pwm_l;

          41. }
          42.    else
          43.    {

          44.      M1 = 0;      //右電機前進
          45.      M2 = 1;

          46. }

          47. if(pwm_r<0)
          48.    {

          49.      M3 = 0;      //左電機后退
          50.      M4 = 1;
          51. pwm_r = -pwm_r;

          52. }
          53.    else
          54.    {

          55.      M3 = 1;      //左電機前進
          56.      M4 = 0;
          57.   

          58. }

          59.    if(pwm_l>255)  pwm_l = 255 ;    //防止PWM值超過255
          60.    if(pwm_r>255)  pwm_r = 255 ;    //防止PWM值超過255
          61.    
          62.    CCAP0H = 0 + pwm_l;     //設(shè)定PWM0占空比(CCAP0H=255,速度最大)
          63.    CCAP1H = 0 + pwm_r;     //設(shè)定PWM1占空比(CCAP0H=255,速度最大)

          64.    //這里50可調(diào),作用是跳過電機PWM死區(qū),在PWM值為0-40時,電機不轉(zhuǎn)動,即死區(qū)(**錯誤的注釋,解釋在下句*)
          65.    //*此處曾經(jīng)完全被誤導,曾經(jīng)在0的地方加的是50,目的是為了消除電機PWM死區(qū),但是導致小車嚴重震蕩,現(xiàn)在該為零才對

          66. }

          67. #endif

          復制代碼


          1. /*********************************************

          2. MPU-6050數(shù)據(jù)處理

          3. *********************************************/


          4. #ifndef  _MPU6050_H_
          5. #define  _MPU6050_H_

          6. #include <REG52.H>
          7. #include <INTRINS.H>

          8. #include "I2C.H"



          9. //****************************************
          10. // 定義MPU6050內(nèi)部地址
          11. //****************************************

          12. #defineSMPLRT_DIV0x19//陀螺儀采樣率,典型值:0x07(125Hz)
          13. #defineCONFIG0x1A//低通濾波頻率,典型值:0x06(5Hz)
          14. #defineGYRO_CONFIG0x1B//陀螺儀自檢及測量范圍,典型值:0x18(不自檢,2000deg/s)
          15. #defineACCEL_CONFIG0x1C//加速計自檢、測量范圍及高通濾波頻率,典型值:0x01(不自檢,2G,5Hz)
          16. #defineACCEL_XOUT_H0x3B
          17. #defineACCEL_XOUT_L0x3C
          18. #defineACCEL_YOUT_H0x3D
          19. #defineACCEL_YOUT_L0x3E
          20. #defineACCEL_ZOUT_H0x3F
          21. #defineACCEL_ZOUT_L0x40
          22. #defineTEMP_OUT_H0x41
          23. #defineTEMP_OUT_L0x42
          24. #defineGYRO_XOUT_H0x43
          25. #defineGYRO_XOUT_L0x44
          26. #defineGYRO_YOUT_H0x45
          27. #defineGYRO_YOUT_L0x46
          28. #defineGYRO_ZOUT_H0x47
          29. #defineGYRO_ZOUT_L0x48
          30. #definePWR_MGMT_10x6B//電源管理,典型值:0x00(正常啟用)
          31. #defineWHO_AM_I0x75//IIC地址寄存器(默認數(shù)值0x68,只讀)
          32. //#defineSlaveAddress 0xD0   //IIC寫入時的地址字節(jié)數(shù)據(jù),+1為讀取



          33. //MPU6050操作函數(shù)聲明

          34. void  InitMPU6050();    //初始化MPU6050
          35. int GetData(uchar REG_Address);        //16位數(shù)據(jù)合成





          36. //**************************************
          37. //初始化MPU6050
          38. //**************************************
          39. void InitMPU6050()
          40. {

          41.         Single_WriteI2C(PWR_MGMT_1, 0x00);//解除休眠狀態(tài)
          42.         Single_WriteI2C(SMPLRT_DIV, 0x07);
          43.         Single_WriteI2C(CONFIG, 0x06);
          44.         Single_WriteI2C(GYRO_CONFIG, 0x18);
          45.         Single_WriteI2C(ACCEL_CONFIG, 0x01);

          46. }



          47. //**************************************
          48. //合成數(shù)據(jù)
          49. //**************************************
          50. int GetData(uchar REG_Address)
          51. {

          52.         uint H;
          53.         uchar L;
          54.         H=Single_ReadI2C(REG_Address);
          55.         L=Single_ReadI2C(REG_Address+1);
          56.         return (H<<8)+L;   //合成數(shù)據(jù)

          57. }


          58. #endif

          復制代碼

          作者: JACKLI    時間: 2018-3-26 23:42
          angmall 發(fā)表于 2018-3-26 21:11

          謝謝
          作者: xue9695    時間: 2018-3-27 10:32
          應(yīng)該是可以做的
          作者: qwertyuiop[    時間: 2018-3-27 22:01
          可以啊,不過平衡車對實時性要求有點高哦
          作者: JACKLI    時間: 2018-3-27 23:37
          xue9695 發(fā)表于 2018-3-27 10:32
          應(yīng)該是可以做的

          嗯,是可以的
          作者: JACKLI    時間: 2018-3-27 23:38
          qwertyuiop[ 發(fā)表于 2018-3-27 22:01
          可以啊,不過平衡車對實時性要求有點高哦

          對的啊,穩(wěn)定性比較差了一點
          作者: heng123    時間: 2018-3-28 00:30
          肯定是可以的 淘寶有賣的吧
          作者: JACKLI    時間: 2018-3-28 22:36
          heng123 發(fā)表于 2018-3-28 00:30
          肯定是可以的 淘寶有賣的吧

          某寶的平衡車太貴啦
          作者: liunian00    時間: 2018-3-30 21:00
          stm32應(yīng)該沒有問題的,msp430也不錯
          作者: JACKLI    時間: 2018-3-31 09:41
          angmall 發(fā)表于 2018-3-26 21:11

          我給單片機燒了你給的代碼,也修改一些相應(yīng)的端口,但是不管怎么傾斜移動平衡車,電機完全不會動,連接上了藍牙也完全沒反應(yīng),這是怎么回事 ?是不是還少了什么東西 ?
          作者: JACKLI    時間: 2018-3-31 12:27
          liunian00 發(fā)表于 2018-3-30 21:00
          stm32應(yīng)該沒有問題的,msp430也不錯

          沒有msp430,沒有用過 這種芯片啊




          歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1