|
KK是一個很有趣的開源飛控,由于其硬件要求低,價格大眾化,所以雖然性能有限,還是有著廣泛的使用群體。我也有一個KK飛控板,并且我下 載了KK的源碼進(jìn)行研究,比較麻煩的是,KK的源碼是用匯編寫的,很多人是看不懂的。
我覺得這是一個很好的硬件平臺(便宜),適合懂單片機(jī)的用戶進(jìn)行電子試驗和算法試驗,因此我花了幾個晚上的時間,用C語言完整從零編寫了KK飛控的源代碼,并且增強(qiáng)了一些很有價值的功能,使得KK的使用更加方便。
現(xiàn)在,我把全部的源碼開放在這里,不懂單片機(jī)的模友可以直接下 載使用,懂單片機(jī)的模友可以嘗試改寫代碼,加入自己喜歡的功能~
飛控的使用說明:
1. 概述
KK_C 是一個四軸飛控固件項目,該固件可用于各種模式的四軸、三軸、六軸、八軸等模式的飛行器,也可用于固定翼穩(wěn)定之用。 KK_C 是完全用 C 語言編寫的固件 , 兼容 KK V5.5 飛控板 , V1.0 版固件大小為 4K 左右 , 適合 ATMAEL 的 MEGA48/88/16 8等單片機(jī)芯片。
KK_C 目前還在不斷完善中,歡迎大家下載使用,隨著版本的升級,還將加入更多
實用的功能,敬請期待!
三軸陀螺儀穩(wěn)定系統(tǒng)
支持正反向陀螺儀芯片
支持電調(diào)油門行程校準(zhǔn)
支持十字模式和 X 模式安裝
支持鎖定保護(hù)功能
3. 改進(jìn)功能( KK_C 特有功能)
開機(jī)等待遙控器信號功能(保障使用安全)
飛行器模式選擇功能(免燒固件)
全遙控器設(shè)置(免調(diào)電位器)
軟件消震動算法(可配置開 / 關(guān))
支持搖桿指數(shù)功能(可配置開 / 關(guān))
PI 控制算法(電位器調(diào)節(jié)感度)
333Hz 高精度電調(diào)信號輸出
電位器正反向識別功能(見 9.5 節(jié))
4. 使用前準(zhǔn)備
1. 遙控器應(yīng)設(shè)定為固定翼工作模式(或單舵機(jī)直升機(jī)模式)
2. 各通道的舵量( EPA )應(yīng)設(shè)置在 80 以上,推薦使用 80
3. 如果有大小舵開關(guān)(雙比率控制 D/R ) ,應(yīng)將開關(guān)撥至大舵量位置
4. 初始時,各通道正反向全部設(shè)置為正向
5. 各通道的微調(diào)歸零( TRIM 或 SUBTRIM 菜單)
6. 各搖桿的微調(diào)歸零(搖桿旁邊的微動開關(guān))
7. 如使用的遙控系統(tǒng)需要對碼,請在連接飛控板之前完成對碼
5. 連線和布局
1. 飛控板和接收機(jī)之間需要連接 4 個通道:副翼 -AIL 、升降 -ELE 、油門 -THR 、方
向 -RUD ,連接方法和標(biāo)準(zhǔn) KK 固件相同,請注意看 KK 飛控板的標(biāo)識
(余下內(nèi)容請下載附件)
單片機(jī)源程序如下:
- //###############################################
- // Author : Gale
- // Email : galemx@126.com
- // Location: FuZhou FuJian China
- //
- #include "KK_C.H"
- #include "F_DELAY.H"
- #include "F_EEROM.H"
- //###############################################
- // Global Vars define
- // 全局變量定義
- //--------------------------------------
- //##Gyro signal 陀螺儀信號
- uchar DevRev; //Gyro rev flags 陀螺儀信號反轉(zhuǎn)標(biāo)識
- uchar SoftSet; //Fly control software setting 飛控軟件設(shè)置
- uchar AxisMode; //Fly control mode 飛控模式
- //--------------------------------------
- //##Arm 鎖定
- bool InLock=1; //model is in lock 模型處于鎖定狀態(tài)
- uchar ArmCnt=0; //Count for arm/disarm
- //###############################################
- //
- // Stick exp
- // 搖桿指數(shù)調(diào)整
- //
- int StickExp(int stk)
- {
- uchar neg=(stk<0);
-
- stk*=stk;
- stk/=128;
-
- if(neg) stk=-stk;
-
- return stk;
- }
- //###############################################
- //
- // Stick angle limit
- // 搖桿角度限幅
- //
- int StickLimitValue(int v)
- {
- if(v>PPM_MAX) return PPM_MAX;
- if(v<0) return 0;
- return v;
- }
- //###############################################
- //
- // Board initialization
- // 系統(tǒng)初始化
- //
- void Init(void)
- {
- //Disable all int 禁用全部中斷
- CLI();
-
- //Port direction 設(shè)置端口方向
- DDRB=0x7F; //0b01111111
- DDRC=0xC0; //0b11000000
- DDRD=0xF1; //0b11110001
-
- //Interrupt setting 設(shè)置中斷
- PCICR=0x05; //0b00000101 PB7,PB1
- PCMSK0=0x80; //0b10000000 PB7
- PCMSK2=0x02; //0b00000010 PD1
- EICRA=0x05; //0b00000101 PD2,PD3
- EIMSK=0x03; //0b00000011 PD2,PD3
-
- //Set timer1 to 1M 將定時器1設(shè)為1M
- TCCR1B=0x02; // 1/8 sysclk, 1us count
-
- //Set timer2 to 8us count
- TCCR2B=4; // 1/64 sysclk,8us count
-
- //Enable interrupts 打開中斷
- SEI();
-
- //Delay to avoid power jitter
- //延時2秒避開電源不穩(wěn)定階段
- Delay100ms(20);
- }
- //###############################################
- //
- // Test arming/disarming
- // 判斷是否需要鎖定/解鎖
- //----Hold rud stick for a while, ARMING_TIME should mul main-loop cycle
- //----保持方向搖桿一會后解/鎖,ARMING_TIME乘以主循環(huán)周期就是時間
- //
- #define ARMING_TIME 250
- void ArmingRoutine(void)
- {
- //Count for anti-jitter 鎖定消抖動
- if(RxRud<-STICKGATE || RxRud>STICKGATE) ArmCnt++;
- else ArmCnt=0;
-
- //Hold rud stick for a while, the num should mul main-loop cycle
- if(ArmCnt>ARMING_TIME)
- {
- if(InLock)
- {
- if(RxRud>STICKGATE)
- {
- GyroBaseCnt=GYROBASECNT;
- InLock=0;
- }
- }
- else
- {
- if(RxRud<-STICKGATE) InLock=1;
- }
- }
- }
- //###############################################
- //
- // Gain scale (return gyro*gain/128)
- // 感度調(diào)整
- //
- int GainAdj(int gyro,uchar gain)
- {
- int r;
- r=gyro/8;
- r*=gain;
- return r/(128/8);
- }
- //###############################################
- //
- // Caculate plane attitude
- // 計算飛行器姿態(tài)
- //
- void CaclAttitude(void)
- {
- GyroRead();
-
- //If no gyro base, calibrate gyro
- //如果還未建立基準(zhǔn),建立它
- if(GyroBaseCnt)
- {
- GyroBaseRol+=GyroRol;
- GyroBaseRol/=2;
-
- GyroBasePit+=GyroPit;
- GyroBasePit/=2;
-
- GyroBaseYaw+=GyroYaw;
- GyroBaseYaw/=2;
-
- GyroBaseCnt--;
- if(!(GyroBaseCnt&7)) LED0_TOG(); //Shine LED show gyro cali 閃爍LED表示在進(jìn)行陀螺儀校準(zhǔn)
-
- GyroRolI=GyroPitI=GyroYawI=0;//Reset I value 清空積分值
- }
- else
- {
- if(InLock)
- {
- //熄滅LED表示在鎖定中
- LED0_OFF();
- }
- else
- {
- //Remove base part from gyro value
- //減去基礎(chǔ)值
- GyroRol-=GyroBaseRol;
- GyroPit-=GyroBasePit;
- GyroYaw-=GyroBaseYaw;
-
- //Reverse gyro signals if necessary
- //根據(jù)設(shè)置反轉(zhuǎn)各個陀螺儀信號
- if(BITTST(DevRev,GYRO_ROL)) GyroRol=-GyroRol;
- if(BITTST(DevRev,GYRO_PIT)) GyroPit=-GyroPit;
- if(BITTST(DevRev,GYRO_YAW)) GyroYaw=-GyroYaw;
-
- //Gyro feature compensation
- //陀螺儀特性補償
- GyroRol=GyroCompe(GyroRol,GyroRolPN);
- GyroPit=GyroCompe(GyroPit,GyroPitPN);
- GyroYaw=GyroCompe(GyroYaw,GyroYawPN);
-
- //Sum integral value with return
- //帶回歸計算積分值
- GyroRolI=GyroIntegral(GyroRolI,GyroRol);
- GyroPitI=GyroIntegral(GyroPitI,GyroPit);
- GyroYawI=GyroIntegral(GyroYawI,GyroYaw);
-
- //Light LED
- //點亮LED表示在工作中
- LED0_ON();
- }
- }
- }
- //###############################################
- //
- // Axis signal mixer
- // 計算電機(jī)輸出信號
- //
- void AxisMixer(void)
- {
- int thr,ail,ele,rud;
-
- //Stick exp
- //搖桿指數(shù)
- if(BITTST(SoftSet,SOFT_EXP))
- {
- //Rudder do not need exp
- thr=StickExp(RxThr);
- ail=StickExp(RxAil)/2;
- ele=StickExp(RxEle)/2;
- }
- else
- {
- thr=RxThr;
- ail=RxAil/4;
- ele=RxEle/4;
- }
-
- //Add gyro to adjustment
- //將陀螺儀信號累加到調(diào)節(jié)量上
- ail+=GainAdj(GyroRol,GainRol)+GainAdj(GyroRolI,GainPit);
- ele+=GainAdj(GyroPit,GainRol)+GainAdj(GyroPitI,GainPit);
- rud=RxRud/4+GainAdj(GyroYaw,GainYaw);//+GainAdj(GyroYawI,GainPit);
- if(AxisMode==AXIS_CROSS)
- {
- // + Mode 十字模式
- // 1
- // 3 + 2
- // 4
- Motor1=MotorLimitValue(thr - ele + rud);
- Motor2=MotorLimitValue(thr - ail - rud);
- Motor3=MotorLimitValue(thr + ail - rud);
- Motor4=MotorLimitValue(thr + ele + rud);
- }
- else
- {
- // X Mode X模式
- // 1 2
- // X
- // 3 4
- Motor1=MotorLimitValue(thr + ail - ele + rud);
- Motor2=MotorLimitValue(thr - ail - ele - rud);
- Motor3=MotorLimitValue(thr + ail + ele - rud);
- Motor4=MotorLimitValue(thr - ail + ele + rud);
- }
- }
- //###############################################
- //
- // Main routine
- // 主程序
- //
- void main(void)
- {
- Init(); //Board init 初始化系統(tǒng)
- PpmWaitSignal(); //Wait rx signal, led will flash 等待接收機(jī)的信號,等待時LED閃爍
- Setup(); //Load & Adjust parameters 加載&調(diào)節(jié)參數(shù)
-
- //Main loop 主循環(huán)
- LED0_OFF();
- while(1)
- {
- TimerRst();
- CaclAttitude(); //Caculate plane attitude 計算飛行器姿態(tài)
- TimerTo(1000);
-
- //Do something between MotorControlBegin() and MotorControlEnd
- //See functions declaration, can not exceed 1000us
- //在MotorControlBegin()和MotorControlEnd()之間干點事兒,注意不要超過1000us
- MotorControlBegin(); //Output head of ppm signal 輸出PPM信號的頭部分
- PpmReadSignal(); //Read rx 讀取接收機(jī)信號 140us
- if(RxThr<RxThrLow) //If thr shutdown 如果油門關(guān)閉
- {
- GyroGainRead(); //Read gain 讀取感度電位器 670us
- ArmingRoutine(); //Arm/disarm 加鎖解鎖測試 5us
- }
- else
- {
- AxisMixer(); //Cacl motor signal 計算電機(jī)信號 305us
- }
-
- //If locked(arm) or no gyro base, shutdown all motor
- //如果處于鎖定態(tài)或者陀螺儀基準(zhǔn)未建立,關(guān)閉所有馬達(dá)
- if(InLock || GyroBaseCnt || RxThr<5)
- {
- Motor1=Motor2=Motor3=Motor4=0;
- }
- //MOTOR6_L(); //I use it for test execute period 我用來觀察執(zhí)行時間的
- MotorControlEnd(); //Output whole ppm signal 輸出完整的PPM信號
- }
- }
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
KK_C_V100_M88.rar
(20.32 KB, 下載次數(shù): 151)
2017-10-30 15:01 上傳
點擊文件名下載附件
KK_C 使用說明v1.0.rar
(421.05 KB, 下載次數(shù): 112)
2017-10-30 15:01 上傳
點擊文件名下載附件
(共9頁)
|
|