找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16242|回复: 11
打印 上一主题 下一主题
收起左侧

KK开源四轴飞控源代码与使用说明

  [复制链接]
跳转到指定楼层
楼主
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 飞控板的标识

(余下内容请下载附件)

单片机源程序如下:
  1. //###############################################
  2. // Author  : Gale
  3. // Email   : galemx@126.com
  4. // Location: FuZhou FuJian China
  5. //
  6. #include "KK_C.H"
  7. #include "F_DELAY.H"
  8. #include "F_EEROM.H"

  9. //###############################################
  10. // Global Vars define
  11. // 全局变量定义

  12. //--------------------------------------
  13. //##Gyro signal 陀螺仪信号
  14. uchar DevRev;                                         //Gyro rev flags 陀螺仪信号反转标识
  15. uchar SoftSet;                                        //Fly control software setting 飞控软件设置
  16. uchar AxisMode;                                        //Fly control mode 飞控模式

  17. //--------------------------------------
  18. //##Arm 锁定
  19. bool InLock=1;        //model is in lock 模型处于锁定状态
  20. uchar ArmCnt=0;        //Count for arm/disarm

  21. //###############################################
  22. //
  23. //   Stick exp
  24. //   摇杆指数调整
  25. //
  26. int StickExp(int stk)
  27. {
  28.          uchar neg=(stk<0);
  29.         
  30.         stk*=stk;
  31.         stk/=128;
  32.         
  33.         if(neg) stk=-stk;
  34.         
  35.         return stk;
  36. }

  37. //###############################################
  38. //
  39. //   Stick angle limit
  40. //   摇杆角度限幅
  41. //
  42. int StickLimitValue(int v)
  43. {
  44.          if(v>PPM_MAX)        return PPM_MAX;
  45.         if(v<0)                        return 0;
  46.         return v;
  47. }

  48. //###############################################
  49. //
  50. //   Board initialization
  51. //   系统初始化
  52. //
  53. void Init(void)
  54. {
  55.          //Disable all int 禁用全部中断
  56.         CLI();           
  57.         
  58.         //Port direction 设置端口方向
  59.         DDRB=0x7F;                 //0b01111111
  60.         DDRC=0xC0;                 //0b11000000
  61.         DDRD=0xF1;                 //0b11110001
  62.         
  63.         //Interrupt setting 设置中断
  64.         PCICR=0x05;                 //0b00000101 PB7,PB1
  65.         PCMSK0=0x80;         //0b10000000 PB7
  66.         PCMSK2=0x02;         //0b00000010 PD1
  67.         EICRA=0x05;                 //0b00000101 PD2,PD3
  68.         EIMSK=0x03;                 //0b00000011 PD2,PD3
  69.         
  70.         //Set timer1 to 1M 将定时器1设为1M
  71.         TCCR1B=0x02;         // 1/8 sysclk, 1us count
  72.         
  73.         //Set timer2 to 8us count
  74.         TCCR2B=4;                // 1/64 sysclk,8us count
  75.                         
  76.         //Enable interrupts 打开中断
  77.         SEI();
  78.         
  79.         //Delay to avoid power jitter
  80.         //延时2秒避开电源不稳定阶段
  81.         Delay100ms(20);
  82. }

  83. //###############################################
  84. //
  85. //   Test arming/disarming
  86. //   判断是否需要锁定/解锁
  87. //----Hold rud stick for a while, ARMING_TIME should mul main-loop cycle
  88. //----保持方向摇杆一会后解/锁,ARMING_TIME乘以主循环周期就是时间
  89. //
  90. #define ARMING_TIME                  250
  91. void ArmingRoutine(void)
  92. {
  93.          //Count for anti-jitter 锁定消抖动
  94.         if(RxRud<-STICKGATE || RxRud>STICKGATE)        ArmCnt++;
  95.         else                                                                            ArmCnt=0;
  96.                         
  97.         //Hold rud stick for a while, the num should mul main-loop cycle
  98.         if(ArmCnt>ARMING_TIME)               
  99.         {         
  100.                 if(InLock)
  101.                 {
  102.                          if(RxRud>STICKGATE)        
  103.                         {
  104.                                  GyroBaseCnt=GYROBASECNT;        
  105.                                  InLock=0;
  106.                         }
  107.                 }
  108.                 else
  109.                 {
  110.                          if(RxRud<-STICKGATE)                InLock=1;
  111.                 }
  112.         }
  113. }

  114. //###############################################
  115. //
  116. //   Gain scale (return gyro*gain/128)
  117. //   感度调整
  118. //
  119. int GainAdj(int gyro,uchar gain)
  120. {
  121.          int r;
  122.         r=gyro/8;
  123.         r*=gain;                  
  124.         return r/(128/8);
  125. }

  126. //###############################################
  127. //
  128. //   Caculate plane attitude
  129. //   计算飞行器姿态
  130. //
  131. void CaclAttitude(void)
  132. {
  133.         GyroRead();
  134.         
  135.         //If no gyro base, calibrate gyro
  136.         //如果还未建立基准,建立它
  137.         if(GyroBaseCnt)
  138.         {                        
  139.                  GyroBaseRol+=GyroRol;
  140.                 GyroBaseRol/=2;
  141.                
  142.                 GyroBasePit+=GyroPit;
  143.                 GyroBasePit/=2;
  144.                
  145.                 GyroBaseYaw+=GyroYaw;
  146.                 GyroBaseYaw/=2;
  147.                
  148.                 GyroBaseCnt--;
  149.                 if(!(GyroBaseCnt&7)) LED0_TOG();        //Shine LED show gyro cali 闪烁LED表示在进行陀螺仪校准
  150.                
  151.                 GyroRolI=GyroPitI=GyroYawI=0;//Reset I value 清空积分值
  152.         }
  153.         else
  154.         {               
  155.                 if(InLock)
  156.                 {
  157.                          //熄灭LED表示在锁定中
  158.                         LED0_OFF();
  159.                 }
  160.                 else
  161.                 {
  162.                           //Remove base part from gyro value
  163.                         //减去基础值
  164.                          GyroRol-=GyroBaseRol;
  165.                          GyroPit-=GyroBasePit;
  166.                          GyroYaw-=GyroBaseYaw;
  167.         
  168.                         //Reverse gyro signals if necessary
  169.                         //根据设置反转各个陀螺仪信号
  170.                         if(BITTST(DevRev,GYRO_ROL))          GyroRol=-GyroRol;
  171.                         if(BITTST(DevRev,GYRO_PIT))          GyroPit=-GyroPit;
  172.                         if(BITTST(DevRev,GYRO_YAW))          GyroYaw=-GyroYaw;
  173.                         
  174.                         //Gyro feature compensation
  175.                         //陀螺仪特性补偿
  176.                         GyroRol=GyroCompe(GyroRol,GyroRolPN);
  177.                         GyroPit=GyroCompe(GyroPit,GyroPitPN);
  178.                         GyroYaw=GyroCompe(GyroYaw,GyroYawPN);
  179.                         
  180.                         //Sum integral value with return
  181.                         //带回归计算积分值               
  182.                         GyroRolI=GyroIntegral(GyroRolI,GyroRol);
  183.                         GyroPitI=GyroIntegral(GyroPitI,GyroPit);
  184.                         GyroYawI=GyroIntegral(GyroYawI,GyroYaw);
  185.                
  186.                         //Light LED
  187.                         //点亮LED表示在工作中
  188.                          LED0_ON();
  189.                 }
  190.         }
  191. }

  192. //###############################################
  193. //
  194. //   Axis signal mixer
  195. //   计算电机输出信号
  196. //
  197. void AxisMixer(void)
  198. {
  199.          int thr,ail,ele,rud;
  200.         
  201.         //Stick exp
  202.         //摇杆指数
  203.         if(BITTST(SoftSet,SOFT_EXP))
  204.         {
  205.                  //Rudder do not need exp
  206.                  thr=StickExp(RxThr);
  207.                  ail=StickExp(RxAil)/2;
  208.                  ele=StickExp(RxEle)/2;
  209.         }
  210.         else
  211.         {
  212.                  thr=RxThr;        
  213.                  ail=RxAil/4;
  214.                  ele=RxEle/4;
  215.         }        
  216.                
  217.         //Add gyro to adjustment
  218.         //将陀螺仪信号累加到调节量上
  219.         ail+=GainAdj(GyroRol,GainRol)+GainAdj(GyroRolI,GainPit);
  220.         ele+=GainAdj(GyroPit,GainRol)+GainAdj(GyroPitI,GainPit);
  221.         rud=RxRud/4+GainAdj(GyroYaw,GainYaw);//+GainAdj(GyroYawI,GainPit);

  222.         if(AxisMode==AXIS_CROSS)
  223.         {
  224.                  // + Mode 十字模式
  225.                 //       1  
  226.                 //     3 + 2
  227.                 //       4        
  228.                  Motor1=MotorLimitValue(thr - ele + rud);
  229.                  Motor2=MotorLimitValue(thr - ail - rud);
  230.                  Motor3=MotorLimitValue(thr + ail - rud);
  231.                  Motor4=MotorLimitValue(thr + ele + rud);
  232.         }
  233.         else
  234.         {
  235.                  // X Mode X模式
  236.                 //     1   2
  237.                 //       X
  238.                 //     3   4
  239.                  Motor1=MotorLimitValue(thr + ail - ele + rud);
  240.                  Motor2=MotorLimitValue(thr - ail - ele - rud);
  241.                  Motor3=MotorLimitValue(thr + ail + ele - rud);
  242.                  Motor4=MotorLimitValue(thr - ail + ele + rud);
  243.         }
  244. }

  245. //###############################################
  246. //
  247. //   Main routine
  248. //   主程序
  249. //
  250. void main(void)
  251. {        
  252.          Init();                                    //Board init 初始化系统
  253.         PpmWaitSignal();        //Wait rx signal, led will flash 等待接收机的信号,等待时LED闪烁
  254.         Setup();                        //Load & Adjust parameters 加载&调节参数
  255.         
  256.         //Main loop 主循环
  257.          LED0_OFF();
  258.         while(1)
  259.         {               
  260.                 TimerRst();
  261.                         CaclAttitude();        //Caculate plane attitude 计算飞行器姿态        
  262.                 TimerTo(1000);
  263.                                 
  264.                 //Do something between MotorControlBegin() and MotorControlEnd
  265.                 //See functions declaration, can not exceed 1000us
  266.                 //在MotorControlBegin()和MotorControlEnd()之间干点事儿,注意不要超过1000us
  267.                 MotorControlBegin();        //Output head of ppm signal 输出PPM信号的头部分
  268.                         PpmReadSignal();        //Read rx 读取接收机信号 140us
  269.                         if(RxThr<RxThrLow)        //If thr shutdown 如果油门关闭
  270.                         {        
  271.                                 GyroGainRead();                //Read gain 读取感度电位器 670us               
  272.                                 ArmingRoutine();        //Arm/disarm 加锁解锁测试 5us
  273.                         }
  274.                         else
  275.                         {
  276.                                 AxisMixer();                //Cacl motor signal 计算电机信号 305us
  277.                         }               
  278.                         
  279.                         //If locked(arm) or no gyro base, shutdown all motor
  280.                         //如果处于锁定态或者陀螺仪基准未建立,关闭所有马达
  281.                         if(InLock || GyroBaseCnt || RxThr<5)
  282.                         {
  283.                                   Motor1=Motor2=Motor3=Motor4=0;
  284.                         }               
  285.                         //MOTOR6_L();                        //I use it for test execute period 我用来观察执行时间的               
  286.                 MotorControlEnd();                //Output whole ppm signal 输出完整的PPM信号
  287.         }
  288. }

  289. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
KK_C_V100_M88.rar (20.32 KB, 下载次数: 146)
KK_C 使用说明v1.0.rar (421.05 KB, 下载次数: 105) (共9页)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏9 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:252798 发表于 2018-3-16 14:14 | 只看该作者
虽然刚开始学习,但很喜欢飞行器和平衡车!楼主发的是好资源!顶起!
回复

使用道具 举报

板凳
ID:283655 发表于 2019-7-8 23:34 | 只看该作者
楼主太强了!请问楼主是在哪找到的鸭?最近想做二轴,想学习一下KK的代码~
回复

使用道具 举报

地板
ID:362900 发表于 2019-7-9 10:44 | 只看该作者
感谢楼主无私分享啊!!!
回复

使用道具 举报

5#
ID:609185 发表于 2020-1-3 18:01 | 只看该作者
非常感谢你

回复

使用道具 举报

6#
ID:609185 发表于 2020-1-3 18:01 | 只看该作者
非常感谢
回复

使用道具 举报

7#
ID:698113 发表于 2020-2-25 17:20 | 只看该作者
非常感谢
回复

使用道具 举报

8#
ID:505599 发表于 2020-3-7 18:13 | 只看该作者
非常好,尝试一下
回复

使用道具 举报

9#
ID:20373 发表于 2020-6-3 23:31 | 只看该作者
感谢楼主无私分享啊!
回复

使用道具 举报

10#
ID:698113 发表于 2020-6-20 15:25 | 只看该作者
开始研究下
回复

使用道具 举报

11#
ID:701385 发表于 2020-6-21 21:33 来自手机 | 只看该作者
收藏了,留个足迹
回复

使用道具 举报

12#
ID:159157 发表于 2020-11-20 16:17 | 只看该作者
试试看 很感兴趣
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表