微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 四轴飞行器的设计之四轴主板的综合程序——STC15单片机实战指南连载

四轴飞行器的设计之四轴主板的综合程序——STC15单片机实战指南连载

时间:10-02 整理:3721RD 点击:
前面比较全面的讲述了四轴飞行器的硬件设计和软件中PID算法以及四元数与滤波算法,这节放出四轴主板的程序代码。  
例程比较复杂,这里采用了模块化编程的思路,按功能将其各个函数进行分类。笔者刚开始计划这部分的例程不贴到书上,但怕读者又说读者开源不够,与此,将完整的一套四轴源码贴到这里,做到真正的开源,起到让读者学习的目的。但读者需要注意的,该例程不像前面的小实例那样简单,读者再学习的时候,要静下心来,边读例程,边理解,同时一定要做记录,达到真正的理解。再者,便于读者调试,这里保留了笔者调试时所用的串口示波器源码,这样,可大大降低读者调试的难度,同时,所有“.c”文件对应的头文件“.h”文件,这里全部省略,里面主要是对变量和函数的声明,学到这里,对于函数的声明等,应该能熟练于心了。接下来,我们开始上菜,读者慢慢“享用”。

  1. <font face="黑体">/* =============         1        STC四轴正式版程序.c                 */
  2. #include "includes.h"
  3. #include "main.h"
  4. </font> <font face="黑体">
  5. #define Check2401  1    //2401与mcu通信检测           置0屏蔽置1开启
  6. #define ReseveData 1    //飞行器接收数据控
  7. #define OutData    1                //飞行器内部数据输出

  8. void main()
  9. {
  10.     FlyAllInit();               //飞行器各模块初始化

  11. #if Check2401
  12.     Check24L01();                 //检测2401是否正常 不正常的话串口输出error
  13. #endif        
  14.     while(1)
  15.     {         
  16.       #if ReseveData
  17.               Reseve2401();        //接收2401数据
  18.       #endif                  
  19.               
  20.           #if  OutData
  21.           OutPutData();                //输出飞机内部调试数据
  22.           #endif                        
  23.    }         
  24. }
  25.         /* =============         2        filtering.c                 */
  26. #include <STC15W4K60S4.H>
  27. #include <intrins.h>
  28. #include <NRF24L01.H>
  29. #include <MPU6050.H>
  30. #include <math.h>
  31. #include <STC15W4KPWM.H>
  32. #include <Timer.h>
  33. #include <EEPROM.h>
  34. #include <USART.h>
  35. #include <IMU.H>
  36. #include "outputdata.h"
  37. #include "stdio.h"
  38. #include "filtering.h"

  39. /*-- 3-axis accelerometer data collected from MPU --*/
  40. short Z_angle,Y_angle,X_angle;
  41. /*-- Y-axis gyroscope     data collected from MPU --*/
  42. short Y_gyro,X_gyro,Z_gyro;
  43. /*- The final angular data filtered by Kalman Filter --*/
  44. short  X_gyroInit, Y_gyroInit, Z_gyroInit;

  45. /*------- Data collection -------*/
  46. void Read_MPU()
  47. {
  48.          
  49.         Z_angle = GetData(ACCEL_ZOUT_H);;
  50.         //Z_angle = (Z_angle/8192)*9.807;         //Z-axis accelerometer
  51.          
  52.         Y_angle = GetData(ACCEL_YOUT_H);
  53.         //Y_angle = (Y_angle/8192)*9.807;         //Y-axis accelerometer
  54.          
  55.         X_angle = GetData(ACCEL_XOUT_H);
  56.         //X_angle = (X_angle/8192)*9.807;
  57.     X_gyro=xgy();
  58.         Y_gyro=ygy();
  59.         Z_gyro=zgy();
  60. </font> <font face="黑体">
  61. }

  62. static short xgy(void)
  63. {
  64.          
  65.         short i,j,k;
  66.         short tmp;
  67.    
  68.         X_gyro = GetData(GYRO_XOUT_H);;
  69.     X_gyro/= 16.4;         //X-axis accelerometer
  70.         i = X_gyro;
  71. </font> <font face="黑体">
  72.         X_gyro = GetData(GYRO_XOUT_H);;
  73.     X_gyro/= 16.4;         //X-axis accelerometer
  74.         j = X_gyro;
  75. </font> <font face="黑体">
  76.         X_gyro = GetData(GYRO_XOUT_H);
  77.     X_gyro/= 16.4;         //X-axis accelerometer
  78.         k = X_gyro;
  79.         if (i > j)
  80.         {
  81.                 tmp = i; i = j; j = tmp;
  82.         }
  83.         if (k > j)
  84.           tmp = j;
  85.         else if(k > i)
  86.           tmp = k;
  87.     else
  88.       tmp = i;
  89.         return tmp;
  90. }

  91. short ygy(void)
  92. {
  93. </font> <font face="黑体">
  94.         short i,j,k;
  95.         short tmp;
  96.          
  97.         Y_gyro = GetData(GYRO_YOUT_H);
  98.         Y_gyro/= 16.4;                                                  //Y-axis gyroscope
  99.         i = Y_gyro;
  100. </font> <font face="黑体">
  101.         Y_gyro =   GetData(GYRO_YOUT_H);
  102.         Y_gyro/= 16.4;                                                  //Y-axis gyroscope
  103.         j = Y_gyro;
  104. </font> <font face="黑体">
  105.         Y_gyro =   GetData(GYRO_YOUT_H);;
  106.         Y_gyro/= 16.4;                                                  //Y-axis gyroscope
  107.         k = Y_gyro;
  108.         if (i > j)
  109.         {
  110.                 tmp = i; i = j; j = tmp;
  111.         }
  112.         if (k > j)
  113.           tmp = j;
  114.         else if(k > i)
  115.           tmp = k;
  116.     else
  117.       tmp = i;
  118.         return tmp;
  119. }

  120. short zgy(void)
  121. {
  122. </font> <font face="黑体">
  123.         short i,j,k;
  124.         short tmp;
  125. </font> <font face="黑体">
  126.         Z_gyro =  GetData(GYRO_ZOUT_H);;
  127.         Z_gyro/= 16.4;
  128.         i = Z_gyro;
  129. </font> <font face="黑体">
  130.         Z_gyro =  GetData(GYRO_ZOUT_H);
  131.         Z_gyro/= 16.4;
  132.         j = Z_gyro;
  133. </font> <font face="黑体">
  134.         Z_gyro =  GetData(GYRO_ZOUT_H);
  135.         Z_gyro/= 16.4;
  136.         k = Z_gyro;
  137.         if (i > j)
  138.         {
  139.                 tmp = i; i = j; j = tmp;
  140.         }
  141.         if (k > j)
  142.           tmp = j;
  143.         else if(k > i)
  144.           tmp = k;
  145.     else
  146.       tmp = i;
  147.         return tmp;
  148. }
  149. void Delay1ms()                //@30.000MHz
  150. {
  151.         unsigned char i, j;

  152.         i = 30;
  153.         j = 43;
  154.         do
  155.         {
  156.                 while (--j);
  157.         } while (--i);
  158. }
  159. void gyro_init(void)
  160. {
  161.         int i=0;
  162.         int x,y,z;
  163.         short a,b,c;
  164.         for(i=0;i<100;i++)
  165.         {        
  166.                 a=xgy() ;
  167.                 b=ygy() ;
  168.                 c=zgy() ;
  169.                 x=x+a;
  170.                 y=y+b;
  171.                 z=z+c;
  172.                 Delay1ms();
  173.         }
  174.     X_gyroInit=x/100;
  175.     Y_gyroInit=y/100;
  176.     Z_gyroInit=z/100;
  177. }
  178.         /* =============         3        control.c                 */
  179. #include <STC15W4K60S4.H>
  180. #include <intrins.h>
  181. #include <NRF24L01.H>
  182. #include <MPU6050.H>
  183. #include <math.h>
  184. #include <STC15W4KPWM.H>
  185. #include <Timer.h>
  186. #include <EEPROM.h>
  187. #include <USART.h>
  188. #include <IMU.H>
  189. #include "outputdata.h"
  190. #include "stdio.h"
  191. #include "filtering.h"
  192. #include "control.h"
  193. #include "includes.h"

  194. extern  unsigned char RXBUF[8];
  195. extern  float Pitch;   //x
  196. extern  float Roll;    //y
  197. extern  float Average_Gx,Average_Gy,Average_Gz  ;
  198. extern  int key;
  199. unsigned int Controldata_THROTTLE_Set=0;//1880-50-50-100+30;
  200. //************************************************
  201. int  Controldata_THROTTLE=0  ;         //?
  202. int  Controldata_PITCH   =0  ;         //?
  203. int  Controldata_ROLL    =0  ;         //?
  204. int  Controldata_YAW     =0  ;         //?
  205. int  Controldata_OFFSET  =0  ;         //?
  206. unsigned int   ControlNum=0  ;
  207. //************************************************   
  208. float  IUX=0.0,IUY=0.0;                              
  209. float  COUT_PITCHZ,COUT_PITCHF,COUT_ROLLZ,COUT_ROLLF;

  210. float PWM_XZ,PWM_XF,PWM_YZ,PWM_YF;//?pwm?
  211. float Yaw1=0;

  212. //*************************************************
  213. void MainControl()
  214. {
  215.         Get_Control_Data() ;
  216.         Control();
  217. }
  218. //=============================================================
  219. float Controldata_ROLLleft=0,Controldata_ROLLright=0;
  220. float  Controldata_PITCHfront=0, Controldata_PITCHback=0;
  221. int error=0;
  222. extern int keyk;
  223. extern unsigned int s;
  224. int ss=0;

  225. void Get_Control_Data()
  226. {
  227.         float a=0,b=530,c=521,d=527;
  228.         if(keyk==1)
  229.         {
  230.                 d =    RXBUF[0]*16+RXBUF[1];         //oá1?
  231.                 b =    RXBUF[2]*16+RXBUF[3];         //?
  232.                 c =    RXBUF[4]*16+RXBUF[5];         //?o?
  233.                 a =    RXBUF[6]*16+RXBUF[7];         //óí?
  234.         //*********************脱控保护******************************        
  235.                 if(error==1)
  236.                 {
  237.                         if(ss==0)
  238.                         {ss=s;}
  239.                         a=a-(s-ss)*20;
  240.                 }         
  241.                 else
  242.                 ss=0;
  243.         }
  244.         //***********************************************************
  245.         if(a>1024)
  246.         {a=1024;}
  247.         a= a/1024.0 ;

  248.         if((b>=530&b<=540)||(b<=530&b>=520))
  249.         {b=530;}
  250.         b=b-530;
  251.         if(b>0)
  252.         {b=b/494.0;}
  253.         else
  254.         {b=b/530.0;}

  255.         if((c>=521&c<=531)||(c<=521&c>=511))
  256.         {c=521.0;}
  257.         c=c-521;
  258.         if(c>0)
  259.         {c=c/523.0;}
  260.         else
  261.         {c=c/521.0;}

  262.         if((d>=517&d<=527)||(d<=537&d>=527))
  263.         {d=527;}
  264.         d=d-527;
  265.         if(d>0)
  266.         {d=d/507.0;}
  267.         else
  268.         {d=d/527.0;}
  269.                                                                           
  270.         if(b>1)
  271.          b=1;
  272.         else if(b<-1)
  273.          b=-1;
  274.         //-------------
  275.         if(c>1)
  276.          c=1;
  277.         else if(c<-1)
  278.          c=-1;
  279.         //-------------
  280.         if(d>1)
  281.          d=1;
  282.         else if(d<-1)
  283.          d=-1;  
  284.         /*****************************/                                       
  285.         Controldata_THROTTLE=a*2400;
  286.         Controldata_PITCH=  b*20;
  287.         Controldata_YAW =   c*180;
  288.         Controldata_ROLL =  d*20;
  289.                
  290.         if( Controldata_PITCH>0)
  291.         {Controldata_PITCHfront=0 ,Controldata_PITCHback=         Controldata_PITCH;}
  292.         else
  293.         {Controldata_PITCHfront=Controldata_PITCH ,Controldata_PITCHb        ack= 0;}
  294.                  
  295.         if(Controldata_ROLL>0)
  296.         {
  297.                  Controldata_ROLLleft=0;
  298.                 Controldata_ROLLright=Controldata_ROLL;
  299.         }
  300.         else
  301.         {
  302.                 Controldata_ROLLleft=Controldata_ROLL;
  303.                 Controldata_ROLLright=0;
  304.         }
  305. }

  306. extern float IntegralZ;
  307. #define MINPWM 0
  308. #define MAXPWM 2699

  309. void Control(void)
  310. {
  311.         float  EX0=0.0,EX1=0.0,EY0=0.0,EY1=0.0;      
  312.         //-----------------------------  
  313.         float PID_P_Y , PID_D_Y ;//, PID_I_Y;
  314.         float PID_P_X , PID_D_X ;//, PID_I_X;
  315.         float PID_P_Z , PID_D_Z;
  316.         /***********************整定PID***************************/
  317.         EX0=Pitch;  
  318.         
  319.         EY0=Roll;
  320.         //********************************************************
  321.         PID_P_Y=3.2;//4;//4.0;//3.1;  
  322.         PID_D_Y=1.2;//0.4; 0.45; 0.43; 2.85; 0.6; 0.815+0.1; 0.86;

  323.         PID_P_X=3.2;//3.2;;//4;//3.0;//9.41;//15-1-1-0.4;
  324.         PID_D_X=1.2;//1.2;//1.2;//0.4;//0.4;//0.45;//0.6;//2.85;
  325.         //0.6;//2.515;//1.555+1+0.3+0.2;

  326.         PID_P_Z=0;//5;//0.2;
  327.         PID_D_Z=0;//0.03;
  328.         /**********************************************************/
  329.         Yaw1=PID_P_Z*(IntegralZ-Controldata_YAW)+PID_D_Z* Average_Gz;
  330.         if(Yaw1>300)
  331.         {Yaw1=300;}
  332.         else if(Yaw1<-300)
  333.         {Yaw1=-300;}
  334.         /*********************************************************/
  335. PWM_XF= (float)(Controldata_THROTTLE)- (EX0-
  336. Controldata_PITCHfront)*PID_P_X + (Average_Gy)*PID_D_X  -
  337. (EY0-Controldata_ROLLleft)*PID_P_Y-(Average_Gx)*PID_D_Y +Yaw1;
  338.     PWM_YF=(float)(Controldata_THROTTLE)-(EX0-
  339.         Controldata_PITCHfront)*PID_P_X + (Average_Gy)*PID_D_X  + (EY0-
  340.         Controldata_ROLLright)*PID_P_Y+(Average_Gx)*PID_D_Y -Yaw1;  
  341. PWM_XZ=(float)(Controldata_THROTTLE)+ (EX0-
  342. Controldata_PITCHback)*PID_P_X - (Average_Gy)*PID_D_X  - (EY0-
  343. Controldata_ROLLleft)*PID_P_Y-(Average_Gx)*PID_D_Y  -Yaw1;  
  344.         PWM_YZ=(float)(Controldata_THROTTLE)+ (EX0-
  345.         Controldata_PITCHback)*PID_P_X – (Average_Gy)*PID_D_X + (EY0-
  346.         Controldata_ROLLright)*PID_P_Y+(Average_Gx)*PID_D_Y +Yaw1;
  347.         //**********************************************************
  348.         #if 1         // 方便调试
  349.          if(Controldata_THROTTLE<30)
  350.          {
  351.                  PWM_XF=PWM_YF= PWM_XZ= PWM_YZ=0;
  352.                 IntegralZ=0;
  353.                 PWM(0,0,0,0) ;
  354.          }
  355.         #endif

  356.         if( PWM_XZ<MINPWM)
  357.          PWM_XZ=MINPWM;
  358.         else if( PWM_XZ>MAXPWM)
  359.          PWM_XZ=MAXPWM;

  360.         if( PWM_XF<MINPWM)
  361.          PWM_XF=MINPWM;
  362.         else if( PWM_XF>MAXPWM)
  363.          PWM_XF=MAXPWM;

  364.         if( PWM_YZ<MINPWM)
  365.          PWM_YZ=MINPWM;
  366.         else if( PWM_YZ>MAXPWM)
  367.          PWM_YZ=MAXPWM;

  368.         if( PWM_YF<MINPWM)
  369.          PWM_YF=MINPWM;
  370.         else if( PWM_YF>MAXPWM)
  371.          PWM_YF=MAXPWM;
  372.         /**********************************************/
  373.         PWM(PWM_XZ,PWM_XF,PWM_YF,PWM_YZ) ;
  374. }
  375.         /* =============         4        spi.c                 */
  376. #include "includes.h"
  377. #include "spi.h"
  378. #include <STC15W4K60S4.H>
  379. typedef bit BOOL;
  380. typedef unsigned char BYTE;
  381. typedef unsigned short WORD;
  382. typedef unsigned long DWORD;

  383. #define FOSC            11059200L
  384. #define BAUD            (65536 - FOSC / 4 / 115200)

  385. #define null           0
  386. #define FALSE           0
  387. #define TRUE            1

  388. //sfr  AUXR           =   0x8e;      //辅助寄存器
  389. //sfr P_SW1           =   0xa2;      //外设功能切换寄存器1
  390. #define SPI_S0          0x04
  391. #define SPI_S1          0x08

  392. //sfr SPSTAT          =   0xcd;                   //SPI状态寄存器
  393. #define SPIF            0x80                    //SPSTAT.7
  394. #define WCOL            0x40                    //SPSTAT.6
  395. //sfr SPCTL           =   0xce;                   //SPI控制寄存器
  396. #define SSIG            0x80                    //SPCTL.7
  397. #define SPEN            0x40                    //SPCTL.6
  398. #define DORD            0x20                    //SPCTL.5
  399. #define MSTR            0x10                    //SPCTL.4
  400. #define CPOL            0x08                    //SPCTL.3
  401. #define CPHA            0x04                    //SPCTL.2
  402. #define SPDHH           0x00                    //CPU_CLK/4
  403. #define SPDH            0x01                    //CPU_CLK/16
  404. #define SPDL            0x02                    //CPU_CLK/64
  405. #define SPDLL           0x03                    //CPU_CLK/128
  406. //sfr SPDAT           =   0xcf;                   //SPI数据寄存器

  407. //sbit SS             =   P2^4;                   //SPI的SS脚,连接到Flash的CE

  408. #define SFC_WREN        0x06                    //串行Flash命令集
  409. #define SFC_WRDI        0x04
  410. #define SFC_RDSR        0x05
  411. #define SFC_WRSR        0x01
  412. #define SFC_READ        0x03
  413. #define SFC_FASTREAD    0x0B
  414. #define SFC_RDID        0xAB
  415. #define SFC_PAGEPROG    0x02
  416. #define SFC_RDCR        0xA1
  417. #define SFC_WRCR        0xF1
  418. #define SFC_SECTORER    0xD7
  419. #define SFC_BLOCKER     0xD8
  420. #define SFC_CHIPER      0xC7

  421. void InitSpi();
  422. BYTE SpiShift(BYTE dat);

  423. void InitSpi()
  424. {
  425.   ACC = P_SW1;                                       //切换到第一组SPI
  426.   ACC &= ~(SPI_S0 | SPI_S1);           //SPI_S0=0 SPI_S1=0
  427.   P_SW1 = ACC;            //(P1.2/SS, P1.3/MOSI, P1.4/MISO, P1.5/SCLK)

  428.     SPSTAT = SPIF | WCOL;                 //清除SPI状态
  429.     SPCTL = SSIG | SPEN | MSTR;    //设置SPI为主模式
  430.         IE2&=0XFC;
  431. }

  432. /************************************************
  433. 使用SPI方式与Flash进行数据交换
  434. 入口参数:
  435.     dat : 准备写入的数据
  436. 出口参数:
  437.     从Flash中读出的数据
  438. ************************************************/
  439. BYTE SpiShift(BYTE dat)
  440. {
  441.     SPDAT = dat;                          // 触发SPI发送
  442.     while (!(SPSTAT & SPIF));          // 等待SPI数据传输完成
  443.     SPSTAT = SPIF | WCOL;                         // 清除SPI状态
  444.    
  445.     return SPDAT;
  446. }
  447.         /* =============         5        NRF24L01.c                 */
  448. #include <STC15W4K60S4.H>
  449. #include "nrf24l01.h"
  450. #include "spi.h"
  451. </font> <font face="黑体">
  452. const unsigned char TX_ADDRESS[TX_ADR_WIDTH]=
  453.                                                 {0x34,0x43,0x10,0x10,0x01};
  454. const unsigned char RX_ADDRESS[RX_ADR_WIDTH]=
  455.                                                 {0x34,0x43,0x10,0x10,0x01};

  456. void NRF24L01_Init(void)
  457. {
  458.     InitSpi();
  459.         NRF24L01_CE=0;
  460.         NRF24L01_CSN=1;        
  461. }

  462. unsigned char NRF24L01_Check(void)
  463. {
  464.     unsigned char buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
  465.         unsigned char i;
  466.          
  467.         NRF24L01_Write_Buf(WRITE_REG1+TX_ADDR,buf,5);         
  468.         NRF24L01_Read_Buf(TX_ADDR,buf,5);   
  469.         for(i=0;i<5;i++) if(buf[i]!=0XA5) break;                                                                    
  470.         if(i!=5) return 1;
  471.         return 0;                 
  472. }                  

  473. unsigned char  NRF24L01_Write_Reg(unsigned char  reg,unsigned char  value)
  474. {
  475.         unsigned char  status;        
  476.            NRF24L01_CSN=0;
  477.           status =SpiShift(reg);
  478.           SpiShift(value);
  479.           NRF24L01_CSN=1;  
  480.           return(status);               
  481. }
  482. </font> <font face="黑体">
  483. unsigned char NRF24L01_Read_Reg(unsigned char reg)
  484. {
  485.         unsigned char  reg_val;            
  486.          NRF24L01_CSN = 0;
  487.           SpiShift(reg);
  488.           reg_val=SpiShift(0XFF);
  489.           NRF24L01_CSN = 1;                    
  490.           return(reg_val);
  491. }        
  492. </font> <font face="黑体">
  493. unsigned char NRF24L01_Read_Buf(unsigned char  reg,unsigned char  *pBuf,unsigned char  len)
  494. {
  495.         unsigned char  status,u8_ctr;               
  496.           NRF24L01_CSN = 0;
  497.           status=SpiShift(reg);           
  498.          for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SpiShift(0XFF);
  499.           NRF24L01_CSN=1;
  500.           return status;
  501. }

  502. unsigned char  NRF24L01_Write_Buf(unsigned char  reg, unsigned char  *pBuf, unsigned char  len)
  503. {
  504.         unsigned char  status,u8_ctr;            
  505.          NRF24L01_CSN = 0;
  506.           status = SpiShift(reg);
  507.           for(  u8_ctr=0; u8_ctr<len; u8_ctr++)SpiShift(*pBuf++);
  508.           NRF24L01_CSN = 1;
  509.           return status;
  510. }                                   

  511. unsigned char  NRF24L01_TxPacket(unsigned char  *txbuf)
  512. {
  513.         unsigned char  sta;
  514.    
  515.         NRF24L01_CE=0;
  516.           NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);
  517.          NRF24L01_CE=1;
  518.         while(NRF24L01_IRQ!=0);
  519.         sta=NRF24L01_Read_Reg(STATUS);           
  520.         NRF24L01_Write_Reg(WRITE_REG1+STATUS,sta);
  521.         if(sta&MAX_TX)
  522.         {
  523.                 NRF24L01_Write_Reg(FLUSH_TX,0xff);
  524.                 return MAX_TX;
  525.         }
  526.         if(sta&TX_OK)
  527.         {
  528.                 return TX_OK;
  529.         }
  530.         return 0xff;
  531. }

  532. unsigned char  NRF24L01_RxPacket(unsigned char  *rxbuf)
  533. {
  534.         unsigned char  sta;                                                                              
  535.   
  536.         sta=NRF24L01_Read_Reg(STATUS);            
  537.         NRF24L01_Write_Reg(WRITE_REG1+STATUS,sta);
  538.         if(sta&RX_OK)
  539.         {
  540.                 NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);
  541.                 NRF24L01_Write_Reg(FLUSH_RX,0xff);
  542.                 return 0;
  543.         }           
  544.         return 1;
  545. }                                            
  546.            
  547. void RX_Mode(void)
  548. {
  549.         NRF24L01_CE=0;         
  550.           NRF24L01_Write_Buf(WRITE_REG1+RX_ADDR_P0,(unsigned         char*)RX_ADDRESS,RX_ADR_WIDTH);
  551.          
  552.           NRF24L01_Write_Reg(WRITE_REG1+EN_AA,0x01);   
  553.           NRF24L01_Write_Reg(WRITE_REG1+EN_RXADDR,0x01);
  554.           NRF24L01_Write_Reg(WRITE_REG1+RF_CH,40);                  
  555.           NRF24L01_Write_Reg(WRITE_REG1+RX_PW_P0,RX_PLOAD_WIDTH);   
  556.           NRF24L01_Write_Reg(WRITE_REG1+RF_SETUP,0x0f);  
  557.           NRF24L01_Write_Reg(WRITE_REG1+CONFIG1, 0x0f);
  558.           NRF24L01_CE = 1;
  559. }                                                
  560.          
  561. void TX_Mode(void)
  562. {                                                                                                                 
  563.         NRF24L01_CE=0;            
  564.           NRF24L01_Write_Buf(WRITE_REG1+TX_ADDR,(unsigned         char*)TX_ADDRESS,TX_ADR_WIDTH);
  565.           NRF24L01_Write_Buf(WRITE_REG1+RX_ADDR_P0,(unsigned         char*)RX_ADDRESS,RX_ADR_WIDTH);         

  566.           NRF24L01_Write_Reg(WRITE_REG1+EN_AA,0x01);
  567.           NRF24L01_Write_Reg(WRITE_REG1+EN_RXADDR,0x01);
  568.           NRF24L01_Write_Reg(WRITE_REG1+SETUP_RETR,0x1a);
  569.           NRF24L01_Write_Reg(WRITE_REG1+RF_CH,40);
  570.           NRF24L01_Write_Reg(WRITE_REG1+RF_SETUP,0x0f);
  571.           NRF24L01_Write_Reg(WRITE_REG1+CONFIG1,0x0e);
  572.         NRF24L01_CE=1;
  573. }                  
  574.         /* =============         6        AllInit.c                 */
  575. #include "includes.h"
  576. #include "AllInit.h"
  577. #include "main.h"

  578. #define RemoteControlData 0                //串口输出遥控器发送数值使能
  579. #define AttitudeData      1                        //串口输出姿态值使能
  580. #define RollData          1                        //输出y轴姿态
  581. #define PitchData         0                        //输出x轴姿态

  582. unsigned char RXBUF[33]={0,0,0,0,0,0,0,0};          //2401数据存储区
  583. int keyk=0;
  584. int ee=0;

  585. /************************************************
  586. 函数功能:检测2401与单片机通信是否正常
  587. *************************************************/
  588. void Check24L01()
  589. {
  590.     while( NRF24L01_Check())
  591.         {   
  592.                 printf("24l01 is error,please replacement 24l01 module! \n");
  593.                 delayms__(100);
  594.         }
  595.         printf ("24l01 is ok!\n");
  596. }
  597. /************************************************
  598. 函数功能:初始化飞行器各个模块
  599. *************************************************/
  600. void FlyAllInit()
  601. {
  602.    delayms_(100);
  603.    InitMPU6050();                              //初始化MPU-6050
  604.    Usart_Init();                  //初始化串口
  605.    PWMGO();                               //初始化PWM
  606.    NRF24L01_Init();                        //初始化2401
  607.    RX_Mode();                                        //设为接收模式
  608.    Time0_Init();             //初始化定时器
  609.    printf ("All module is ok!\n Get ready to fly!\n");
  610. }
  611. /************************************************
  612. 函数功能:飞行器接收2401数据
  613. *************************************************/
  614. void Reseve2401(void)
  615. {
  616.         if(NRF24L01_RxPacket(RXBUF)==0)        
  617.         {
  618.                 if((RXBUF[6]*16+RXBUF[7])<30)
  619.                 {keyk=1;}
  620.                 ee=0;error=0;
  621.                 RXBUF[32]=0;
  622.         }
  623.         else
  624.         {  
  625.                 if(keyk==1)
  626.                 ee++;
  627.         }
  628.         if(ee>=200)
  629.         {error=1;}
  630. }

  631. /************************************************
  632. 函数功能:飞行器输出内部数据
  633. *************************************************/
  634. void OutPutData()
  635. {
  636. //遥控器数值输出
  637. #if RemoteControlData
  638.         OutData[0]=    RXBUF[0]*16+RXBUF[1];  //横滚        
  639.         OutData[1]=    RXBUF[2]*16+RXBUF[3];  //俯仰        
  640.         OutData[2]=    RXBUF[4]*16+RXBUF[5];  //偏航        
  641.         OutData[3]=    RXBUF[6]*16+RXBUF[7];  //油门      
  642.         OutPut_Data();        
  643. #endif                                         
  644. //姿态输出
  645. #if AttitudeData
  646.         #if        PitchData
  647.                 OutData[0] = Pitch;
  648.                 OutData[1] = X_angle;
  649.                 OutData[2] = Average_Gy;
  650.                 // OutData[3] = A_angle_Y;;
  651.                 OutPut_Data();
  652.         #endif
  653.         #if RollData
  654.                 OutData[0] = Roll;
  655.                 OutData[1] = Y_angle;
  656.                 OutData[2] = Average_Gx;
  657.                 // OutData[3] = A_angle_Y;;
  658.                 OutPut_Data();
  659.         #endif  
  660. #endif  
  661. }
  662. /************************************************
  663. 函数名称:MotorTest()
  664. 函数功能:飞行器电机测试
  665. *************************************************/
  666. void MotorTest(void)
  667. {
  668.         //数值设定 0~2700;同时要屏蔽IMU.c 中断里面的MainControl
  669.         PWM(0,0,0,0);
  670. }

  671. void Delay100us()                //@30.000MHz
  672. {
  673.         unsigned char i, j;

  674.         i = 3;
  675.         j = 232;
  676.         do
  677.         {
  678.                 while (--j);
  679.         } while (--i);
  680. }

  681. void delayms__(int ms)
  682. {
  683.   int x,y;
  684.   for(x=ms;x>0;x--)
  685.   {
  686.    for(y=1000;y>0;y--)
  687.     ;
  688.   }
  689. }
  690. /* =============         7        MPU-6050.c                 */
  691. #include <STC15W4K60S4.H>
  692. #include <intrins.h>
  693. #include <MPU6050.H>
  694. #include <NRF24L01.H>
  695. #define  uchar        unsigned char
  696. sbit    SCL=P3^4;                        //IIC时钟引脚定义    Rev8.0硬件
  697. sbit    SDA=P3^5;                        //IIC数据引脚定义
  698. void  InitMPU6050();                                                                                //初始化MPU6050
  699. void  Delay2us();
  700. void  I2C_Start();
  701. void  I2C_Stop();

  702. bit   I2C_RecvACK();

  703. void  I2C_SendByte(unsigned char dat);
  704. uchar I2C_RecvByte();

  705. void  I2C_ReadPage();
  706. void  I2C_WritePage();
  707. uchar Single_ReadI2C(uchar REG_Address);        //读取I2C数据
  708. void  Single_WriteI2C(uchar REG_Address,uchar REG_data);        
  709. //向I2C写入数据
  710. //I^C时序中延时设置,具体参见各芯片的数据手册  6050推荐最小1.3us 但是会出问题,这里延时实际1.9us左右
  711. void Delay2us()                //@27.000MHz
  712. {
  713.         unsigned char i;

  714.         i = 11;
  715.         while (--i);
  716. }
  717. //**************************************
  718. //I2C起始信号
  719. //**************************************
  720. void I2C_Start()
  721. {
  722.     SDA = 1;                    //拉高数据线
  723.     SCL = 1;                    //拉高时钟线
  724.     Delay2us();                 //延时
  725.     SDA = 0;                    //产生下降沿
  726.     Delay2us();                 //延时
  727.     SCL = 0;                    //拉低时钟线
  728. }
  729. //**************************************
  730. //I2C停止信号
  731. //**************************************
  732. void I2C_Stop()
  733. {
  734.     SDA = 0;                    //拉低数据线
  735.     SCL = 1;                    //拉高时钟线
  736.     Delay2us();                 //延时
  737.     SDA = 1;                    //产生上升沿
  738.     Delay2us();                 //延时
  739. }
  740. //**************************************
  741. //I2C接收应答信号
  742. //**************************************
  743. bit I2C_RecvACK()
  744. {
  745.     SCL = 1;                    //拉高时钟线
  746.     Delay2us();                 //延时
  747.     CY = SDA;                   //读应答信号
  748.     SCL = 0;                    //拉低时钟线
  749.     Delay2us();                 //延时
  750.     return CY;
  751. }
  752. //**************************************
  753. //向I2C总线发送一个字节数据
  754. //**************************************
  755. void I2C_SendByte(uchar dat)
  756. {
  757.     uchar i;
  758.     for (i=0; i<8; i++)         //8位计数器
  759.     {
  760.         dat <<= 1;              //移出数据的最高位
  761.         SDA = CY;               //送数据口
  762.         SCL = 1;                //拉高时钟线
  763.         Delay2us();             //延时
  764.         SCL = 0;                //拉低时钟线
  765.         Delay2us();             //延时
  766.     }
  767.     I2C_RecvACK();
  768. }
  769. //**************************************
  770. //从I2C总线接收一个字节数据
  771. //**************************************
  772. uchar I2C_RecvByte()
  773. {
  774.     uchar i;
  775.     uchar dat = 0;
  776.     SDA = 1;                    //使能内部上拉,准备读取数据,
  777.     for (i=0; i<8; i++)         //8位计数器
  778.     {
  779.         dat <<= 1;
  780.         SCL = 1;                //拉高时钟线
  781.         Delay2us();             //延时
  782.         dat |= SDA;             //读数据
  783.         SCL = 0;                //拉低时钟线
  784.         Delay2us();             //延时
  785.     }
  786.     return dat;
  787. }
  788. //**************************************
  789. //向I2C设备写入一个字节数据
  790. //**************************************
  791. void Single_WriteI2C(uchar REG_Address,uchar REG_data)
  792. {
  793.     I2C_Start();                  //起始信号
  794.     I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
  795.     I2C_SendByte(REG_Address);    //内部寄存器地址,
  796.     I2C_SendByte(REG_data);       //内部寄存器数据,
  797.     I2C_Stop();                   //发送停止信号
  798. }
  799. //**************************************
  800. //从I2C设备读取一个字节数据
  801. //**************************************
  802. uchar Single_ReadI2C(uchar REG_Address)
  803. {
  804.         uchar REG_data;
  805.         I2C_Start();                   //起始信号
  806.         I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
  807.         I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始
  808.         I2C_Start();                   //起始信号
  809.         I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
  810.         REG_data=I2C_RecvByte();       //读出寄存器数据
  811.         
  812.         SDA = 1;                    //写应答信号
  813.         SCL = 1;                    //拉高时钟线
  814.         Delay2us();                 //延时
  815.         SCL = 0;                    //拉低时钟线
  816.         Delay2us();                 //延时
  817.         
  818.         I2C_Stop();                    //停止信号
  819.         return REG_data;
  820. }

  821. //**************************************
  822. //初始化MPU6050
  823. //**************************************
  824. void InitMPU6050()
  825. {
  826.         Single_WriteI2C(PWR_MGMT_1, 0x00);        //解除休眠状态
  827.         Single_WriteI2C(SMPLRT_div, 0x07);  //陀螺仪125hz
  828.         Single_WriteI2C(CONFIG, 0x06);      //21HZ滤波 延时A8.5ms G8.3ms  
  829.         //此处取值应相当注意,延时与系统周期相近为宜
  830.         Single_WriteI2C(GYRO_CONFIG, 0x18); //陀螺仪500度/S 65.5LSB/g
  831.         Single_WriteI2C(ACCEL_CONFIG, 0x01);//加速度+-4g  8192LSB/g
  832. }
  833. //**************************************
  834. //合成数据
  835. //**************************************
  836. int GetData(uchar REG_Address)
  837. {
  838.         char H,L;
  839.         H=Single_ReadI2C(REG_Address);
  840.         L=Single_ReadI2C(REG_Address+1);
  841.         return (H<<8)+L;   //合成数据
  842. }
  843. /* =============         8        IMU.c                

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top