KK是一个很有趣的开源飞控,由于其硬件要求低,价格大众化,所以虽然性能有限,还是有着广泛的使用群体。我也有一个KK飞控板,并且我下 载了KK的源码进行研究,比较麻烦的是,KK的源码是用汇编写的,很多人是看不懂的。
我觉得这是一个很好的硬件平台(便宜),适合懂单片机的用户进行电子试验和算法试验,因此我花了几个晚上的时间,用C语言完整从零编写了KK飞控的源代码,并且增强了一些很有价值的功能,使得KK的使用更加方便。
现在,我把全部的源码开放在这里,不懂单片机的模友可以直接下 载使用,懂单片机的模友可以尝试改写代码,加入自己喜欢的功能~
飞控的使用说明:
1. 概述
KK_C 是一个四轴飞控固件项目,该固件可用于各种模式的四轴、三轴、六轴、八轴等模式的飞行器,也可用于固定翼稳定之用。 KK_C 是完全用 C 语言编写的固件 , 兼容 KK V5.5 飞控板 , V1.0 版固件大小为 4K 左右 , 适合 ATMAEL 的 MEGA48/88/16 8等单片机芯片。
KK_C 目前还在不断完善中,欢迎大家下载使用,随着版本的升级,还将加入更多
实用的功能,敬请期待!
三轴陀螺仪稳定系统
支持正反向陀螺仪芯片
支持电调油门行程校准
支持十字模式和 X 模式安装
支持锁定保护功能
3. 改进功能( KK_C 特有功能)
开机等待遥控器信号功能(保障使用安全)
飞行器模式选择功能(免烧固件)
全遥控器设置(免调电位器)
软件消震动算法(可配置开 / 关)
支持摇杆指数功能(可配置开 / 关)
PI 控制算法(电位器调节感度)
333Hz 高精度电调信号输出
电位器正反向识别功能(见 9.5 节)
4. 使用前准备
1. 遥控器应设定为固定翼工作模式(或单舵机直升机模式)
2. 各通道的舵量( EPA )应设置在 80 以上,推荐使用 80
3. 如果有大小舵开关(双比率控制 D/R ) ,应将开关拨至大舵量位置
4. 初始时,各通道正反向全部设置为正向
5. 各通道的微调归零( TRIM 或 SUBTRIM 菜单)
6. 各摇杆的微调归零(摇杆旁边的微动开关)
7. 如使用的遥控系统需要对码,请在连接飞控板之前完成对码
5. 连线和布局
1. 飞控板和接收机之间需要连接 4 个通道:副翼 -AIL 、升降 -ELE 、油门 -THR 、方
向 -RUD ,连接方法和标准 KK 固件相同,请注意看 KK 飞控板的标识
(余下内容请下载附件)
单片机源程序如下:
- //###############################################
- // 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 陀螺仪信号反转标识
- uchar SoftSet; //Fly control software setting 飞控软件设置
- uchar AxisMode; //Fly control mode 飞控模式
- //--------------------------------------
- //##Arm 锁定
- bool InLock=1; //model is in lock 模型处于锁定状态
- uchar ArmCnt=0; //Count for arm/disarm
- //###############################################
- //
- // Stick exp
- // 摇杆指数调整
- //
- 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
- // 系统初始化
- //
- void Init(void)
- {
- //Disable all int 禁用全部中断
- CLI();
-
- //Port direction 设置端口方向
- DDRB=0x7F; //0b01111111
- DDRC=0xC0; //0b11000000
- DDRD=0xF1; //0b11110001
-
- //Interrupt setting 设置中断
- 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设为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秒避开电源不稳定阶段
- Delay100ms(20);
- }
- //###############################################
- //
- // Test arming/disarming
- // 判断是否需要锁定/解锁
- //----Hold rud stick for a while, ARMING_TIME should mul main-loop cycle
- //----保持方向摇杆一会后解/锁,ARMING_TIME乘以主循环周期就是时间
- //
- #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)
- // 感度调整
- //
- int GainAdj(int gyro,uchar gain)
- {
- int r;
- r=gyro/8;
- r*=gain;
- return r/(128/8);
- }
- //###############################################
- //
- // Caculate plane attitude
- // 计算飞行器姿态
- //
- void CaclAttitude(void)
- {
- GyroRead();
-
- //If no gyro base, calibrate gyro
- //如果还未建立基准,建立它
- 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表示在进行陀螺仪校准
-
- GyroRolI=GyroPitI=GyroYawI=0;//Reset I value 清空积分值
- }
- else
- {
- if(InLock)
- {
- //熄灭LED表示在锁定中
- LED0_OFF();
- }
- else
- {
- //Remove base part from gyro value
- //减去基础值
- GyroRol-=GyroBaseRol;
- GyroPit-=GyroBasePit;
- GyroYaw-=GyroBaseYaw;
-
- //Reverse gyro signals if necessary
- //根据设置反转各个陀螺仪信号
- 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
- // 计算电机输出信号
- //
- void AxisMixer(void)
- {
- int thr,ail,ele,rud;
-
- //Stick exp
- //摇杆指数
- 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
- //将陀螺仪信号累加到调节量上
- 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 初始化系统
- PpmWaitSignal(); //Wait rx signal, led will flash 等待接收机的信号,等待时LED闪烁
- Setup(); //Load & Adjust parameters 加载&调节参数
-
- //Main loop 主循环
- LED0_OFF();
- while(1)
- {
- TimerRst();
- CaclAttitude(); //Caculate plane attitude 计算飞行器姿态
- 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 读取接收机信号 140us
- if(RxThr<RxThrLow) //If thr shutdown 如果油门关闭
- {
- GyroGainRead(); //Read gain 读取感度电位器 670us
- ArmingRoutine(); //Arm/disarm 加锁解锁测试 5us
- }
- else
- {
- AxisMixer(); //Cacl motor signal 计算电机信号 305us
- }
-
- //If locked(arm) or no gyro base, shutdown all motor
- //如果处于锁定态或者陀螺仪基准未建立,关闭所有马达
- if(InLock || GyroBaseCnt || RxThr<5)
- {
- Motor1=Motor2=Motor3=Motor4=0;
- }
- //MOTOR6_L(); //I use it for test execute period 我用来观察执行时间的
- MotorControlEnd(); //Output whole ppm signal 输出完整的PPM信号
- }
- }
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
KK_C_V100_M88.rar
(20.32 KB, 下载次数: 149)
KK_C 使用说明v1.0.rar
(421.05 KB, 下载次数: 108)
(共9页)
|