找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8346|回复: 6
收起左侧

mpu6050六轴传感器msp430驱动程序

[复制链接]
ID:90014 发表于 2015-9-14 12:12 | 显示全部楼层 |阅读模式
  1. #include <msp430g2553.h>
  2. #include"mpu6050.h"
  3. #include "USCI_A0.h"
  4. #include "IMU.h "
  5. /*
  6. *  ======== BCSplus_graceInit ========
  7. *  Initialize MSP430 Basic Clock System
  8. */
  9. void BCSplus_graceInit(void)
  10. {
  11.     /* USER CODE START (section: BCSplus_graceInit_prologue) */
  12.     /* User initialization code */
  13.     /* USER CODE END (section: BCSplus_graceInit_prologue) */

  14.     /*
  15.      * Basic Clock System Control 2
  16.      *
  17.      * SELM_0 -- DCOCLK
  18.      * DIVM_0 -- Divide by 1
  19.      * ~SELS -- DCOCLK
  20.      * DIVS_1 -- Divide by 2
  21.      * ~DCOR -- DCO uses internal resistor
  22.      *
  23.      * Note: ~<BIT> indicates that <BIT> has value zero
  24.      */
  25.     BCSCTL2 = SELM_0 | DIVM_0 | DIVS_1;

  26.     if (CALBC1_16MHZ != 0xFF) {
  27.         /* Adjust this accordingly to your VCC rise time */
  28.         __delay_cycles(100000);

  29.         /* Follow recommended flow. First, clear all DCOx and MODx bits. Then
  30.          * apply new RSELx values. Finally, apply new DCOx and MODx bit values.
  31.          */
  32.         DCOCTL = 0x00;
  33.         BCSCTL1 = CALBC1_16MHZ;     /* Set DCO to 16MHz */
  34.         DCOCTL = CALDCO_16MHZ;
  35.     }

  36.     /*
  37.      * Basic Clock System Control 1
  38.      *
  39.      * XT2OFF -- Disable XT2CLK
  40.      * ~XTS -- Low Frequency
  41.      * DIVA_0 -- Divide by 1
  42.      *
  43.      * Note: ~XTS indicates that XTS has value zero
  44.      */
  45.     BCSCTL1 |= XT2OFF | DIVA_0;

  46.     /*
  47.      * Basic Clock System Control 3
  48.      *
  49.      * XT2S_0 -- 0.4 - 1 MHz
  50.      * LFXT1S_0 -- If XTS = 0, XT1 = 32768kHz Crystal ; If XTS = 1, XT1 = 0.4 - 1-MHz crystal or resonator
  51.      * XCAP_1 -- ~6 pF
  52.      */
  53.     BCSCTL3 = XT2S_0 | LFXT1S_0 | XCAP_1;

  54.     /* USER CODE START (section: BCSplus_graceInit_epilogue) */
  55.     /* User code */
  56.     /* USER CODE END (section: BCSplus_graceInit_epilogue) */
  57. }/*
  58. * main.c
  59. */
  60. int main(void)
  61. {
  62.     WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer
  63.     BCSplus_graceInit();        //MCLK = 16M,SMCLK = 8M,ack =32.768k
  64.     WDTCTL = WDTPW | WDTTMSEL | WDTIS0;
  65.     IE1 |= WDTIE;
  66.     USCI_A0_init();             //uart 38400bps  
  67.     P1DIR |= BIT0;              //initialize led control PIN
  68.     _EINT();
  69.     MPU6050_Init();             //initialize mpu6050
  70.    
  71.     while(1)
  72.     {
  73.       /*
  74.       Get_Attitude();
  75.      //MPU6050_Dataanl();
  76.      // ReadMPU6050All();
  77.      //Prepare_Data();             //耗时6.15ms
  78.      //Uart1_Send_AF();             //耗时8.42ms
  79.      P1OUT ^= BIT0;
  80.      Get_Attitude();
  81.      //ReadMPU6050All();
  82.      //MPU6050_Dataanl();         //未使用多字节读取,耗时6ms,使用多字节读取,耗时3.6ms
  83.      //Prepare_Data();
  84.     // Uart1_Send_AF();
  85.      P1OUT ^= BIT0;
  86.      */
  87.     }
  88.    
  89. }

  90. //watchdog interrupt server program per 1ms
  91. #pragma vector=WDT_VECTOR
  92. __interrupt void WDT_ISR_HOOK(void)
  93. {
  94.     /* USER CODE START (section: WDT_ISR_HOOK) */
  95.     /* replace this comment with your code */
  96.     static unsigned int count=0;
  97.     static unsigned char ms2 = 0,ms5 = 0,ms10 = 0;
  98.     count++;
  99.     ms2++;
  100.     ms5++;
  101.     ms10++;
  102.    
  103.     if(ms2 == 2)
  104.     {
  105.      ms2 = 0;
  106.      Prepare_Data();
  107.      //MPU6050_Dataanl();
  108.     }
  109.     if(ms5 >= 4)
  110.     {
  111.       ms5 = 0;
  112.       Get_Attitude();
  113.    
  114.     }
  115.     if(ms10 >= 10)
  116.     {
  117.       ms10 = 0;
  118.       Uart1_Send_AF();
  119.     }
  120.     if(count== 200)
  121.     {
  122.       count=0;
  123.       P1OUT ^= BIT0;
  124.     }

  125.         /* USER CODE END (section: WDT_ISR_HOOK) */
  126. }



  127. /*
  128. * This file contains some mpu6050 operation.
  129. * By IC爬虫 (1394024051@qq.com)
  130. * 2014-4-13 v1.0
  131. */
  132. #include "mpu6050.h"

  133. unsigned char   mpu6050_buffer[14];     //I2C读取后存放数据

  134. int ACC_OFFSET_X,ACC_OFFSET_Y,ACC_OFFSET_Z;
  135. int GYRO_OFFSET_X,GYRO_OFFSET_Y,GYRO_OFFSET_Z;

  136. unsigned char        GYRO_OFFSET_OK = 1;
  137. unsigned char        ACC_OFFSET_OK = 1;

  138. int MPU6050_ACC_LAST_X,MPU6050_ACC_LAST_Y,MPU6050_ACC_LAST_Z;    //final accelerate speed
  139. int MPU6050_GYRO_LAST_X,MPU6050_GYRO_LAST_Y,MPU6050_GYRO_LAST_Z; //final  gyro  speed

  140. /**********************************************************/
  141. //函数名称:void MPU6050_Dataanl
  142. //入口参数:无
  143. //出口参数:无
  144. //函数功能:MPU6050数据读取并处理
  145. /**********************************************************/
  146. void MPU6050_Dataanl(void)
  147. {
  148. #ifndef READALL
  149.   MPU6050_ACC_LAST_X = GetAccelX() - ACC_OFFSET_X;
  150.   MPU6050_ACC_LAST_Y = GetAccelY() - ACC_OFFSET_Y;
  151.   MPU6050_ACC_LAST_Z = GetAccelZ() - ACC_OFFSET_Z;
  152.   
  153.   MPU6050_GYRO_LAST_X = GetAnguX() - GYRO_OFFSET_X;
  154.   MPU6050_GYRO_LAST_Y = GetAnguY() - GYRO_OFFSET_Y;
  155.   MPU6050_GYRO_LAST_Z = GetAnguZ() - GYRO_OFFSET_Z;
  156.   //------------------------------------------------------------------//
  157.   //补偿偏移
  158.   if(!GYRO_OFFSET_OK)
  159.   {
  160.     static long int tempgx=0,tempgy=0,tempgz=0;
  161.     static unsigned char cnt_g=0;

  162.     if(cnt_g==0)
  163.     {
  164.       GYRO_OFFSET_X=0;
  165.       GYRO_OFFSET_Y=0;
  166.       GYRO_OFFSET_Z=0;
  167.       tempgx = 0;
  168.       tempgy = 0;
  169.       tempgz = 0;
  170.       cnt_g = 1;
  171.     }
  172.     tempgx+= MPU6050_GYRO_LAST_X;
  173.     tempgy+= MPU6050_GYRO_LAST_Y;
  174.     tempgz+= MPU6050_GYRO_LAST_Z;
  175.     if(cnt_g==200)
  176.     {
  177.       GYRO_OFFSET_X=tempgx/cnt_g;
  178.       GYRO_OFFSET_Y=tempgy/cnt_g;
  179.       GYRO_OFFSET_Z=tempgz/cnt_g;
  180.       cnt_g = 0;
  181.       GYRO_OFFSET_OK = 1;
  182.       
  183.     }
  184.     cnt_g++;
  185.   }
  186.   if(!ACC_OFFSET_OK)
  187.   {
  188.     static long int tempax=0,tempay=0,tempaz=0;
  189.     static unsigned char cnt_a=0;
  190.    
  191.     if(cnt_a==0)
  192.     {
  193.       ACC_OFFSET_X = 0;
  194.       ACC_OFFSET_Y = 0;
  195.       ACC_OFFSET_Z = 0;
  196.       tempax = 0;
  197.       tempay = 0;
  198.       tempaz = 0;
  199.       cnt_a = 1;
  200.       
  201.     }
  202.     tempax += MPU6050_ACC_LAST_X;//累加
  203.     tempay += MPU6050_ACC_LAST_Y;
  204.     tempaz += MPU6050_ACC_LAST_Z;
  205.     if(cnt_a==200)
  206.     {
  207.       ACC_OFFSET_X = tempax/cnt_a;
  208.       ACC_OFFSET_Y = tempay/cnt_a;
  209.       ACC_OFFSET_Z = tempaz/cnt_a;
  210.       cnt_a = 0;
  211.       ACC_OFFSET_OK = 1;
  212.       
  213.     }
  214.     cnt_a++;
  215.   }
  216.   //--------------------------------------------//
  217. #else
  218. struct MPU6050Struct *MPU6050WORK;
  219.   MPU6050WORK = ReadMPU6050All();
  220.   MPU6050_ACC_LAST_X = (MPU6050WORK ->MPU6050_ACC_X) - ACC_OFFSET_X;
  221.   MPU6050_ACC_LAST_Y = (MPU6050WORK ->MPU6050_ACC_Y) - ACC_OFFSET_Y;
  222.   MPU6050_ACC_LAST_Z = (MPU6050WORK ->MPU6050_ACC_Z) - ACC_OFFSET_Z;
  223.   
  224.   MPU6050_GYRO_LAST_X = (MPU6050WORK ->MPU6050_GYRO_X) - GYRO_OFFSET_X;
  225.   MPU6050_GYRO_LAST_Y = (MPU6050WORK ->MPU6050_GYRO_Y) - GYRO_OFFSET_Y;
  226.   MPU6050_GYRO_LAST_Z = (MPU6050WORK ->MPU6050_GYRO_Z) - GYRO_OFFSET_Z;

  227.   if(!GYRO_OFFSET_OK)
  228.   {
  229.     static long int tempgx=0,tempgy=0,tempgz=0;
  230.     static unsigned char cnt_g=0;

  231.     if(cnt_g==0)
  232.     {
  233.       GYRO_OFFSET_X=0;
  234.       GYRO_OFFSET_Y=0;
  235.       GYRO_OFFSET_Z=0;
  236.       tempgx = 0;
  237.       tempgy = 0;
  238.       tempgz = 0;
  239.       cnt_g = 1;
  240.     }
  241.     tempgx+= MPU6050_GYRO_LAST_X;
  242.     tempgy+= MPU6050_GYRO_LAST_Y;
  243.     tempgz+= MPU6050_GYRO_LAST_Z;
  244.     if(cnt_g==200)
  245.     {
  246.       GYRO_OFFSET_X=tempgx/cnt_g;
  247.       GYRO_OFFSET_Y=tempgy/cnt_g;
  248.       GYRO_OFFSET_Z=tempgz/cnt_g;
  249.       cnt_g = 0;
  250.       GYRO_OFFSET_OK = 1;
  251.       
  252.     }
  253.     cnt_g++;
  254.   }
  255.   if(!ACC_OFFSET_OK)
  256.   {
  257.     static long int tempax=0,tempay=0,tempaz=0;
  258.     static unsigned char cnt_a=0;
  259.    
  260.     if(cnt_a==0)
  261.     {
  262.       ACC_OFFSET_X = 0;
  263.       ACC_OFFSET_Y = 0;
  264.       ACC_OFFSET_Z = 0;
  265.       tempax = 0;
  266.       tempay = 0;
  267.       tempaz = 0;
  268.       cnt_a = 1;
  269.       
  270.     }
  271.     tempax += MPU6050_ACC_LAST_X;//累加
  272.     tempay += MPU6050_ACC_LAST_Y;
  273.     tempaz += MPU6050_ACC_LAST_Z;
  274.     if(cnt_a==200)
  275.     {
  276.       ACC_OFFSET_X = tempax/cnt_a;
  277.       ACC_OFFSET_Y = tempay/cnt_a;
  278.       ACC_OFFSET_Z = tempaz/cnt_a;
  279.       cnt_a = 0;
  280.       ACC_OFFSET_OK = 1;
  281.       
  282.     }
  283.     cnt_a++;
  284.   }
  285. #endif
  286.   
  287. }

  288. /**********************************************************/
  289. //函数名称:void MPU6050Init
  290. //入口参数:无
  291. //出口参数:无
  292. //函数功能:MPU6050初始化
  293. /**********************************************************/
  294. void MPU6050_Init()
  295. {
  296. #ifdef IMITATEIIC
  297.   InitImitateIICPort();
  298. #else
  299.   I2C_Init(SlaveAddr);
  300. #endif
  301.   I2C_Write(PWR_MGMT_1,0x00); //resume from sleep.
  302.   I2C_Write(SMPLRT_DIV, 0x07);
  303.   I2C_Write(CONFIG, 0x06);
  304.   I2C_Write(GYRO_CONFIG, 0x18);
  305.   I2C_Write(ACCEL_CONFIG, 0x01);
  306. }
  307. /**********************************************************/
  308. //函数名称:int Get16Bit
  309. //入口参数:address:读取数据的地址
  310. //出口参数:无
  311. //函数功能:获取MPU6050相应地址上的数据
  312. /**********************************************************/
  313. int Get16Bit (unsigned char  address)
  314. {
  315. #ifndef MULTIREAD
  316.   unsigned char  ho,lo;
  317.   int temp ;
  318.   ho = I2C_Read(address);
  319.   lo = I2C_Read(address+1);
  320.   temp=ho;
  321.   temp<<=8;
  322.   temp+=lo;
  323.   return temp ;
  324. #else
  325.   return( Double_Read_ADXL345(address));
  326. #endif
  327. }
  328. /**********************************************************/
  329. //函数名称:
  330. //入口参数:无
  331. //出口参数:无
  332. //函数功能:获取MPU6050相应轴上的加速度数据
  333. /**********************************************************/
  334. // X/Y/Z-Axis Acceleration
  335. int GetAccelX ()
  336. {
  337.   return Get16Bit(ACCEL_XOUT_H);
  338. }

  339. int GetAccelY ()
  340. {
  341.   return Get16Bit(ACCEL_YOUT_H);
  342. }

  343. int GetAccelZ ()
  344. {
  345.   return Get16Bit(ACCEL_ZOUT_H);
  346. }
  347. /**********************************************************/
  348. //函数名称:
  349. //入口参数:无
  350. //出口参数:无
  351. //函数功能:获取MPU6050相应轴上的角速度数据
  352. /**********************************************************/
  353. // X/Y/Z-Axis Angular velocity
  354. int GetAnguX ()
  355. {
  356.   return Get16Bit(GYRO_XOUT_H);
  357. }

  358. int GetAnguY ()
  359. {
  360.   return Get16Bit(GYRO_YOUT_H);
  361. }

  362. int GetAnguZ ()
  363. {
  364.   return Get16Bit(GYRO_ZOUT_H);
  365. }



  366. #include"msp430iic.h"  

  367. struct MPU6050Struct    MPU6050Data;
  368. void InitImitateIICPort(void)
  369. {
  370.   SET_SDA_OUT;          //set  SDA PIN is out mode
  371.   SDA_HIGH;             // set SDA PIN out is high
  372.   SCL_HIGH;             //set SCL PIN is input mode ,pull up register to SCL PIN high
  373. }

  374. /**************************************
  375. 起始信号
  376. **************************************/
  377. void ADXL345_Start(void)
  378. {
  379.     SET_SDA_OUT;
  380.     SDA_HIGH;                    //拉高数据线
  381.     SCL_HIGH;                    //拉高时钟线
  382.     Delay5us();                 //延时
  383.     SDA_LOW;                    //产生下降沿
  384.     Delay5us();                 //延时
  385.     SCL_LOW;                    //拉低时钟线
  386. }

  387. /**************************************
  388. 停止信号
  389. **************************************/
  390. void ADXL345_Stop(void)
  391. {
  392.     SET_SDA_OUT;
  393.     SDA_LOW;                    //拉低数据线
  394.     SCL_HIGH;                    //拉高时钟线
  395.     Delay5us();                 //延时
  396.     SDA_HIGH;                    //产生上升沿
  397.     Delay5us();                 //延时
  398. }

  399. /**************************************
  400. 发送应答信号
  401. 入口参数:ack (0:ACK 1:NAK)
  402. **************************************/
  403. void ADXL345_SendACK(unsigned char ack)
  404. {
  405.     SET_SDA_OUT;
  406.     if(ack)
  407.       SDA_HIGH;                //写NACK应答信号
  408.     else
  409.       SDA_LOW;                 //写ACK应答信号
  410.     SCL_HIGH;                    //拉高时钟线
  411.     Delay5us();                 //延时
  412.     SCL_LOW;                    //拉低时钟线
  413.     Delay5us();                 //延时
  414. }

  415. /**************************************
  416. 接收应答信号
  417. **************************************/
  418. unsigned char ADXL345_RecvACK(void)
  419. {
  420.     unsigned char ack;
  421.     //------------------//
  422.     //一下两句切不可调换顺序,否则会导致时序错误
  423.     SET_SDA_IN;
  424.     SCL_HIGH;                    //拉高时钟线  
  425.     //-----------------//
  426.     Delay5us();                 //延时
  427.     ack = SDA_IN;                   //读应答信号
  428.     SCL_LOW;                    //拉低时钟线
  429.     Delay5us();                 //延时
  430.     return ack;
  431. }

  432. /**************************************
  433. 向IIC总线发送一个字节数据
  434. **************************************/
  435. void ADXL345_Senduchar(unsigned char dat)
  436. {
  437.     unsigned char i,m;
  438.     SET_SDA_OUT;
  439.     for (i=8; i!=0; i--)         //8位计数器
  440.     {
  441.         m=dat & 0x80;           //移出数据的最高位
  442.         if(m == 0x80)
  443.             SDA_HIGH;
  444.         else
  445.             SDA_LOW;
  446.         SCL_HIGH;                //拉高时钟线
  447.         Delay5us();             //延时
  448.         SCL_LOW;                //拉低时钟线
  449.         dat=dat<<1;
  450.         Delay5us();             //延时
  451.     }
  452.     ADXL345_RecvACK();
  453. }

  454. /**************************************
  455. 从IIC总线接收一个字节数据
  456. **************************************/
  457. unsigned char  ADXL345_Recvuchar(void)
  458. {
  459.     unsigned char  i;
  460.     unsigned char dat = 0;
  461.     unsigned char m;
  462.     SDA_HIGH;                    //使能内部上拉,准备读取数据,
  463.     SET_SDA_IN;
  464.     for (i=8; i!=0; i--)         //8位计数器
  465.     {
  466.         dat <<= 1;
  467.         SCL_HIGH;                //拉高时钟线
  468.         SET_SDA_IN;
  469.         m = SDA_IN;
  470.         if(m == I2C_SDA)
  471.             dat = dat|0x01;
  472.         Delay5us();             //延时
  473.         SCL_LOW;                //拉低时钟线
  474.         Delay5us();             //延时
  475.     }
  476.     return dat;
  477. }

  478. //******单字节写入*******************************************

  479. void Single_Write_ADXL345(unsigned char REG_Address,unsigned char REG_data)
  480. {
  481.     ADXL345_Start();                  //起始信号
  482.     ADXL345_Senduchar(SlaveAddress);   //发送设备地址+写信号
  483.     ADXL345_Senduchar(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  484.     ADXL345_Senduchar(REG_data);       //内部寄存器数据,请参考中文pdf22页
  485.     ADXL345_Stop();                   //发送停止信号
  486. }

  487. //********单字节读取*****************************************
  488. unsigned char  Single_Read_ADXL345(unsigned char  REG_Address)
  489. {  unsigned char REG_data=0;
  490.     ADXL345_Start();                          //起始信号
  491.     ADXL345_Senduchar(SlaveAddress);           //发送设备地址+写信号
  492.     ADXL345_Senduchar(REG_Address);                   //发送存储单元地址,从0开始
  493.     ADXL345_Start();                          //起始信号
  494.     ADXL345_Senduchar(SlaveAddress+1);         //发送设备地址+读信号
  495.     REG_data=ADXL345_Recvuchar();              //读出寄存器数据
  496.     ADXL345_SendACK(1);                     //NACK
  497.     ADXL345_Stop();                           //停止信号
  498.     return REG_data;
  499. }
  500. //********多字节读取*****************************************
  501. int  Double_Read_ADXL345(unsigned char  REG_Address)
  502. {
  503.     unsigned char ValueL=0;
  504.     int Value=0;
  505.     ADXL345_Start();                            //起始信号
  506.     ADXL345_Senduchar(SlaveAddress);            //发送设备地址+写信号
  507.     ADXL345_Senduchar(REG_Address);             //发送存储单元地址,从0开始
  508.     ADXL345_Start();                            //起始信号
  509.     ADXL345_Senduchar(SlaveAddress+1);          //发送设备地址+读信号
  510.    
  511.     Value=ADXL345_Recvuchar();                  //读出寄存器数据
  512.     ADXL345_SendACK(0);                         //ACK
  513.    
  514.     ValueL=ADXL345_Recvuchar();                 //读出寄存器数据
  515.     ADXL345_SendACK(1);                         //NACK
  516.    
  517.     ADXL345_Stop();                             //停止信号
  518.     Value=(Value<<8)+ValueL;
  519.     return Value;
  520. }

  521. struct MPU6050Struct *ReadMPU6050All()
  522. {
  523.   unsigned char TempAcc1=0,TempAcc2=0,TempAcc3=0,TempAcc4=0,TempAcc5=0,TempAcc6=0;
  524.   unsigned char TempGyro1=0,TempGyro2=0,TempGyro3=0,TempGyro4=0,TempGyro5=0,TempGyro6=0;

  525.     ADXL345_Start();                            //起始信号
  526.     ADXL345_Senduchar(SlaveAddress);            //发送设备地址+写信号
  527.     ADXL345_Senduchar(0x3B);                    //发送存储单元地址,从0x3b开始
  528.     ADXL345_Start();                            //起始信号
  529.     ADXL345_Senduchar(SlaveAddress+1);          //发送设备地址+读信号
  530.    
  531.     TempAcc2=ADXL345_Recvuchar();                  //读出寄存器数据
  532.     ADXL345_SendACK(0);                         //ACK
  533.    
  534.     TempAcc1=ADXL345_Recvuchar();                 //读出寄存器数据
  535.     ADXL345_SendACK(0);                         //ACK
  536.    
  537.     TempAcc4=ADXL345_Recvuchar();                  //读出寄存器数据
  538.     ADXL345_SendACK(0);                         //ACK
  539.    
  540.     TempAcc3=ADXL345_Recvuchar();                 //读出寄存器数据
  541.     ADXL345_SendACK(0);                         //ACK
  542.    
  543.     TempAcc6=ADXL345_Recvuchar();                  //读出寄存器数据
  544.     ADXL345_SendACK(0);                         //ACK
  545.    
  546.     TempAcc5=ADXL345_Recvuchar();                 //读出寄存器数据
  547.     ADXL345_SendACK(0);                         //ACK
  548.    
  549.     ADXL345_Recvuchar();                         //丢弃不连续地址的数据
  550.     ADXL345_SendACK(0);                         //ACK
  551.    
  552.     ADXL345_Recvuchar();                         //丢弃不连续地址的数据
  553.     ADXL345_SendACK(0);
  554.    
  555.     TempGyro2=ADXL345_Recvuchar();                  //读出寄存器数据
  556.     ADXL345_SendACK(0);                         //ACK
  557.    
  558.     TempGyro1=ADXL345_Recvuchar();                 //读出寄存器数据
  559.     ADXL345_SendACK(0);
  560.    
  561.     TempGyro4=ADXL345_Recvuchar();                  //读出寄存器数据
  562.     ADXL345_SendACK(0);                         //ACK
  563.    
  564.     TempGyro3=ADXL345_Recvuchar();                 //读出寄存器数据
  565.     ADXL345_SendACK(0);
  566.    
  567.     TempGyro6=ADXL345_Recvuchar();                  //读出寄存器数据
  568.     ADXL345_SendACK(0);                         //ACK
  569.    
  570.     TempGyro5=ADXL345_Recvuchar();                 //读出寄存器数据
  571.     ADXL345_SendACK(1);                         //NACK
  572.    
  573.     ADXL345_Stop();

  574.     MPU6050Data.MPU6050_ACC_X=(TempAcc2<<8) + TempAcc1;
  575.     MPU6050Data.MPU6050_ACC_Y=(TempAcc4<<8) + TempAcc3;
  576.     MPU6050Data.MPU6050_ACC_Z=(TempAcc6<<8) + TempAcc5;
  577.    
  578.     MPU6050Data.MPU6050_GYRO_X=(TempGyro2<<8) + TempGyro1;
  579.     MPU6050Data.MPU6050_GYRO_Y=(TempGyro4<<8) + TempGyro3;
  580.     MPU6050Data.MPU6050_GYRO_Z=(TempGyro6<<8) + TempGyro5;
  581.     return (&MPU6050Data);
  582. }


  583. /*
  584. * This file contains some uSCI_A0 operation.
  585. * By IC爬虫 (1394024051@qq.com)
  586. * 2014-4-28 v1.0
  587. */
  588. //#include "msp430g2553.h"
  589. #include "USCI_A0.h"
  590. //#include "stdio.h"
  591. #include "mpu6050.h"
  592. #include "IMU.h"

  593. #define uchar unsigned char
  594. #define uint unsigned int

  595. //将“int”类型的数据分成两个单字节的数据
  596. #define BYTE0(dwTemp)       (*(char *)(&dwTemp))
  597. #define BYTE1(dwTemp)       (*((char *)(&dwTemp) + 1))
  598. #define BYTE2(dwTemp)       (*((char *)(&dwTemp) + 2))
  599. #define BYTE3(dwTemp)       (*((char *)(&dwTemp) + 3))

  600. /*********************************************************
  601. *名称:USCI_A0_init
  602. *功能:串口初始化
  603. *入口参数:无
  604. *出口参数:无
  605. *说明:设置为P1.1和P1.2为串口通信端口
  606. **********************************************************/
  607. void USCI_A0_init(void)
  608. {
  609.   P1SEL = BIT1 + BIT2 ;   // P1.1 = RXD, P1.2=TXD
  610.   P1SEL2 = BIT1 + BIT2;                     
  611.   UCA0CTL1 |= UCSSEL_2;   // SMCLK
  612.   /*
  613.   UCA0BR0 = 0x45;         // 8MHz 115200
  614.   UCA0BR1 = 0;            // 8MHz 115200
  615.   UCA0MCTL = 0x4a;        // 8MHz 115200  */   
  616.   /*
  617.   UCA0BR0 = 0x68;
  618.   UCA0BR1 = 0;
  619.   UCA0MCTL = 0x40;
  620.   */
  621.   UCA0MCTL = UCBRF_0 | UCBRS_4;
  622.    
  623.     /* Baud rate control register 0 */
  624.     UCA0BR0 = 69;
  625.   UCA0CTL1 &= ~UCSWRST;          // **Initialize USCI state machine**
  626.   
  627.   //IE2 |= UCA0RXIE + UCA0TXIE;  // Enable USCI_A0 TX/RX interrupt
  628.   //IE2 |= UCA0RXIE;             // Enable USCI_A0 RX interrupt
  629.   //__bis_SR_register(GIE);      // Enter LPM3 w/ interrupts enabled
  630. }


  631. /*********************************************************
  632. *名称:UartTX_Send_String
  633. *功能:串口发送字符串函数
  634. *入口参数:*data:数据指针        len :数据长度
  635. *出口参数:无
  636. *说明:
  637. **********************************************************/
  638. void UartTX_Send_String(unsigned char *Data,int len)
  639. {
  640.   int j;
  641.   for(j=0;j<len;j++)
  642.   {
  643.     UartTX_Send_char(*Data++);
  644.   }
  645. }

  646. /*********************************************************
  647. *名称:UartTX_Send_char
  648. *功能:串口发送字符函数
  649. *入口参数:c
  650. *出口参数:无
  651. *说明:
  652. **********************************************************/
  653. unsigned char UartTX_Send_char(unsigned char c)
  654. {
  655.     UCA0TXBUF=c;   
  656.     while(!(IFG2&UCA0TXIFG));
  657.     IFG2&=~UCA0TXIFG;
  658.     return c;
  659. }
  660. /*********************************************************
  661. *名称:int putchar
  662. *功能:串口发送字符函数
  663. *入口参数:ch
  664. *出口参数:无
  665. *说明:
  666. **********************************************************/
  667. int putchar(int ch)
  668. {
  669.   UCA0TXBUF=ch;
  670.   while(!(IFG2&UCA0TXIFG));
  671.    //UCA0TXBUF=ch;
  672.   IFG2&=~UCA0TXIFG;
  673.    return ch;
  674. }


  675. void sendChar(unsigned char c)
  676. {
  677.    while(!(IFG2&UCA0TXIFG));
  678.    UCA0TXBUF=c;
  679. }

  680. void sendStr(unsigned char *s)
  681. {
  682.   while(*s!='\0')
  683.   {
  684.     sendChar(*s);
  685.     s++;
  686.   }
  687. }

  688. /*********************************************************
  689. *名称:void Uart1_Send_AF
  690. *功能:串口发送姿态数据
  691. *入口参数:无
  692. *出口参数:无
  693. *说明:每一次执行这个函数就算是一帧数据,帧头为0X88,功能字
  694. *      为0XAF
  695. **********************************************************/
  696. void Uart1_Send_AF(void)
  697. {
  698.   unsigned char sum = 0;//累加串口发送的数据的值,做校验用
  699.   unsigned int _temp;   
  700.   sum += UartTX_Send_char(0x88);  //帧头
  701.   sum += UartTX_Send_char(0xAF);  //功能字
  702.   
  703.   sum += UartTX_Send_char(0x1c);
  704.   sum += UartTX_Send_char( BYTE1(MPU6050_ACC_LAST_X) ); //发送加速度X轴数据的高8位
  705.   sum += UartTX_Send_char( BYTE0(MPU6050_ACC_LAST_X) ); //发送加速度X轴数据的低8位
  706.   
  707.   sum += UartTX_Send_char( BYTE1(MPU6050_ACC_LAST_Y) ); //发送加速度Y轴数据的高8位
  708.   sum += UartTX_Send_char( BYTE0(MPU6050_ACC_LAST_Y) ); //发送加速度Y轴数据的低8位
  709.   
  710.   sum += UartTX_Send_char( BYTE1(MPU6050_ACC_LAST_Z) ); //发送加速度Z轴数据的高8位
  711.   sum += UartTX_Send_char( BYTE0(MPU6050_ACC_LAST_Z) ); //发送加速度Z轴数据的低8位
  712.   
  713.   sum += UartTX_Send_char( BYTE1(MPU6050_GYRO_LAST_X) ); //发送陀螺仪X轴数据的高8位
  714.   sum += UartTX_Send_char( BYTE0(MPU6050_GYRO_LAST_X) ); //发送陀螺仪X轴数据的低8位
  715.   
  716.   sum += UartTX_Send_char( BYTE1(MPU6050_GYRO_LAST_Y) ); //发送陀螺仪Y轴数据的高8位
  717.   sum += UartTX_Send_char( BYTE0(MPU6050_GYRO_LAST_Y) ); //发送陀螺仪Y轴数据的低8位
  718.   
  719.   sum += UartTX_Send_char( BYTE1(MPU6050_GYRO_LAST_Z) ); //发送陀螺仪Z轴数据的高8位
  720.   sum += UartTX_Send_char( BYTE0(MPU6050_GYRO_LAST_Z) ); //发送陀螺仪Z轴数据的低8位
  721.   sum += UartTX_Send_char(0);
  722.   sum += UartTX_Send_char(0);
  723.   sum += UartTX_Send_char(0);
  724.   sum += UartTX_Send_char(0);
  725.   sum += UartTX_Send_char(0);
  726.   sum += UartTX_Send_char(0);
  727.         
  728.   _temp = (long int)(Q_ANGLE_X*100);
  729.   sum += UartTX_Send_char( BYTE1(_temp) );
  730.   sum += UartTX_Send_char( BYTE0(_temp) );
  731.   _temp = (long int)(Q_ANGLE_Y*100);
  732.   sum += UartTX_Send_char( BYTE1(_temp) );
  733.   sum += UartTX_Send_char( BYTE0(_temp) );
  734.         
  735.   sum += UartTX_Send_char(0);
  736.   sum += UartTX_Send_char(0);
  737.   sum += UartTX_Send_char(0);
  738.   sum += UartTX_Send_char(0);
  739.   sum += UartTX_Send_char(0);
  740.   sum += UartTX_Send_char(0);
  741.   
  742.   UartTX_Send_char(sum); //串口发送累加值用于校验
  743. }


  744. /*
  745. * This file contains some IMU operation.
  746. * By IC爬虫 (1394024051@qq.com)
  747. * 2014-4-29 v1.0
  748. */
  749. #include "IMU.h"

  750. #define RtA           57.324841  //弧度到角度
  751. #define AtR              0.0174533  //度到角度
  752. #define Acc_G           0.0011963  //加速度变成G
  753. #define Gyro_G           0.0152672  //角速度变成度
  754. #define Gyro_Gr          0.0002663                                
  755. #define FILTER_NUM 20

  756. int   ACC_AVG_X,ACC_AVG_Y,ACC_AVG_Z;      //平均值滤波后的ACC
  757. float GYRO_I_X,GYRO_I_Y,GYRO_I_Z;         //陀螺仪积分
  758. float EXP_ANGLE_X,EXP_ANGLE_Y,EXP_ANGLE_Z;//期望角度
  759. float DIF_ANGLE_X,DIF_ANGLE_Y,DIF_ANGLE_Z;//期望角度和实际角度的差
  760. float Q_ANGLE_X,Q_ANGLE_Y,Q_ANGLE_Z;      //四元数计算出的角度

  761. int ACC_X_BUF[FILTER_NUM],ACC_Y_BUF[FILTER_NUM],ACC_Z_BUF[FILTER_NUM];        //加速度滑动窗口滤波数组

  762. /**********************************************************/
  763. //函数名称:Prepare_Data
  764. //入口参数:无
  765. //出口参数:无
  766. //函数功能:读取MPU6050数据进行平滑滤波,为后续计算准备数据
  767. /**********************************************************/
  768. void Prepare_Data(void)
  769. {
  770.   static unsigned char filter_cnt=0;
  771.   long int temp1=0,temp2=0,temp3=0;
  772.   unsigned char i;
  773.         
  774.   MPU6050_Dataanl();//完成传感器数据的读取和计算,并且对数据简单处理
  775.         
  776.   ACC_X_BUF[filter_cnt] = MPU6050_ACC_LAST_X;//更新滑动窗口数组
  777.   ACC_Y_BUF[filter_cnt] = MPU6050_ACC_LAST_Y;
  778.   ACC_Z_BUF[filter_cnt] = MPU6050_ACC_LAST_Z;
  779.   
  780.   for(i=0;i<FILTER_NUM;i++)
  781.   {
  782.     temp1 += ACC_X_BUF[i];
  783.     temp2 += ACC_Y_BUF[i];
  784.     temp3 += ACC_Z_BUF[i];
  785.   }
  786.   
  787.   ACC_AVG_X = temp1 / FILTER_NUM;
  788.   ACC_AVG_Y = temp2 / FILTER_NUM;
  789.   ACC_AVG_Z = temp3 / FILTER_NUM;
  790.   
  791.   filter_cnt++;
  792.   
  793.   if(filter_cnt==FILTER_NUM)  filter_cnt=0;
  794.         
  795.   GYRO_I_X += MPU6050_GYRO_LAST_X*Gyro_G*0.02;//0.0001是时间间隔,两次prepare函数的执行周期
  796.   GYRO_I_Y += MPU6050_GYRO_LAST_Y*Gyro_G*0.02;//示波器测量的得到的时间是20ms.
  797.   GYRO_I_Z += MPU6050_GYRO_LAST_Z*Gyro_G*0.02;
  798. }

  799. void Get_Attitude(void)
  800. {
  801.   IMUupdate( MPU6050_GYRO_LAST_X*Gyro_Gr,
  802.             MPU6050_GYRO_LAST_Y*Gyro_Gr,
  803.             MPU6050_GYRO_LAST_Z*Gyro_Gr,
  804.             ACC_AVG_X,ACC_AVG_Y,ACC_AVG_Z);        //*0.0174转成弧度
  805. }
  806. ////////////////////////////////////////////////////////////////////////////////
  807. #define Kp 10.0f        // proportional gain governs rate of convergence to accelerometer/magnetometer
  808. #define Ki 0.008f       // integral gain governs rate of convergence of gyroscope biases
  809. #define halfT 0.004f    // half the sample period采样周期的一半

  810. float q0 = 1, q1 = 0, q2 = 0, q3 = 0;    // quaternion elements representing the estimated orientation
  811. float exInt = 0, eyInt = 0, ezInt = 0;    // scaled integral error
  812. /**********************************************************/
  813. //函数名称:IMUupdate
  814. //入口参数:gx:浮点型的陀螺仪x轴数据
  815. //          gy:浮点型的陀螺仪y轴数据
  816. //          gz:浮点型的陀螺仪z轴数据
  817. //          ax:浮点型的加速度x轴数据
  818. //          ay:浮点型的加速度y轴数据
  819. //          az:浮点型的加速度z轴数据
  820. //出口参数:无
  821. //函数功能:通过陀螺仪和加速度传感器的数据用四元数计算姿态
  822. /**********************************************************/
  823. void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)
  824. {
  825.   float norm;
  826. //  float hx, hy, hz, bx, bz;
  827.   float vx, vy, vz;// wx, wy, wz;
  828.   float ex, ey, ez;

  829.   //先把这些需要用到的值弄好
  830.   float q0q0 = q0*q0;
  831.   float q0q1 = q0*q1;
  832.   float q0q2 = q0*q2;
  833. //  float q0q3 = q0*q3;
  834.   float q1q1 = q1*q1;
  835. //  float q1q2 = q1*q2;
  836.   float q1q3 = q1*q3;
  837.   float q2q2 = q2*q2;
  838.   float q2q3 = q2*q3;
  839.   float q3q3 = q3*q3;
  840.         
  841.   if(ax*ay*az==0) return;
  842.                
  843.   norm = sqrt(ax*ax + ay*ay + az*az);//acc数据归一化
  844.   ax = ax /norm;
  845.   ay = ay / norm;
  846.   az = az / norm;

  847.   // estimated direction of gravity and flux (v and w)   估计重力方向和流量/变迁
  848.   vx = 2*(q1q3 - q0q2);        //四元数中xyz的表示
  849.   vy = 2*(q0q1 + q2q3);
  850.   vz = q0q0 - q1q1 - q2q2 + q3q3 ;

  851.   // error is sum of cross product between reference direction of fields and direction measured by sensors
  852.   ex = (ay*vz - az*vy) ;   //向量外积在相减得到差分就是误差
  853.   ey = (az*vx - ax*vz) ;
  854.   ez = (ax*vy - ay*vx) ;

  855.   exInt = exInt + ex * Ki; //对误差进行积分
  856.   eyInt = eyInt + ey * Ki;
  857.   ezInt = ezInt + ez * Ki;

  858.   // adjusted gyroscope measurements
  859.   gx = gx + Kp*ex + exInt; //将误差PI后补偿到陀螺仪,即补偿零点漂移
  860.   gy = gy + Kp*ey + eyInt;
  861.   gz = gz + Kp*ez + ezInt; //这里的gz由于没有观测者进行矫正会产生漂移,变现出来的就是积分自增或者自减

  862.   // integrate quaternion rate and normalise //四元数的微分方程
  863.   q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
  864.   q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
  865.   q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
  866.   q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;

  867.   // normalise quaternion
  868.   norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
  869.   q0 = q0 / norm;
  870.   q1 = q1 / norm;
  871.   q2 = q2 / norm;
  872.   q3 = q3 / norm;

  873.   //Q_ANGLE.Yaw = atan2(2 * q1 * q2 + 2 * q0 * q3, -2 * q2*q2 - 2 * q3* q3 + 1)* 57.3; // yaw
  874.   Q_ANGLE_Y  = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch
  875.   Q_ANGLE_X = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll
  876. }




  877. /*
  878. * This file contains some I2C operation.
  879. * By IC爬虫 (1394024051@qq.com)
  880. * 2014-4-13 v1.0
  881. */
  882. #include "HardWareIIC.h"

  883. uchar I2CSendBuffer[2],I2CRecvBuffer; //I2C发送缓存和接收缓存

  884. int I2CSendPtr=0;

  885. /**********************************************************/
  886. //函数名称:void I2C_Init
  887. //入口参数:SlaveAddr:从机的设备地址
  888. //出口参数:无
  889. //函数功能:I2C初始化,P1.6->SCL ,P1.7->SDA
  890. /**********************************************************/
  891. void I2C_Init (unsigned char SlaveAddr)
  892. {
  893.   P1SEL |= BIT6+BIT7;               // Assign I2C pins to USCI_B0
  894.   P1SEL2|= BIT6+BIT7;               // Assign I2C pins to USCI_B0
  895.   UCB0CTL1 |= UCSWRST;              // Enable SW reset
  896.   
  897.   UCB0CTL0 = UCMST+UCMODE_3+UCSYNC; // I2C Master, synchronous mode
  898.   UCB0CTL0 &= ~(UCSLA10+UCA10);                        //7 bit add of slave and master
  899.   
  900.   UCB0CTL1 = UCSSEL_2+UCSWRST;      // Use SMCLK, keep SW reset
  901.   
  902.   UCB0BR0 = 80;                     // fSCL = SMCLK/12 = ~100kHz
  903.   UCB0BR1 = 0;
  904.   
  905.   UCB0I2COA = 0x01A5;                                                                //set own address
  906.   UCB0I2CSA = SlaveAddr;            // Set slave address
  907.   
  908.   IE2 &= ~(UCB0RXIE+UCB0TXIE);         // disenable  TX&RX interrupt
  909.   UCB0CTL1 &= ~UCSWRST;             // Clear SW reset, resume operation
  910.   
  911. }
  912. /**********************************************************/
  913. //函数名称:void I2C_WriteInit
  914. //入口参数:无
  915. //出口参数:无
  916. //函数功能:I2C写数据初始化,发送模式,接收中断关闭,发送中断关闭
  917. /**********************************************************/
  918. void I2C_WriteInit()
  919. {
  920.   UCB0CTL1 |= UCTR;            // UCTR=1 => Transmit Mode (R/W bit = 0)
  921.   IFG2 &= ~UCB0TXIFG;                //clean TX interrupt sign
  922.   IE2 &= ~UCB0RXIE;           // disable Receive ready interrupt
  923.   IE2 &= ~UCB0TXIE;     // disable Transmit ready interrupt
  924. }
  925. /**********************************************************/
  926. //函数名称:void I2C_ReadInit
  927. //入口参数:无
  928. //出口参数:无
  929. //函数功能:I2C读数据初始化,接收模式,接收中断关闭,发送中断关闭
  930. /**********************************************************/
  931. void I2C_ReadInit()
  932. {
  933.   UCB0CTL1 &= ~UCTR;   // UCTR=0 => Receive Mode (R/W bit = 1)
  934.   IFG2 &= ~UCB0RXIFG;
  935.   IE2 &= ~UCB0TXIE;    // disable Transmit ready interrupt
  936.   IE2 &= ~UCB0RXIE;     // disable Receive ready interrupt
  937. }
  938. /**********************************************************/
  939. //函数名称:I2C_Write
  940. //入口参数:address:需要写入数据的设备的地址
  941. //          data:发送的数据
  942. //出口参数:无
  943. //函数功能:I2C发送数据
  944. /**********************************************************/
  945. void I2C_Write(uchar address,uchar data)
  946. {

  947.   I2C_WriteInit();
  948.   UCB0CTL1 |= UCTXSTT;          //generate start condition
  949.   //while(UCB0CTL1 & UCTXSTT);        //generate start condition ,and transmit slave address and write bit
  950.   while(!(IFG2 & UCB0TXIFG));   //wait start condition and equipment address transmitted
  951.   IFG2 &= ~UCB0TXIFG;           //clean UCB0TXIFG
  952.   while(UCB0CTL1 & UCTXSTT);    //wait slave acknowledge
  953.   
  954.   UCB0TXBUF=address;                //send address code
  955.   while(!(IFG2 & UCB0TXIFG ));        //wait sending over
  956.   IFG2 &= ~UCB0TXIFG;            // Clear USCI_B0 TX int flag
  957.    
  958.   UCB0TXBUF=data;                //send  data
  959.   while(!(IFG2 & UCB0TXIFG ));                //wait sending over
  960.   IFG2 &= ~UCB0TXIFG;            // Clear USCI_B0 TX int flag
  961.   
  962.   UCB0CTL1 |= UCTXSTP;            // I2C stop condition
  963.   while (UCB0CTL1 & UCTXSTP);     // Ensure stop condition got sent
  964. }
  965. /**********************************************************/
  966. //函数名称:uchar I2C_Read
  967. //入口参数:address:需要读数据的设备的地址
  968. //出口参数:无
  969. //函数功能:I2C接收数据
  970. /**********************************************************/
  971. uchar I2C_Read(uchar address)
  972. {
  973.   unsigned char data;
  974.   while (UCB0STAT & UCBUSY); // wait until I2C module has finished all operations
  975.   I2C_WriteInit();
  976.   UCB0CTL1 |= UCTXSTT;       // start condition generation
  977.   while(UCB0CTL1 & UCTXSTT);
  978.   
  979.   
  980.   UCB0TXBUF=address;                                                        //send address code
  981.   while(!(IFG2 & UCB0TXIFG ));                //wait sending over
  982.   IFG2 &= ~UCB0TXIFG;            // Clear USCI_B0 TX int flag
  983.   
  984. // __disable_interrupt();
  985. I2C_ReadInit();
  986.   while(UCB0RXIFG & IFG2);
  987.   IFG2 &= ~UCB0RXIFG;
  988.   data  = UCB0RXBUF;
  989.   
  990.   UCB0CTL1 |= UCTXSTP;            // I2C stop condition
  991.   while (UCB0CTL1 & UCTXSTP);     // Ensure stop condition got sent
  992.   return data;
  993. }

  994. /*----------------------------------------------------------------------------*/
  995. // Description:
  996. //   Acknowledge Polling. The EEPROM will not acknowledge if a write cycle is
  997. //   in progress. It can be used to determine when a write cycle is completed.
  998. /*----------------------------------------------------------------------------*/
  999. void I2C_AckPolling(void)
  1000. {
  1001.   while (UCB0STAT & UCBUSY)
  1002.   {     
  1003.     ;// wait until I2C module has
  1004.   }  // finished all operations

  1005.   do
  1006.   {
  1007.     UCB0STAT = 0x00;              // clear I2C interrupt flags
  1008.     UCB0CTL1 |= UCTR;             // I2CTRX=1 => Transmit Mode (R/W bit = 0)
  1009.     UCB0CTL1 &= ~UCTXSTT;
  1010.     UCB0CTL1 |= UCTXSTT;          // start condition is generated
  1011.     while (UCB0CTL1 & UCTXSTT)    // wait till I2CSTT bit was cleared
  1012.     {   
  1013.       if (!(UCNACKIFG & UCB0STAT))
  1014.       {  
  1015.         break;// Break out if ACK received
  1016.       }
  1017.     }
  1018.     UCB0CTL1 |= UCTXSTP;          // stop condition is generated after
  1019.                                   // slave address was sent => I2C communication is started
  1020.     while (UCB0CTL1 & UCTXSTP)
  1021.     {   
  1022.       ;// wait till stop bit is reset
  1023.     }
  1024.     __delay_cycles(500);          // Software delay
  1025.    
  1026.   } while (UCNACKIFG & UCB0STAT);
  1027. }


  1028. // USCI_B0 Data ISR
  1029. // Notice : UCSIAB0RX_ISR should be handle with UCSIAB0TX_ISR
  1030. #pragma vector = USCIAB0TX_VECTOR
  1031. __interrupt void USCIAB0TX_ISR(void)
  1032. {
  1033.   if (UCB0TXIFG & IFG2)      // TX
  1034.   {
  1035.     UCB0TXBUF = I2CSendBuffer[I2CSendPtr]; // Load TX buffer
  1036.     I2CSendPtr--;                          // Decrement TX byte counter
  1037.     if (I2CSendPtr < 0)
  1038.     {               
  1039.       while (!(IFG2 & UCB0TXIFG));         // wait for tx complete
  1040.       IE2 &= ~UCB0TXIE;                    // disable interrupts.
  1041.       IFG2 &= ~UCB0TXIFG;                  // Clear USCI_B0 TX int flag
  1042.       __bic_SR_register_on_exit(LPM0_bits);// Exit LPM0
  1043.     }
  1044.   }
  1045.   else if (UCB0RXIFG & IFG2) // RX
  1046.   {
  1047.     I2CRecvBuffer = UCB0RXBUF;             // store received data in buffer
  1048.     __bic_SR_register_on_exit(LPM0_bits);  // Exit LPM0
  1049.   }
  1050. }
复制代码




回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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