stc也可以做四軸
單片機源程序如下:
- //========================================================================
- // 作者:xiaoliu
- // 郵箱:1042763631
- // 版本V1.0
- //========================================================================
- // 愛好者電子工作室
- //特別聲明:此程序
- //
- //
- //
- // MCU工作頻率12MHz
- //=========================================================================
- //1、如果需要更改工作頻率,請修改本工程中的config.h頭文件中 MAIN_Fosc的宏定義,
- // 延時函數都會保持一致,無需更改延遲的參數。
- //2、波特率為2400,如果需要更改,必須和STC-ISP最低波特率保持一致才能實現自動下載
- //3、IO口已被重新定義,IAP15W4K58S4最大封裝為64腳,具有62個IO口,其中有8個模擬口,
- // 當然模擬口也可用作數字口,數字用D表示,模擬用A來表示,此定義專門為STC15W4K系列
- // 定義的IO,方便方便以后大家日后的使用,此定義方法類似arduino。
- // 使用數字IO口時,定義如下:
- // P3.0-P3.7--->D0-D7 也可以直接使用0-7
- // P2.0-P2.7--->D8-D15 也可以直接使用8-15
- // P4.0-P4.7--->D16-D23 也可以直接使用16-23
- // P5.0-P5.7--->D24-D31 也可以直接使用24-31
- // P6.0-P6.7--->D32-D39 也可以直接使用32-39
- // P7.0-P7.7--->D40-D47 也可以直接使用40-47
- // P0.0-P0.7--->D48-D55 也可以直接使用48-55
- // P1.0-P1.7--->D56-D63 也可以直接使用56-63 也可以使用A0-A7
- // 使用模擬IO口時,定義如下:
- // P1.0-P1.7--->0-7
- //4、pinMode、digitalWrite必須使用數字IO定義方法,analogRead必須使用模擬IO定義方法
- //=============================================================================
- #include "config.h"
- #include "GPIO.h"
- #include "usart.h"
- #include "delay.h"
- #include "epwm.h"
- #include "eInterrupt.h"
- #include "IMU.h"
- #include "nrf24l01.h"
- #include "MPU6050.h"
- #include "eeprom.h"
- #define Q15(X) \
- ((X < 0.0) ? (int)(32768*(X) - 0.5) : (int)(32767*(X) + 0.5))
- #define EAXSFR() P_SW2 |= 0x80 /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作對象為擴展SFR(XSFR) */
- //PWM定義
- #define PWM_L 11 //左邊的電機
- #define PWM_R 7 //右邊的電機
- #define PWM_F 10 //前面的電機
- #define PWM_B 9 //后面的電機
- //mpu6050定義
- #define SDA 22 //定義mpu6050的SDA的數字io
- #define SCL 48 //定義mpu6050的SCL的數字io
- #define CE 23
- #define CSN 57
- #define SCK 56
- #define MOSI 34
- #define MISO 33
- #define IRQ 32
- #define LED_4 18
- #define LED_2 55
- #define LED_3 25
- #define LED_1 28
- u8 SW2_tmp;
- bit B_8ms;
- u8 count;
- //******************************************************************************************************
- u8 xdata TxBuf[20]={0};
- u8 xdata RxBuf[20]={0};
- u8 xdata RxBuf_temp[20]={0};
- u8 xdata tp[16];
- //******************************************************************************************************
- u8 YM=0; //油門變化速度控制,不這樣做的話快速變化油門時四軸會失速翻轉
- int data speed2=0,speed3=0,speed4=0,speed5=0; //電機速度參數
- int data PWM2=0,PWM3=0,PWM4=0,PWM5=0; //加載至PWM模塊的參數
- int xdata g_x=0,g_y=0,g_z=0; //陀螺儀矯正參數
- int xdata a_x,a_y; //角度矯正參數
- long xdata g_x_aver=0;
- long xdata g_y_aver=0;
- long xdata g_z_aver=0;
- int delta_rc_x=0;
- int delta_rc_y=0;
- int delta_rc_z=0;
- u8 YM_last;
- int delta_Ax;
- int delta_Ay;
- int delta_Az;
- int Ax_real;
- int Ay_real;
- int Az_real;
- int delta_Ax_last;
- int delta_Ay_last;
- int delta_Az_last;
- //*****************角度參數*************************************************
- int xdata Angle_ax=0,Angle_ay=0,Angle_az=0; //由加速度計算的加速度(弧度制)
- int idata Angle_gy=0,Angle_gx=0,Angle_gz=0; //由角速度計算的角速率(角度制)
- int data AngleX=0,AngleY=0,AngleZ=0; //四元數解算出的歐拉角
- float xdata Anglezlate=0; //Z軸相關
- float xdata IMU_gz;
- int xdata Ax=0,Ay=0; //加入遙控器控制量后的角度
- int xdata gx=0,gy=0; //加入遙控器控制量后的角?
- u8 data lastR0=0,ZT=0; //上一次RxBuf[0]數據(RxBuf[0]數據在不斷變動的) 狀態標識
- //****************姿態處理和PID*********************************************
- int data PID_Output; //PID最終輸出量
- float xdata Last_Angle_gx=0; //外環PI輸出量 上一次陀螺儀數據
- long xdata ERRORX_Out=0; //外環P 外環I 外環誤差積分
- long xdata ERRORX_In=0; //內環P 內環I 內環D 內環誤差積分
- float xdata Last_Angle_gy=0;
- long xdata ERRORY_Out=0;
- long xdata ERRORY_In=0;
- long xdata ERRORZ_Out=0;
- int xdata Last_Ax=0;
- int xdata Last_Ay=0;
- unsigned int LED_num=0;
- int xdata Last_gx=0;
- int xdata Last_gy=0;
- long idata PID_P;
- long idata PID_I;
- long idata PID_D;
- #define Out_XP 18.0f //外環P
- #define Out_XI Q15(0.024) //外環I Q15(0.024)
- #define Out_XD 3.0f //外環D
- #define In_XP Q15(0.3) //內環P 720 0.3 0.3 0.5
- #define In_XI Q15(0.00)//內環I 0.024 0 0
- #define In_XD 7.5f //內環D 720 5 7.5 8.0
- #define In_YP In_XP
- #define In_YI In_XI
- #define In_YD In_XD
- #define Out_YP Out_XP
- #define Out_YI Out_XI
- #define Out_YD Out_XD
- #define ZP 5.0f // 5
- #define ZD 8.0f //自旋控制的PID 8
- #define ZI Q15(0.24) // 0.24
- #define ERR_MAX 8000
- #define KALMAN_Q Q15(0.20)
- #define KALMAN_R Q15(0.80)
-
-
- int KalmanFilter_ax( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
- int KalmanFilter_ay( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
- int KalmanFilter_az( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
- int KalmanFilter_gyrox( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
- int KalmanFilter_gyroy( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
- int KalmanFilter_gyroz( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R);
- void main()
- {
- int i=1;
- u8 j;
- Serialbegin(2400,1,COM1);//設置COM1的波特率為2400,將“最低波特率”的值設為2400即可實現自動下載
- pinMode(SDA,pullup);//設置為內部上拉模式
- pinMode(SCL,pullup);//設置為內部上拉模式
-
- pinMode(PWM_L,OUTPP);//設置成推挽模式
- pinMode(PWM_R,OUTPP);//設置成推挽模式
- pinMode(PWM_F,OUTPP);//設置成推挽模式
- pinMode(PWM_B,OUTPP);//設置成推挽模式
- pinMode(LED_4,OUTPP);//設置成推挽模式
- pinMode(LED_2,OUTPP);//設置成推挽模式
- pinMode(LED_3,OUTPP);//設置成推挽模式
- pinMode(LED_1,OUTPP);//設置成推挽模式
- pinMode(CE,pullup);//設置為內部上拉模式
- pinMode(CSN,pullup);//設置為內部上拉模式
- pinMode(SCK,pullup);//設置為內部上拉模式
- pinMode(MOSI,pullup);//設置為內部上拉模式
- pinMode(MISO,pullup);//設置為內部上拉模式
- pinMode(IRQ,pullup);//設置為內部上拉模式
-
- //以下為PWM初始化
- epwmnTcolck(12);//系統時鐘,不分頻
- epwmTwide(20000);//設置PWM寬度為1001
- epwmStartADC(0);//不觸發AD
- epwmFirstSignalLevel(PWM_L,0);//設置初始電平為低
- epwmFirstSignalLevel(PWM_R,0);//設置初始電平為低
- epwmFirstSignalLevel(PWM_F,0);//設置初始電平為低
- epwmFirstSignalLevel(PWM_B,0);//設置初始電平為低
-
- epwmSetValue(PWM_L,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- epwmSetValue(PWM_R,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- epwmSetValue(PWM_F,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- epwmSetValue(PWM_B,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- epwmCRbegin();//啟動PWM計數器
- init_NRF24L01();//初始化無線模塊
- RxBuf[1] = 128;
- RxBuf[2] = 128;
- RxBuf[3] = 128;
- RxBuf[4] = 0;
- IAPRead(); //讀取陀螺儀靜差
- InitMPU6050(); //初始化MPU-6050
- Timer0_attachInterrupt(10000);//定時器0以10ms定時中斷
- Timer3_attachInterrupt(4000);//
- loop()
- {
- YM = RxBuf[4]; //油門
-
-
- if((RxBuf[5] == 1)||(RxBuf[6] == 1)) //校準時,請按2次,第1次清除角速度,第2次清除角度
- {
- RxBuf[5] = 0;
- RxBuf[6] = 0;
- RxBuf_temp[5] = 0;
- RxBuf_temp[6] = 0;
- if(RxBuf[4] < 20)
- {
-
-
- EA = 0;
- TR0=0;
- g_x_aver=0;
- g_y_aver=0;
- g_z_aver=0;
- for(j=0;j<64;j++)
- {
- Read_MPU6050(tp);
- g_x_aver=g_x_aver+(((int *)&tp)[4]);
- g_y_aver=g_y_aver+(((int *)&tp)[5]);
- g_z_aver=g_z_aver+(((int *)&tp)[6]);
- }
- g_x_aver=g_x_aver>>6;
- g_y_aver=g_y_aver>>6;
- g_z_aver=g_z_aver>>6;
-
- IAP_Gyro();
-
- epwmSetValue(PWM_L,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
- epwmSetValue(PWM_R,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
- epwmSetValue(PWM_F,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
- epwmSetValue(PWM_B,19300,20000);//設置翻轉值,第1次翻轉為960,第2次翻轉為1001
- delay_ms(100); //校準完畢滴一聲
- epwmSetValue(PWM_L,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- epwmSetValue(PWM_R,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- epwmSetValue(PWM_F,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- epwmSetValue(PWM_B,19300,20000);//設置翻轉值,第1次翻轉為1000,第2次翻轉為1001
- TR0=1;
- EA = 1;
- }
- }
- }
- }
- void timer0_int (void) interrupt TIMER0_VECTOR
- {
- B_8ms = 1;
- P52=1;
- LED_num++;
- if(LED_num>200)
- {
- LED_num=0;
- // P51=1;
- // P42=1;
- // P07=1;
- // P54=1;
- }
- if(LED_num==50)
- {
- // P51=0;
- // P42=0;
- // P07=0;
- // P54=0;
- }
-
- if(RxBuf[0] == lastR0) //如果RxBuf[0]的數據沒有收到 即失聯
- {
- if(++ZT >= 128)
- {
- ZT = 120; //狀態標識大于128即1秒沒有收到數據,失控保護
-
- RxBuf[1] = 128;
- RxBuf_temp[1] = 128;
- RxBuf[2] = 128; //觸發失控保護 ,緩慢下降,俯仰橫滾方向舵歸中
- RxBuf_temp[2]=128;
- RxBuf[3] = 128;
- RxBuf_temp[3]=128;
- if(RxBuf[4] != 0)
- {
- RxBuf[4]--; //油門在原值逐漸減小
- RxBuf_temp[4]=RxBuf[4];
- }
- }
- }
- else ZT = 0;
- lastR0 = RxBuf[0];
- Read_MPU6050(tp);
- Angle_ax=KalmanFilter_ax( ((int *)&tp)[0],KALMAN_Q,KALMAN_R);
- Angle_ay=KalmanFilter_ay( ((int *)&tp)[1],KALMAN_Q,KALMAN_R);
- Angle_az=KalmanFilter_az( ((int *)&tp)[2],KALMAN_Q,KALMAN_R);
- Angle_gx = ((float)(((int *)&tp)[4] - g_x)) / 65.5; //陀螺儀處理 結果單位是 +-度
- Angle_gy = ((float)(((int *)&tp)[5] - g_y)) / 65.5; //陀螺儀量程 +-500度/S, 1度/秒 對應讀數 65.536
- Angle_gz=KalmanFilter_gyroz( ((int *)&tp)[6],Q15(0.2),Q15(0.8))- g_z;
- IMU_gz=Angle_gz/65.5;
- Last_Angle_gx = Angle_gx; //儲存上一次角速度數據
- Last_Angle_gy = Angle_gy;
-
- //*********************************** 四元數解算 ***********************************
- IMUupdate(Angle_gx*0.0174533f, Angle_gy*0.0174533f, IMU_gz*0.0174533f, Angle_ax,Angle_ay,Angle_az);//姿態解算,精度0.1度
- //將四軸飛行器的所有數據發到遙控上
- TxBuf[0]=AngleX-a_x;
- TxBuf[1]=(AngleX-a_x)>>8;
- TxBuf[2]=Angle_ax;
- TxBuf[3]=Angle_ax>>8;
- TxBuf[4]=((int *)&tp)[4]-g_x;
- TxBuf[5]=(((int *)&tp)[4]-g_x)>>8;
- TxBuf[6]=AngleY-a_y;
- TxBuf[7]=(AngleY-a_y)>>8;
- TxBuf[8]=Angle_ay;
- TxBuf[9]=Angle_ay>>8;
- TxBuf[10]=((int *)&tp)[5]-g_y;
- TxBuf[11]=(((int *)&tp)[5]-g_y)>>8;
- TxBuf[12]=AngleZ;//z軸角度始終為0,因為不能從IMU中獲取
- TxBuf[13]=(AngleZ)>>8;
- TxBuf[14]=Angle_az;
- TxBuf[15]=Angle_az>>8;
- TxBuf[16]=Angle_gz;
- TxBuf[17]=Angle_gz>>8;
- //0.174533為PI/180 目的是將角度轉弧度 四元數計算出 俯仰(X軸): AngleX, 橫滾(Y軸): AngleY
- //************** MPU6050 Y軸與水平傾角 ***********************************************************
- if((RxBuf[2] > 113) && (RxBuf[2] < 143)) RxBuf[2] = 128; //113 143 128
- delta_rc_y=128-RxBuf[2] ;
- delta_rc_y=delta_rc_y*10/7;
- // Ay為誤差,delta_rc_y為遙控給的角度作為基準,RxBuf[8]為微調量,a_y為偏差角度,AngleY為采樣的角度
- //一般的,在不考慮微調、偏移量,誤差=基準-測量值
- Ay = delta_rc_y -(char)RxBuf[8]*2+a_y-AngleY;
- if(YM > 20) ERRORY_Out += Ay; //外環積分(油門小于某個值時不積分)
- else ERRORY_Out = 0; //油門小于定值時清除積分值
- if(ERRORY_Out > ERR_MAX) ERRORY_Out = ERR_MAX;
- else if(ERRORY_Out < -ERR_MAX) ERRORY_Out = -ERR_MAX; //積分限幅
- PID_P=(long)Ay*Out_YP;
- PID_I=((long)ERRORY_Out*Out_YI)>>15;
- PID_D=((Angle_gx+Last_Angle_gx)/2)*Out_YD;
- PID_Output = (PID_P +PID_I+PID_D+5)/10; //外環PID,“+5”為了四舍五入?
- Last_Ay=Ay;
-
- gy=PID_Output - Angle_gx;
- if(YM > 20)ERRORY_In +=gy;//內環積分(油門小于某個值時不積分)
- else ERRORY_In = 0; //油門小于定值時清除積分值
- if(ERRORY_In > ERR_MAX) ERRORY_In = ERR_MAX;
- else if(ERRORY_In < -ERR_MAX) ERRORY_In = -ERR_MAX; //積分限幅
- PID_P=((long)gy*In_YP)>>15;
- PID_I=((long)ERRORY_In*In_YI)>>15;
- PID_D=((long)gy - Last_gy)*In_YD;
- PID_Output =PID_P+PID_I+PID_D;
- Last_gy=gy;
- if(PID_Output > 19300) PID_Output = 19300; //輸出量限幅
- if(PID_Output < -19300) PID_Output = -19300;
- speed5 = PID_Output, speed2 = -PID_Output;//加載到速度參數
- //**************MPU6050 X軸與水平傾角**************************************************
- if((RxBuf[1] > 113) && (RxBuf[1] < 143)) RxBuf[1] = 128;
- delta_rc_x=RxBuf[1] - 128;
- delta_rc_x=delta_rc_x*10/7;
- // Ax為誤差,delta_rc_x為遙控給的角度作為基準,RxBuf[7]為微調量,a_x為偏差角度,AngleX為采樣的角度
- //一般的,在不考慮微調、偏移量,誤差=基準-測量值
- Ax = delta_rc_x+(char)RxBuf[7]*2+a_x-AngleX;
- if(YM > 20) ERRORX_Out += Ax; //外環積分(油門小于某個值時不積分)
- else ERRORX_Out = 0; //油門小于定值時清除積分值
- if(ERRORX_Out > ERR_MAX) ERRORX_Out = ERR_MAX; //積分限幅
- else if(ERRORX_Out < -ERR_MAX) ERRORX_Out = -ERR_MAX; //積分限幅
- PID_P=(long)Ax*Out_YP;
- PID_I=((long)ERRORX_Out*Out_XI)>>15;
- PID_D=((Angle_gy+Last_Angle_gy)/2)*Out_XD;
- PID_Output = (PID_P+PID_I+PID_D+5)/10; //外環PID
- Last_Ax=Ax;
- gx=PID_Output - Angle_gy;
- if(YM > 20) ERRORX_In += gx; //內環積分(油門小于某個值時不積分)
- else ERRORX_In = 0; //油門小于定值時清除積分值
- if(ERRORX_In > ERR_MAX) ERRORX_In = ERR_MAX;
- else if(ERRORX_In < -ERR_MAX) ERRORX_In = -ERR_MAX; //積分限幅
- PID_P=((long)gx*In_XP)>>15;
- PID_I=((long)ERRORX_In*In_XI)>>15;
- PID_D=((long)gx - Last_gx)*In_XD;
- PID_Output =PID_P+PID_I+PID_D;
-
- Last_gx=gx;
- if(PID_Output > 19300) PID_Output = 19300; //輸出量限幅
- if(PID_Output < -19300) PID_Output = -19300;
-
- speed4 = 0 - PID_Output;
-
- speed3 = 0 + PID_Output;
-
- //************** MPU6050 Z軸指向 *****************************
- //只做速度環即可
- if((RxBuf[3] > 113) && (RxBuf[3] < 143)) RxBuf[3] = 128;
- delta_rc_z = (RxBuf[3] - 128)-Angle_gz; //操作量
- delta_rc_z = ((int)RxBuf[3] - 128)*64-Angle_gz; //本來是乘與65.5的系數,乘與64也可以
- if(YM > 20) ERRORZ_Out += delta_rc_z;
- else ERRORZ_Out = 0;
- if(ERRORZ_Out > 50000) ERRORZ_Out = 50000;
- else if(ERRORZ_Out < -50000) ERRORZ_Out = -50000; //積分限幅
- PID_P=((long)delta_rc_z)*ZP;
- PID_I=((long)ERRORZ_Out * ZI)>>15;
- PID_D=((long)delta_rc_z - Anglezlate) * ZD;
- PID_Output =( PID_P + PID_I + PID_D)>>6;
-
- Anglezlate = delta_rc_z;
- if(PID_Output > 19300) PID_Output = 19300; //輸出量限幅
- if(PID_Output < -19300) PID_Output = -19300;
- speed4 = speed4 + PID_Output;
- speed5 = speed5 - PID_Output;speed2 = speed2 - PID_Output;
- speed3 = speed3 + PID_Output;
-
- //**************將速度參數加載至PWM模塊*************************************************
- if(YM < 20) PWM2 = 19300, PWM3 = 19300, PWM4 = 19300, PWM5 = 19300;
- else
- {
- PWM2 = 19300 - (int)YM*4 - speed2;
- if(PWM2 > 19300) PWM2 = 19300; //速度參數控制,防止超過PWM參數范圍0-1000
- else if(PWM2 < 0) PWM2 = 0;
- PWM3 = 19300 - (int)YM*4 - speed3;
- if(PWM3 > 19300) PWM3 = 19300;
- else if(PWM3 < 0) PWM3 = 0;
- PWM4 = 19300 - (int)YM*4 - speed4;
- if(PWM4 > 19300) PWM4 = 19300;
- else if(PWM4 < 0) PWM4 = 0;
- PWM5 = 19300 - (int)YM*4 - speed5;
- if(PWM5 > 19300) PWM5 = 19300;
- else if(PWM5 < 0) PWM5 = 0;
- }
- epwmSetValue(PWM_L,PWM5,20000);//設置翻轉值,第1次翻轉為PWM5,第2次翻轉為1001
- epwmSetValue(PWM_R,PWM2,20000);//設置翻轉值,第1次翻轉為PWM2,第2次翻轉為1001
- epwmSetValue(PWM_F,PWM4,20000);//設置翻轉值,第1次翻轉為PWM4,第2次翻轉為1001
- epwmSetValue(PWM_B,PWM3,20000);//設置翻轉值,第1次翻轉為PWM3,第2次翻轉為1001
- P52=0;
- }
- void timer3_int (void) interrupt 19
- {
- count++;
- if(count==1)
- {
- nRF24L01_TxPacket(TxBuf);//發射數據
- }
- else if(count==3)
- {
- SetRX_Mode();
- }
- else if(count==4)
- {
- nRF24L01_RxPacket(RxBuf_temp);//接收數據
- 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)
- {
- RxBuf[8]=RxBuf_temp[8];//左右微調
- RxBuf[7]=RxBuf_temp[7];//前后微調
- RxBuf[6]=RxBuf_temp[6];
- RxBuf[5]=RxBuf_temp[5];
- RxBuf[4]=RxBuf_temp[4];
- RxBuf[3]=RxBuf_temp[3];
- RxBuf[2]=RxBuf_temp[2];
- RxBuf[1]=RxBuf_temp[1];
- RxBuf[0]=RxBuf_temp[0];
- }
- count=0;
- }
- }
- int KalmanFilter_ax( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
- {
- int R = MeasureNoise_R;
- int Q = ProcessNiose_Q;
- static int ax_last;
- int ax_mid = ax_last;
- long ax_now;
- static int ax_p_last;
- long p_mid ;
- long p_now;
- int kg;
- long temp;
- ax_mid=ax_last;
- p_mid=ax_p_last+Q;
- temp=p_mid<<15;
- kg=(temp/((long)p_mid+R));
- ax_now= ax_mid+(((long)kg*(ResrcData-ax_mid))>>15);
- p_now=((long)p_mid*(32768-kg))>>15;
- ax_p_last = p_now;
- ax_last = ax_now;
- return ax_now;
- }
- int KalmanFilter_ay( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
- {
- int R = MeasureNoise_R;
- int Q = ProcessNiose_Q;
- static int ay_last;
- int ay_mid = ay_last;
- long ay_now;
- static int ay_p_last;
- long p_mid ;
- long p_now;
- int kg;
- long temp;
- ay_mid=ay_last;
- p_mid=ay_p_last+Q;
- temp=p_mid<<15;
- kg=(temp/((long)p_mid+R));
- ay_now= ay_mid+(((long)kg*(ResrcData-ay_mid))>>15);
- p_now=((long)p_mid*(32768-kg))>>15;
- ay_p_last = p_now;
- ay_last = ay_now;
- return ay_now;
- }
- int KalmanFilter_az( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
- {
- int R = MeasureNoise_R;
- int Q = ProcessNiose_Q;
- static int az_last;
- int az_mid = az_last;
- long az_now;
- static int az_p_last;
- long p_mid ;
- long p_now;
- int kg;
- long temp;
- az_mid=az_last;
- p_mid=az_p_last+Q;
- temp=p_mid<<15;
- kg=(temp/((long)p_mid+R));
- az_now= az_mid+(((long)kg*(ResrcData-az_mid))>>15);
- p_now=((long)p_mid*(32768-kg))>>15;
- az_p_last = p_now;
- az_last = az_now;
- return az_now;
- }
- int KalmanFilter_gyrox( int ResrcData,int ProcessNiose_Q,int MeasureNoise_R)
- {
- int R = MeasureNoise_R;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
黑色板子四軸程序.zip
(555.97 KB, 下載次數: 80)
2017-9-4 10:13 上傳
點擊文件名下載附件
|