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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6346|回復: 3
收起左側

四軸飛行器stc單片機程序

[復制鏈接]
ID:230801 發表于 2017-9-4 10:14 | 顯示全部樓層 |閱讀模式
stc也可以做四軸
0.png 0.png

單片機源程序如下:
  1. //========================================================================
  2. //        作者:xiaoliu
  3. //        郵箱:1042763631
  4. //        版本V1.0
  5. //========================================================================
  6. //                                 愛好者電子工作室
  7. //特別聲明:此程序
  8. //         
  9. //
  10. //
  11. //                                 MCU工作頻率12MHz
  12. //=========================================================================
  13. //1、如果需要更改工作頻率,請修改本工程中的config.h頭文件中 MAIN_Fosc的宏定義,
  14. //   延時函數都會保持一致,無需更改延遲的參數。
  15. //2、波特率為2400,如果需要更改,必須和STC-ISP最低波特率保持一致才能實現自動下載
  16. //3、IO口已被重新定義,IAP15W4K58S4最大封裝為64腳,具有62個IO口,其中有8個模擬口,
  17. //   當然模擬口也可用作數字口,數字用D表示,模擬用A來表示,此定義專門為STC15W4K系列
  18. //   定義的IO,方便方便以后大家日后的使用,此定義方法類似arduino。
  19. //   使用數字IO口時,定義如下:
  20. //   P3.0-P3.7--->D0-D7   也可以直接使用0-7
  21. //   P2.0-P2.7--->D8-D15  也可以直接使用8-15
  22. //   P4.0-P4.7--->D16-D23 也可以直接使用16-23
  23. //   P5.0-P5.7--->D24-D31 也可以直接使用24-31
  24. //   P6.0-P6.7--->D32-D39 也可以直接使用32-39
  25. //   P7.0-P7.7--->D40-D47 也可以直接使用40-47
  26. //   P0.0-P0.7--->D48-D55 也可以直接使用48-55
  27. //   P1.0-P1.7--->D56-D63 也可以直接使用56-63 也可以使用A0-A7
  28. //   使用模擬IO口時,定義如下:
  29. //   P1.0-P1.7--->0-7
  30. //4、pinMode、digitalWrite必須使用數字IO定義方法,analogRead必須使用模擬IO定義方法
  31. //=============================================================================
  32. #include "config.h"
  33. #include "GPIO.h"
  34. #include "usart.h"
  35. #include "delay.h"
  36. #include "epwm.h"
  37. #include "eInterrupt.h"
  38. #include "IMU.h"
  39. #include "nrf24l01.h"
  40. #include "MPU6050.h"
  41. #include "eeprom.h"
  42. #define Q15(X) \
  43.    ((X < 0.0) ? (int)(32768*(X) - 0.5) : (int)(32767*(X) + 0.5))
  44. #define        EAXSFR()                P_SW2 |=  0x80        /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作對象為擴展SFR(XSFR) */
  45. //PWM定義
  46. #define PWM_L 11 //左邊的電機
  47. #define PWM_R 7  //右邊的電機
  48. #define PWM_F 10 //前面的電機
  49. #define PWM_B 9  //后面的電機
  50. //mpu6050定義         
  51. #define SDA         22         //定義mpu6050的SDA的數字io
  52. #define SCL   48         //定義mpu6050的SCL的數字io


  53. #define CE    23         
  54. #define CSN   57
  55. #define SCK   56
  56. #define MOSI  34
  57. #define MISO  33
  58. #define IRQ   32

  59. #define LED_4   18
  60. #define LED_2   55
  61. #define LED_3   25
  62. #define LED_1   28

  63. u8 SW2_tmp;
  64. bit        B_8ms;
  65. u8 count;
  66. //******************************************************************************************************
  67. u8        xdata        TxBuf[20]={0};
  68. u8        xdata        RxBuf[20]={0};
  69. u8  xdata RxBuf_temp[20]={0};
  70. u8        xdata        tp[16];
  71. //******************************************************************************************************
  72. u8        YM=0;              //油門變化速度控制,不這樣做的話快速變化油門時四軸會失速翻轉

  73. int                data speed2=0,speed3=0,speed4=0,speed5=0;           //電機速度參數
  74. int                data PWM2=0,PWM3=0,PWM4=0,PWM5=0;        //加載至PWM模塊的參數
  75. int                xdata g_x=0,g_y=0,g_z=0;                        //陀螺儀矯正參數
  76. int                xdata a_x,a_y;                                                //角度矯正參數

  77. long  xdata g_x_aver=0;
  78. long  xdata g_y_aver=0;
  79. long  xdata g_z_aver=0;
  80. int   delta_rc_x=0;
  81. int   delta_rc_y=0;
  82. int   delta_rc_z=0;

  83. u8 YM_last;
  84. int delta_Ax;
  85. int delta_Ay;
  86. int delta_Az;

  87. int Ax_real;
  88. int Ay_real;
  89. int Az_real;

  90. int delta_Ax_last;
  91. int delta_Ay_last;
  92. int delta_Az_last;
  93. //*****************角度參數*************************************************
  94. int xdata Angle_ax=0,Angle_ay=0,Angle_az=0;        //由加速度計算的加速度(弧度制)
  95. int idata Angle_gy=0,Angle_gx=0,Angle_gz=0;        //由角速度計算的角速率(角度制)
  96. int data  AngleX=0,AngleY=0,AngleZ=0;                                //四元數解算出的歐拉角
  97. float xdata  Anglezlate=0;                                //Z軸相關
  98. float xdata IMU_gz;
  99. int xdata  Ax=0,Ay=0;                                        //加入遙控器控制量后的角度
  100. int xdata  gx=0,gy=0;                                        //加入遙控器控制量后的角?
  101. u8 data lastR0=0,ZT=0; //上一次RxBuf[0]數據(RxBuf[0]數據在不斷變動的)   狀態標識
  102. //****************姿態處理和PID*********************************************
  103. int        data PID_Output;        //PID最終輸出量

  104. float        xdata Last_Angle_gx=0;        //外環PI輸出量  上一次陀螺儀數據
  105. long        xdata ERRORX_Out=0;        //外環P  外環I  外環誤差積分
  106. long        xdata ERRORX_In=0;        //內環P  內環I   內環D  內環誤差積分

  107. float        xdata Last_Angle_gy=0;
  108. long        xdata ERRORY_Out=0;
  109. long        xdata ERRORY_In=0;
  110. long        xdata ERRORZ_Out=0;

  111. int xdata Last_Ax=0;
  112. int xdata Last_Ay=0;

  113. unsigned int LED_num=0;

  114. int xdata Last_gx=0;
  115. int xdata Last_gy=0;
  116. long idata PID_P;
  117. long idata PID_I;
  118. long idata PID_D;
  119. #define        Out_XP        18.0f            //外環P
  120. #define        Out_XI        Q15(0.024)        //外環I                Q15(0.024)
  121. #define        Out_XD        3.0f            //外環D

  122. #define        In_XP        Q15(0.3) //內環P 720        0.3                                0.3                 0.5
  123. #define        In_XI        Q15(0.00)//內環I                0.024                   0                  0
  124. #define        In_XD        7.5f                 //內環D 720   5                  7.5                   8.0


  125. #define        In_YP        In_XP
  126. #define        In_YI        In_XI
  127. #define        In_YD        In_XD

  128. #define        Out_YP        Out_XP
  129. #define        Out_YI        Out_XI
  130. #define        Out_YD        Out_XD

  131. #define        ZP        5.0f                          //  5
  132. #define        ZD        8.0f        //自旋控制的PID                 8
  133. #define ZI  Q15(0.24)                        //  0.24

  134. #define        ERR_MAX        8000
  135. #define KALMAN_Q        Q15(0.20)
  136. #define KALMAN_R        Q15(0.80)
  137.          
  138.          
  139. int KalmanFilter_ax( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
  140. int KalmanFilter_ay( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
  141. int KalmanFilter_az( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
  142. int KalmanFilter_gyrox( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
  143. int KalmanFilter_gyroy( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
  144. int KalmanFilter_gyroz( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);       
  145. void main()
  146. {               
  147.                 int i=1;
  148.                 u8 j;          
  149.                 Serialbegin(2400,1,COM1);//設置COM1的波特率為2400,將“最低波特率”的值設為2400即可實現自動下載
  150.                 pinMode(SDA,pullup);//設置為內部上拉模式
  151.                 pinMode(SCL,pullup);//設置為內部上拉模式
  152.        
  153.                 pinMode(PWM_L,OUTPP);//設置成推挽模式
  154.                 pinMode(PWM_R,OUTPP);//設置成推挽模式
  155.                 pinMode(PWM_F,OUTPP);//設置成推挽模式
  156.                 pinMode(PWM_B,OUTPP);//設置成推挽模式

  157.                 pinMode(LED_4,OUTPP);//設置成推挽模式       
  158.                 pinMode(LED_2,OUTPP);//設置成推挽模式                
  159.                 pinMode(LED_3,OUTPP);//設置成推挽模式
  160.                 pinMode(LED_1,OUTPP);//設置成推挽模式         

  161.                 pinMode(CE,pullup);//設置為內部上拉模式
  162.                 pinMode(CSN,pullup);//設置為內部上拉模式
  163.                 pinMode(SCK,pullup);//設置為內部上拉模式
  164.                 pinMode(MOSI,pullup);//設置為內部上拉模式
  165.                 pinMode(MISO,pullup);//設置為內部上拉模式
  166.                 pinMode(IRQ,pullup);//設置為內部上拉模式
  167.                
  168.                 //以下為PWM初始化       
  169.               epwmnTcolck(12);//系統時鐘,不分頻
  170.                 epwmTwide(20000);//設置PWM寬度為1001
  171.                 epwmStartADC(0);//不觸發AD
  172.                 epwmFirstSignalLevel(PWM_L,0);//設置初始電平為低
  173.                 epwmFirstSignalLevel(PWM_R,0);//設置初始電平為低
  174.                 epwmFirstSignalLevel(PWM_F,0);//設置初始電平為低
  175.                 epwmFirstSignalLevel(PWM_B,0);//設置初始電平為低
  176.                
  177.                 epwmSetValue(PWM_L,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  178.                 epwmSetValue(PWM_R,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  179.                 epwmSetValue(PWM_F,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  180.                 epwmSetValue(PWM_B,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  181.                 epwmCRbegin();//啟動PWM計數器
  182.                 init_NRF24L01();//初始化無線模塊
  183.                 RxBuf[1] = 128;
  184.                 RxBuf[2] = 128;
  185.                 RxBuf[3] = 128;
  186.                 RxBuf[4] = 0;
  187.                 IAPRead();                //讀取陀螺儀靜差
  188.                 InitMPU6050();        //初始化MPU-6050
  189.                 Timer0_attachInterrupt(10000);//定時器0以10ms定時中斷
  190.                 Timer3_attachInterrupt(4000);//
  191.                   loop()
  192.                 {                                                         
  193.                         YM = RxBuf[4];        //油門

  194.                             
  195.                        
  196.                         if((RxBuf[5] == 1)||(RxBuf[6] == 1))        //校準時,請按2次,第1次清除角速度,第2次清除角度
  197.                         {
  198.                                 RxBuf[5] = 0;
  199.                                 RxBuf[6] = 0;
  200.                                 RxBuf_temp[5] = 0;
  201.                                 RxBuf_temp[6] = 0;
  202.                                 if(RxBuf[4] < 20)
  203.                                 {               
  204.                                
  205.                                
  206.                                         EA = 0;
  207.                                         TR0=0;
  208.                                         g_x_aver=0;
  209.                                         g_y_aver=0;
  210.                                         g_z_aver=0;
  211.                                         for(j=0;j<64;j++)
  212.                                         {               
  213.                                                         Read_MPU6050(tp);
  214.                                                         g_x_aver=g_x_aver+(((int *)&tp)[4]);
  215.                                                         g_y_aver=g_y_aver+(((int *)&tp)[5]);
  216.                                                         g_z_aver=g_z_aver+(((int *)&tp)[6]);                                               
  217.                                         }               
  218.                                         g_x_aver=g_x_aver>>6;
  219.                                         g_y_aver=g_y_aver>>6;
  220.                                         g_z_aver=g_z_aver>>6;
  221.                                        
  222.                                         IAP_Gyro();
  223.    
  224.                                         epwmSetValue(PWM_L,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
  225.                                         epwmSetValue(PWM_R,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
  226.                                         epwmSetValue(PWM_F,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
  227.                                         epwmSetValue(PWM_B,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
  228.                                         delay_ms(100); //校準完畢滴一聲

  229.                                         epwmSetValue(PWM_L,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  230.                                         epwmSetValue(PWM_R,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  231.                                         epwmSetValue(PWM_F,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  232.                                         epwmSetValue(PWM_B,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
  233.                                         TR0=1;
  234.                                         EA = 1;
  235.                                 }
  236.                         }

  237.                 }
  238. }

  239. void timer0_int (void) interrupt TIMER0_VECTOR
  240. {
  241.         B_8ms = 1;
  242.         P52=1;

  243.          LED_num++;
  244.         if(LED_num>200)
  245.         {
  246.            LED_num=0;
  247. //           P51=1;                               
  248. //           P42=1;
  249. //           P07=1;
  250. //           P54=1;                  
  251.         }
  252.         if(LED_num==50)
  253.         {
  254. //           P51=0;                       
  255. //           P42=0;
  256. //           P07=0;
  257. //           P54=0;                  
  258.         }
  259.        
  260.         if(RxBuf[0] == lastR0)        //如果RxBuf[0]的數據沒有收到 即失聯
  261.         {
  262.                 if(++ZT >= 128)
  263.                 {
  264.                         ZT = 120;        //狀態標識大于128即1秒沒有收到數據,失控保護
  265.                        
  266.                         RxBuf[1] = 128;
  267.                         RxBuf_temp[1] = 128;
  268.                         RxBuf[2] = 128; //觸發失控保護 ,緩慢下降,俯仰橫滾方向舵歸中
  269.                         RxBuf_temp[2]=128;
  270.                         RxBuf[3] = 128;
  271.                         RxBuf_temp[3]=128;
  272.                         if(RxBuf[4] != 0)       
  273.                         {
  274.                                 RxBuf[4]--;        //油門在原值逐漸減小
  275.                                 RxBuf_temp[4]=RxBuf[4];
  276.                         }
  277.                 }
  278.         }
  279.         else        ZT = 0;
  280.         lastR0 = RxBuf[0];

  281.         Read_MPU6050(tp);
  282.     Angle_ax=KalmanFilter_ax( ((int *)&tp)[0],KALMAN_Q,KALMAN_R);
  283.         Angle_ay=KalmanFilter_ay( ((int *)&tp)[1],KALMAN_Q,KALMAN_R);
  284.         Angle_az=KalmanFilter_az( ((int *)&tp)[2],KALMAN_Q,KALMAN_R);

  285.         Angle_gx = ((float)(((int *)&tp)[4] - g_x)) / 65.5;        //陀螺儀處理        結果單位是 +-度
  286.         Angle_gy = ((float)(((int *)&tp)[5] - g_y)) / 65.5;        //陀螺儀量程 +-500度/S, 1度/秒 對應讀數 65.536
  287.         Angle_gz=KalmanFilter_gyroz( ((int *)&tp)[6],Q15(0.2),Q15(0.8))- g_z;
  288.         IMU_gz=Angle_gz/65.5;
  289.         Last_Angle_gx = Angle_gx;                //儲存上一次角速度數據
  290.         Last_Angle_gy = Angle_gy;


  291.        
  292. //*********************************** 四元數解算 ***********************************
  293.         IMUupdate(Angle_gx*0.0174533f, Angle_gy*0.0174533f, IMU_gz*0.0174533f, Angle_ax,Angle_ay,Angle_az);//姿態解算,精度0.1度
  294. //將四軸飛行器的所有數據發到遙控上       
  295.         TxBuf[0]=AngleX-a_x;
  296.         TxBuf[1]=(AngleX-a_x)>>8;
  297.         TxBuf[2]=Angle_ax;
  298.         TxBuf[3]=Angle_ax>>8;
  299.         TxBuf[4]=((int *)&tp)[4]-g_x;
  300.         TxBuf[5]=(((int *)&tp)[4]-g_x)>>8;
  301.         TxBuf[6]=AngleY-a_y;
  302.         TxBuf[7]=(AngleY-a_y)>>8;       
  303.         TxBuf[8]=Angle_ay;
  304.         TxBuf[9]=Angle_ay>>8;       
  305.         TxBuf[10]=((int *)&tp)[5]-g_y;
  306.         TxBuf[11]=(((int *)&tp)[5]-g_y)>>8;       
  307.         TxBuf[12]=AngleZ;//z軸角度始終為0,因為不能從IMU中獲取
  308.         TxBuf[13]=(AngleZ)>>8;
  309.         TxBuf[14]=Angle_az;
  310.         TxBuf[15]=Angle_az>>8;
  311.         TxBuf[16]=Angle_gz;
  312.         TxBuf[17]=Angle_gz>>8;
  313.         //0.174533為PI/180 目的是將角度轉弧度        四元數計算出 俯仰(X軸): AngleX, 橫滾(Y軸): AngleY                       
  314. //************** MPU6050 Y軸與水平傾角 ***********************************************************
  315.         if((RxBuf[2] > 113) && (RxBuf[2] < 143))        RxBuf[2] = 128;                 //113 143 128
  316.         delta_rc_y=128-RxBuf[2] ;
  317.         delta_rc_y=delta_rc_y*10/7;
  318.         //        Ay為誤差,delta_rc_y為遙控給的角度作為基準,RxBuf[8]為微調量,a_y為偏差角度,AngleY為采樣的角度
  319.         //一般的,在不考慮微調、偏移量,誤差=基準-測量值
  320.         Ay  = delta_rc_y -(char)RxBuf[8]*2+a_y-AngleY;
  321.         if(YM > 20)                ERRORY_Out += Ay;                                //外環積分(油門小于某個值時不積分)
  322.         else                        ERRORY_Out = 0;                                        //油門小于定值時清除積分值
  323.         if(ERRORY_Out >  ERR_MAX)        ERRORY_Out =  ERR_MAX;
  324.         else if(ERRORY_Out < -ERR_MAX)        ERRORY_Out = -ERR_MAX;        //積分限幅
  325.         PID_P=(long)Ay*Out_YP;
  326.         PID_I=((long)ERRORY_Out*Out_YI)>>15;
  327.         PID_D=((Angle_gx+Last_Angle_gx)/2)*Out_YD;
  328.         PID_Output = (PID_P +PID_I+PID_D+5)/10;        //外環PID,“+5”為了四舍五入?
  329.         Last_Ay=Ay;
  330.        
  331.         gy=PID_Output - Angle_gx;
  332.         if(YM > 20)ERRORY_In +=gy;//內環積分(油門小于某個值時不積分)
  333.         else                        ERRORY_In = 0;                                                        //油門小于定值時清除積分值
  334.         if(ERRORY_In >  ERR_MAX)        ERRORY_In =  ERR_MAX;
  335.         else if(ERRORY_In < -ERR_MAX)        ERRORY_In = -ERR_MAX;        //積分限幅
  336.         PID_P=((long)gy*In_YP)>>15;
  337.         PID_I=((long)ERRORY_In*In_YI)>>15;
  338.         PID_D=((long)gy - Last_gy)*In_YD;
  339.         PID_Output =PID_P+PID_I+PID_D;
  340.         Last_gy=gy;
  341.         if(PID_Output >  19300)        PID_Output =  19300;  //輸出量限幅
  342.         if(PID_Output < -19300)        PID_Output = -19300;
  343.         speed5 =  PID_Output,        speed2 =   -PID_Output;//加載到速度參數
  344. //**************MPU6050 X軸與水平傾角**************************************************
  345.         if((RxBuf[1] > 113) && (RxBuf[1] < 143))        RxBuf[1] = 128;       
  346.         delta_rc_x=RxBuf[1] - 128;
  347.         delta_rc_x=delta_rc_x*10/7;
  348.         //        Ax為誤差,delta_rc_x為遙控給的角度作為基準,RxBuf[7]為微調量,a_x為偏差角度,AngleX為采樣的角度
  349.         //一般的,在不考慮微調、偏移量,誤差=基準-測量值
  350.         Ax = delta_rc_x+(char)RxBuf[7]*2+a_x-AngleX;
  351.         if(YM > 20)        ERRORX_Out += Ax;        //外環積分(油門小于某個值時不積分)
  352.         else                ERRORX_Out = 0;                //油門小于定值時清除積分值
  353.         if(ERRORX_Out >  ERR_MAX)        ERRORX_Out =  ERR_MAX;        //積分限幅
  354.         else if(ERRORX_Out < -ERR_MAX)        ERRORX_Out = -ERR_MAX;        //積分限幅       
  355.         PID_P=(long)Ax*Out_YP;
  356.         PID_I=((long)ERRORX_Out*Out_XI)>>15;
  357.         PID_D=((Angle_gy+Last_Angle_gy)/2)*Out_XD;
  358.         PID_Output = (PID_P+PID_I+PID_D+5)/10;        //外環PID
  359.         Last_Ax=Ax;
  360.         gx=PID_Output - Angle_gy;
  361.         if(YM > 20)        ERRORX_In += gx;        //內環積分(油門小于某個值時不積分)
  362.         else                ERRORX_In  = 0; //油門小于定值時清除積分值
  363.         if(ERRORX_In >  ERR_MAX)        ERRORX_In =  ERR_MAX;
  364.         else if(ERRORX_In < -ERR_MAX)        ERRORX_In = -ERR_MAX;        //積分限幅

  365.         PID_P=((long)gx*In_XP)>>15;
  366.         PID_I=((long)ERRORX_In*In_XI)>>15;
  367.         PID_D=((long)gx - Last_gx)*In_XD;
  368.         PID_Output =PID_P+PID_I+PID_D;
  369.        
  370.         Last_gx=gx;
  371.         if(PID_Output >  19300)        PID_Output =  19300;  //輸出量限幅
  372.         if(PID_Output < -19300)        PID_Output = -19300;
  373.                        
  374.                                                                                 speed4 = 0 - PID_Output;
  375.        
  376.                                                                                 speed3 = 0 + PID_Output;
  377.        
  378. //************** MPU6050 Z軸指向 *****************************       
  379. //只做速度環即可
  380.         if((RxBuf[3] > 113) && (RxBuf[3] < 143))        RxBuf[3] = 128;
  381.         delta_rc_z = (RxBuf[3] - 128)-Angle_gz;        //操作量       
  382.         delta_rc_z = ((int)RxBuf[3] - 128)*64-Angle_gz;        //本來是乘與65.5的系數,乘與64也可以
  383.         if(YM > 20)                ERRORZ_Out += delta_rc_z;
  384.         else                        ERRORZ_Out  = 0;
  385.         if(ERRORZ_Out >  50000)        ERRORZ_Out =  50000;
  386.         else if(ERRORZ_Out < -50000)        ERRORZ_Out = -50000;        //積分限幅
  387.         PID_P=((long)delta_rc_z)*ZP;
  388.         PID_I=((long)ERRORZ_Out * ZI)>>15;
  389.         PID_D=((long)delta_rc_z - Anglezlate) * ZD;

  390.         PID_Output =( PID_P + PID_I + PID_D)>>6;                                                                                 
  391.        
  392.         Anglezlate = delta_rc_z;
  393.         if(PID_Output >  19300)        PID_Output =  19300;  //輸出量限幅
  394.         if(PID_Output < -19300)        PID_Output = -19300;
  395.                 speed4 = speed4 + PID_Output;
  396.                 speed5 = speed5 - PID_Output;speed2 = speed2 - PID_Output;
  397.                 speed3 = speed3 + PID_Output;
  398.                
  399. //**************將速度參數加載至PWM模塊*************************************************       
  400.         if(YM < 20)                PWM2 = 19300,        PWM3 = 19300,        PWM4 = 19300,        PWM5 = 19300;
  401.         else
  402.         {
  403.                 PWM2 = 19300 - (int)YM*4 - speed2;
  404.                          if(PWM2 > 19300)        PWM2 = 19300;        //速度參數控制,防止超過PWM參數范圍0-1000
  405.                 else if(PWM2 < 0)                PWM2 = 0;

  406.                 PWM3 = 19300 - (int)YM*4 - speed3;
  407.                          if(PWM3 > 19300)        PWM3 = 19300;
  408.                 else if(PWM3 < 0)                PWM3 = 0;

  409.                 PWM4 = 19300 - (int)YM*4 - speed4;
  410.                          if(PWM4 > 19300)        PWM4 = 19300;
  411.                 else if(PWM4 < 0)                PWM4 = 0;

  412.                 PWM5 = 19300 - (int)YM*4 - speed5;
  413.                          if(PWM5 > 19300)        PWM5 = 19300;
  414.                 else if(PWM5 < 0)                PWM5 = 0;
  415.         }
  416.         epwmSetValue(PWM_L,PWM5,20000);//設置翻轉值,第1次翻轉為PWM5,第2次翻轉為1001
  417.         epwmSetValue(PWM_R,PWM2,20000);//設置翻轉值,第1次翻轉為PWM2,第2次翻轉為1001
  418.         epwmSetValue(PWM_F,PWM4,20000);//設置翻轉值,第1次翻轉為PWM4,第2次翻轉為1001
  419.         epwmSetValue(PWM_B,PWM3,20000);//設置翻轉值,第1次翻轉為PWM3,第2次翻轉為1001
  420.         P52=0;
  421.         }
  422. void timer3_int (void) interrupt 19
  423. {
  424.                  count++;
  425.                         if(count==1)
  426.                         {
  427.                                 nRF24L01_TxPacket(TxBuf);//發射數據
  428.                         }
  429.                         else if(count==3)
  430.                         {
  431.                                 SetRX_Mode();
  432.                         }
  433.                         else if(count==4)
  434.                         {                               
  435.                                 nRF24L01_RxPacket(RxBuf_temp);//接收數據
  436.                                 if((RxBuf_temp[9]-RxBuf_temp[8]-RxBuf_temp[7]-RxBuf_temp[6]-RxBuf_temp[5]-RxBuf_temp[4]-RxBuf_temp[3]-RxBuf_temp[2]-RxBuf_temp[1]-RxBuf_temp[0])==0)
  437.                                 {                                       
  438.                                         RxBuf[8]=RxBuf_temp[8];//左右微調
  439.                                         RxBuf[7]=RxBuf_temp[7];//前后微調
  440.                                         RxBuf[6]=RxBuf_temp[6];
  441.                                         RxBuf[5]=RxBuf_temp[5];
  442.                                         RxBuf[4]=RxBuf_temp[4];
  443.                                         RxBuf[3]=RxBuf_temp[3];
  444.                                         RxBuf[2]=RxBuf_temp[2];
  445.                                         RxBuf[1]=RxBuf_temp[1];
  446.                                         RxBuf[0]=RxBuf_temp[0];
  447.                                 }
  448.                                 count=0;
  449.                         }
  450. }
  451. int KalmanFilter_ax( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
  452. {
  453.    int R = MeasureNoise_R;
  454.    int Q = ProcessNiose_Q;
  455.    static int ax_last;
  456.    int ax_mid = ax_last;
  457.    long ax_now;
  458.    static int ax_p_last;
  459.    long p_mid ;
  460.    long p_now;
  461.    int kg;        
  462.          long temp;
  463.    ax_mid=ax_last;
  464.    p_mid=ax_p_last+Q;
  465.          temp=p_mid<<15;
  466.          kg=(temp/((long)p_mid+R));
  467.    ax_now= ax_mid+(((long)kg*(ResrcData-ax_mid))>>15);
  468.    p_now=((long)p_mid*(32768-kg))>>15;      
  469.    ax_p_last = p_now;
  470.    ax_last = ax_now;
  471.    return ax_now;               
  472. }
  473. int KalmanFilter_ay( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
  474. {
  475.    int R = MeasureNoise_R;
  476.    int Q = ProcessNiose_Q;
  477.    static int ay_last;
  478.    int ay_mid = ay_last;
  479.    long ay_now;
  480.    static int ay_p_last;
  481.    long p_mid ;
  482.    long p_now;
  483.    int kg;        
  484.          long temp;
  485.    ay_mid=ay_last;
  486.    p_mid=ay_p_last+Q;
  487.    temp=p_mid<<15;
  488.         kg=(temp/((long)p_mid+R));

  489.    ay_now= ay_mid+(((long)kg*(ResrcData-ay_mid))>>15);
  490.    p_now=((long)p_mid*(32768-kg))>>15;      
  491.    ay_p_last = p_now;
  492.    ay_last = ay_now;
  493.    return ay_now;               
  494. }
  495. int KalmanFilter_az( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
  496. {
  497.    int R = MeasureNoise_R;
  498.    int Q = ProcessNiose_Q;
  499.    static int az_last;
  500.    int az_mid = az_last;
  501.    long az_now;
  502.    static int az_p_last;
  503.    long p_mid ;
  504.    long p_now;
  505.    int kg;        
  506.         long temp;
  507.    az_mid=az_last;
  508.    p_mid=az_p_last+Q;
  509.         temp=p_mid<<15;
  510.         kg=(temp/((long)p_mid+R));

  511.    az_now= az_mid+(((long)kg*(ResrcData-az_mid))>>15);
  512.    p_now=((long)p_mid*(32768-kg))>>15;      
  513.    az_p_last = p_now;
  514.    az_last = az_now;
  515.    return az_now;               
  516. }
  517. int KalmanFilter_gyrox( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
  518. {
  519.    int R = MeasureNoise_R;
  520. ……………………

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

所有資料51hei提供下載:
黑色板子四軸程序.zip (555.97 KB, 下載次數: 80)
回復

使用道具 舉報

ID:233308 發表于 2017-9-15 15:30 來自手機 | 顯示全部樓層
謝謝謝謝樓主
回復

使用道具 舉報

ID:233308 發表于 2017-9-15 15:48 | 顯示全部樓層
黑幣不夠下載了
回復

使用道具 舉報

ID:233308 發表于 2017-9-15 15:48 | 顯示全部樓層
黑幣不夠下載了
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 97人澡人人添人人爽欧美 | 欧美国产中文 | 亚洲一区二区三区乱码aⅴ 四虎在线视频 | 国产一区二区精品在线 | 国产精品久久久一区二区三区 | av一二三区 | 日韩精品一区二区三区老鸭窝 | 亚洲视频免费在线播放 | 国产精品欧美一区二区 | 日韩中文欧美 | 美女一区二区在线观看 | 韩日在线视频 | 美女艹b | 亚洲一级在线 | 久久中文免费视频 | 国产精品嫩草影院精东 | 国产伦精品一区二区三区视频金莲 | 精品国产一区二区三区久久 | 欧美 日韩 国产 成人 在线 91 | 久草网站| 亚洲日本激情 | 中文字幕91 | 久久免费视频观看 | 免费精品视频一区 | 久久国产亚洲 | 青青久草 | 国产中文在线观看 | 黄网站免费在线观看 | 美女黄频| 日本精品久久久一区二区三区 | 97国产在线观看 | 国产欧美在线观看 | 欧美精品99 | 国产一区二 | 午夜影院在线观看视频 | 免费污视频 | 网络毛片 | 亚洲一区二区三区在线视频 | 欧美日韩成人影院 | 国产精品久久久久久久久久久久 | 永久www成人看片 |