发 帖  
[问答] mpu6050六轴传感器msp430驱动程序
422 MPU6050 六轴传感器 MSP430
分享
  1. <ul type="1" class="litype_1"><li>#include <msp430g2553.h></li><li>#include"mpu6050.h"</li><li>#include "USCI_A0.h"</li><li>#include "IMU.h "</li><li>/*</li><li> *  ======== BCSplus_graceInit ========</li><li> *  Initialize MSP430 Basic Clock System</li><li> */</li><li>void BCSplus_graceInit(void)</li><li>{</li><li>    /* USER CODE START (section: BCSplus_graceInit_prologue) */</li><li>    /* User initialization code */</li><li>    /* USER CODE END (section: BCSplus_graceInit_prologue) */</li><li></li><li>    /*</li><li>     * Basic Clock System Control 2</li><li>     *</li><li>     * SELM_0 -- DCOCLK</li><li>     * DIVM_0 -- Divide by 1</li><li>     * ~SELS -- DCOCLK</li><li>     * DIVS_1 -- Divide by 2</li><li>     * ~DCOR -- DCO uses internal resistor</li><li>     *</li><li>     * Note: ~<BIT> indicates that <BIT> has value zero</li><li>     */</li><li>    BCSCTL2 = SELM_0 | DIVM_0 | DIVS_1;</li><li></li><li>    if (CALBC1_16MHZ != 0xFF) {</li><li>        /* Adjust this accordingly to your VCC rise time */</li><li>        __delay_cycles(100000);</li><li></li><li>        /* Follow recommended flow. First, clear all DCOx and MODx bits. Then</li><li>         * apply new RSELx values. Finally, apply new DCOx and MODx bit values.</li><li>         */</li><li>        DCOCTL = 0x00;</li><li>        BCSCTL1 = CALBC1_16MHZ;     /* Set DCO to 16MHz */</li><li>        DCOCTL = CALDCO_16MHZ;</li><li>    }</li><li></li><li>    /*</li><li>     * Basic Clock System Control 1</li><li>     *</li><li>     * XT2OFF -- Disable XT2CLK</li><li>     * ~XTS -- Low Frequency</li><li>     * DIVA_0 -- Divide by 1</li><li>     *</li><li>     * Note: ~XTS indicates that XTS has value zero</li><li>     */</li><li>    BCSCTL1 |= XT2OFF | DIVA_0;</li><li></li><li>    /*</li><li>     * Basic Clock System Control 3</li><li>     *</li><li>     * XT2S_0 -- 0.4 - 1 MHz</li><li>     * LFXT1S_0 -- If XTS = 0, XT1 = 32768kHz Crystal ; If XTS = 1, XT1 = 0.4 - 1-MHz crystal or resonator</li><li>     * XCAP_1 -- ~6 pF</li><li>     */</li><li>    BCSCTL3 = XT2S_0 | LFXT1S_0 | XCAP_1;</li><li></li><li>    /* USER CODE START (section: BCSplus_graceInit_epilogue) */</li><li>    /* User code */</li><li>    /* USER CODE END (section: BCSplus_graceInit_epilogue) */</li><li>}/*</li><li> * main.c</li><li> */</li><li>int main(void)</li><li>{</li><li>    WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer</li><li>    BCSplus_graceInit();        //MCLK = 16M,SMCLK = 8M,ack =32.768k</li><li>    WDTCTL = WDTPW | WDTTMSEL | WDTIS0;</li><li>    IE1 |= WDTIE;</li><li>    USCI_A0_init();             //uart 38400bps  </li><li>    P1DIR |= BIT0;              //initialize led control PIN</li><li>    _EINT();</li><li>    MPU6050_Init();             //initialize mpu6050</li><li>   </li><li>    while(1)</li><li>    {</li><li>      /*</li><li>      Get_Attitude();</li><li>     //MPU6050_Dataanl();</li><li>     // ReadMPU6050All();</li><li>     //Prepare_Data();             //耗时6.15ms</li><li>     //Uart1_Send_AF();             //耗时8.42ms</li><li>     P1OUT ^= BIT0;</li><li>     Get_Attitude();</li><li>     //ReadMPU6050All();</li><li>     //MPU6050_Dataanl();         //未使用多字节读取,耗时6ms,使用多字节读取,耗时3.6ms</li><li>     //Prepare_Data();</li><li>    // Uart1_Send_AF();</li><li>     P1OUT ^= BIT0;</li><li>     */</li><li>    }</li><li>   </li><li>}</li><li></li><li>//watchdog interrupt server program per 1ms</li><li>#pragma vector=WDT_VECTOR</li><li>__interrupt void WDT_ISR_HOOK(void)</li><li>{</li><li>    /* USER CODE START (section: WDT_ISR_HOOK) */</li><li>    /* replace this comment with your code */</li><li>    static unsigned int count=0;</li><li>    static unsigned char ms2 = 0,ms5 = 0,ms10 = 0;</li><li>    count++;</li><li>    ms2++;</li><li>    ms5++;</li><li>    ms10++;</li><li>   </li><li>    if(ms2 == 2)</li><li>    {</li><li>     ms2 = 0;</li><li>     Prepare_Data();</li><li>     //MPU6050_Dataanl();</li><li>    }</li><li>    if(ms5 >= 4)</li><li>    {</li><li>      ms5 = 0;</li><li>      Get_Attitude();</li><li>   </li><li>    }</li><li>    if(ms10 >= 10)</li><li>    {</li><li>      ms10 = 0;</li><li>      Uart1_Send_AF();</li><li>    }</li><li>    if(count== 200)</li><li>    {</li><li>      count=0;</li><li>      P1OUT ^= BIT0;</li><li>    }</li><li></li><li>        /* USER CODE END (section: WDT_ISR_HOOK) */</li><li>}</li><li></li><li></li><li></li><li>/*</li><li> * This file contains some mpu6050 operation.</li><li> * By IC爬虫 (<a href="mailto:1394024051@qq.com">1394024051@qq.com</a>)</li><li> * 2014-4-13 v1.0</li><li> */</li><li>#include "mpu6050.h"</li><li></li><li>unsigned char   mpu6050_buffer[14];     //I2C读取后存放数据</li><li></li><li>int ACC_OFFSET_X,ACC_OFFSET_Y,ACC_OFFSET_Z;</li><li>int GYRO_OFFSET_X,GYRO_OFFSET_Y,GYRO_OFFSET_Z;</li><li></li><li>unsigned char        GYRO_OFFSET_OK = 1;</li><li>unsigned char        ACC_OFFSET_OK = 1;</li><li></li><li>int MPU6050_ACC_LAST_X,MPU6050_ACC_LAST_Y,MPU6050_ACC_LAST_Z;    //final accelerate speed</li><li>int MPU6050_GYRO_LAST_X,MPU6050_GYRO_LAST_Y,MPU6050_GYRO_LAST_Z; //final  gyro  speed</li><li></li><li>/**********************************************************/</li><li>//函数名称:void MPU6050_Dataanl</li><li>//入口参数:无</li><li>//出口参数:无</li><li>//函数功能:MPU6050数据读取并处理</li><li>/**********************************************************/</li><li>void MPU6050_Dataanl(void)</li><li>{</li><li>#ifndef READALL</li><li>  MPU6050_ACC_LAST_X = GetAccelX() - ACC_OFFSET_X;</li><li>  MPU6050_ACC_LAST_Y = GetAccelY() - ACC_OFFSET_Y;</li><li>  MPU6050_ACC_LAST_Z = GetAccelZ() - ACC_OFFSET_Z;</li><li>  </li><li>  MPU6050_GYRO_LAST_X = GetAnguX() - GYRO_OFFSET_X;</li><li>  MPU6050_GYRO_LAST_Y = GetAnguY() - GYRO_OFFSET_Y;</li><li>  MPU6050_GYRO_LAST_Z = GetAnguZ() - GYRO_OFFSET_Z;</li><li>  //------------------------------------------------------------------//</li><li>  //补偿偏移</li><li>  if(!GYRO_OFFSET_OK)</li><li>  {</li><li>    static long int tempgx=0,tempgy=0,tempgz=0;</li><li>    static unsigned char cnt_g=0;</li><li></li><li>    if(cnt_g==0)</li><li>    {</li><li>      GYRO_OFFSET_X=0;</li><li>      GYRO_OFFSET_Y=0;</li><li>      GYRO_OFFSET_Z=0;</li><li>      tempgx = 0;</li><li>      tempgy = 0;</li><li>      tempgz = 0;</li><li>      cnt_g = 1;</li><li>    }</li><li>    tempgx+= MPU6050_GYRO_LAST_X;</li><li>    tempgy+= MPU6050_GYRO_LAST_Y;</li><li>    tempgz+= MPU6050_GYRO_LAST_Z;</li><li>    if(cnt_g==200)</li><li>    {</li><li>      GYRO_OFFSET_X=tempgx/cnt_g;</li><li>      GYRO_OFFSET_Y=tempgy/cnt_g;</li><li>      GYRO_OFFSET_Z=tempgz/cnt_g;</li><li>      cnt_g = 0;</li><li>      GYRO_OFFSET_OK = 1;</li><li>      </li><li>    }</li><li>    cnt_g++;</li><li>  }</li><li>  if(!ACC_OFFSET_OK)</li><li>  {</li><li>    static long int tempax=0,tempay=0,tempaz=0;</li><li>    static unsigned char cnt_a=0;</li><li>   </li><li>    if(cnt_a==0)</li><li>    {</li><li>      ACC_OFFSET_X = 0;</li><li>      ACC_OFFSET_Y = 0;</li><li>      ACC_OFFSET_Z = 0;</li><li>      tempax = 0;</li><li>      tempay = 0;</li><li>      tempaz = 0;</li><li>      cnt_a = 1;</li><li>      </li><li>    }</li><li>    tempax += MPU6050_ACC_LAST_X;//累加</li><li>    tempay += MPU6050_ACC_LAST_Y;</li><li>    tempaz += MPU6050_ACC_LAST_Z;</li><li>    if(cnt_a==200)</li><li>    {</li><li>      ACC_OFFSET_X = tempax/cnt_a;</li><li>      ACC_OFFSET_Y = tempay/cnt_a;</li><li>      ACC_OFFSET_Z = tempaz/cnt_a;</li><li>      cnt_a = 0;</li><li>      ACC_OFFSET_OK = 1;</li><li>      </li><li>    }</li><li>    cnt_a++;</li><li>  }</li><li>  //--------------------------------------------//</li><li>#else</li><li>struct MPU6050Struct *MPU6050WORK;</li><li>  MPU6050WORK = ReadMPU6050All();</li><li>  MPU6050_ACC_LAST_X = (MPU6050WORK ->MPU6050_ACC_X) - ACC_OFFSET_X;</li><li>  MPU6050_ACC_LAST_Y = (MPU6050WORK ->MPU6050_ACC_Y) - ACC_OFFSET_Y;</li><li>  MPU6050_ACC_LAST_Z = (MPU6050WORK ->MPU6050_ACC_Z) - ACC_OFFSET_Z;</li><li>  </li><li>  MPU6050_GYRO_LAST_X = (MPU6050WORK ->MPU6050_GYRO_X) - GYRO_OFFSET_X;</li><li>  MPU6050_GYRO_LAST_Y = (MPU6050WORK ->MPU6050_GYRO_Y) - GYRO_OFFSET_Y;</li><li>  MPU6050_GYRO_LAST_Z = (MPU6050WORK ->MPU6050_GYRO_Z) - GYRO_OFFSET_Z;</li><li></li><li>  if(!GYRO_OFFSET_OK)</li><li>  {</li><li>    static long int tempgx=0,tempgy=0,tempgz=0;</li><li>    static unsigned char cnt_g=0;</li><li></li><li>    if(cnt_g==0)</li><li>    {</li><li>      GYRO_OFFSET_X=0;</li><li>      GYRO_OFFSET_Y=0;</li><li>      GYRO_OFFSET_Z=0;</li><li>      tempgx = 0;</li><li>      tempgy = 0;</li><li>      tempgz = 0;</li><li>      cnt_g = 1;</li><li>    }</li><li>    tempgx+= MPU6050_GYRO_LAST_X;</li><li>    tempgy+= MPU6050_GYRO_LAST_Y;</li><li>    tempgz+= MPU6050_GYRO_LAST_Z;</li><li>    if(cnt_g==200)</li><li>    {</li><li>      GYRO_OFFSET_X=tempgx/cnt_g;</li><li>      GYRO_OFFSET_Y=tempgy/cnt_g;</li><li>      GYRO_OFFSET_Z=tempgz/cnt_g;</li><li>      cnt_g = 0;</li><li>      GYRO_OFFSET_OK = 1;</li><li>      </li><li>    }</li><li>    cnt_g++;</li><li>  }</li><li>  if(!ACC_OFFSET_OK)</li><li>  {</li><li>    static long int tempax=0,tempay=0,tempaz=0;</li><li>    static unsigned char cnt_a=0;</li><li>   </li><li>    if(cnt_a==0)</li><li>    {</li><li>      ACC_OFFSET_X = 0;</li><li>      ACC_OFFSET_Y = 0;</li><li>      ACC_OFFSET_Z = 0;</li><li>      tempax = 0;</li><li>      tempay = 0;</li><li>      tempaz = 0;</li><li>      cnt_a = 1;</li><li>      </li><li>    }</li><li>    tempax += MPU6050_ACC_LAST_X;//累加</li><li>    tempay += MPU6050_ACC_LAST_Y;</li><li>    tempaz += MPU6050_ACC_LAST_Z;</li><li>    if(cnt_a==200)</li><li>    {</li><li>      ACC_OFFSET_X = tempax/cnt_a;</li><li>      ACC_OFFSET_Y = tempay/cnt_a;</li><li>      ACC_OFFSET_Z = tempaz/cnt_a;</li><li>      cnt_a = 0;</li><li>      ACC_OFFSET_OK = 1;</li><li>      </li><li>    }</li><li>    cnt_a++;</li><li>  }</li><li>#endif</li><li>  </li><li>}</li><li></li><li>/**********************************************************/</li><li>//函数名称:void MPU6050Init</li><li>//入口参数:无</li><li>//出口参数:无</li><li>//函数功能:MPU6050初始化</li><li>/**********************************************************/</li><li>void MPU6050_Init()</li><li>{</li><li>#ifdef IMITATEIIC</li><li>  InitImitateIICPort();</li><li>#else</li><li>  I2C_Init(SlaveAddr);</li><li>#endif</li><li>  I2C_Write(PWR_MGMT_1,0x00); //resume from sleep.</li><li>  I2C_Write(SMPLRT_DIV, 0x07);</li><li>  I2C_Write(CONFIG, 0x06);</li><li>  I2C_Write(GYRO_CONFIG, 0x18);</li><li>  I2C_Write(ACCEL_CONFIG, 0x01);</li><li>}</li><li>/**********************************************************/</li><li>//函数名称:int Get16Bit</li><li>//入口参数:address:读取数据的地址</li><li>//出口参数:无</li><li>//函数功能:获取MPU6050相应地址上的数据</li><li>/**********************************************************/</li><li>int Get16Bit (unsigned char  address)</li><li>{</li><li>#ifndef MULTIREAD</li><li>  unsigned char  ho,lo;</li><li>  int temp ;</li><li>  ho = I2C_Read(address);</li><li>  lo = I2C_Read(address+1);</li><li>  temp=ho;</li><li>  temp<<=8;</li><li>  temp+=lo;</li><li>  return temp ;</li><li>#else</li><li>  return( Double_Read_ADXL345(address));</li><li>#endif</li><li>}</li><li>/**********************************************************/</li><li>//函数名称:</li><li>//入口参数:无</li><li>//出口参数:无</li><li>//函数功能:获取MPU6050相应轴上的加速度数据</li><li>/**********************************************************/</li><li>// X/Y/Z-Axis Acceleration</li><li>int GetAccelX ()</li><li>{</li><li>  return Get16Bit(ACCEL_XOUT_H);</li><li>}</li><li></li><li>int GetAccelY ()</li><li>{</li><li>  return Get16Bit(ACCEL_YOUT_H);</li><li>}</li><li></li><li>int GetAccelZ ()</li><li>{</li><li>  return Get16Bit(ACCEL_ZOUT_H);</li><li>}</li><li>/**********************************************************/</li><li>//函数名称:</li><li>//入口参数:无</li><li>//出口参数:无</li><li>//函数功能:获取MPU6050相应轴上的角速度数据</li><li>/**********************************************************/</li><li>// X/Y/Z-Axis Angular velocity</li><li>int GetAnguX ()</li><li>{</li><li>  return Get16Bit(GYRO_XOUT_H);</li><li>}</li><li></li><li>int GetAnguY ()</li><li>{</li><li>  return Get16Bit(GYRO_YOUT_H);</li><li>}</li><li></li><li>int GetAnguZ ()</li><li>{</li><li>  return Get16Bit(GYRO_ZOUT_H);</li><li>}</li><li></li><li></li><li></li><li>#include"msp430iic.h"  </li><li></li><li>struct MPU6050Struct    MPU6050Data;</li><li>void InitImitateIICPort(void)</li><li>{</li><li>  SET_SDA_OUT;          //set  SDA PIN is out mode</li><li>  SDA_HIGH;             // set SDA PIN out is high</li><li>  SCL_HIGH;             //set SCL PIN is input mode ,pull up register to SCL PIN high</li><li>}</li><li></li><li>/**************************************</li><li>起始信号</li><li>**************************************/</li><li>void ADXL345_Start(void)</li><li>{</li><li>    SET_SDA_OUT;</li><li>    SDA_HIGH;                    //拉高数据线</li><li>    SCL_HIGH;                    //拉高时钟线</li><li>    Delay5us();                 //延时</li><li>    SDA_LOW;                    //产生下降沿</li><li>    Delay5us();                 //延时</li><li>    SCL_LOW;                    //拉低时钟线</li><li>}</li><li></li><li>/**************************************</li><li>停止信号</li><li>**************************************/</li><li>void ADXL345_Stop(void)</li><li>{</li><li>    SET_SDA_OUT;</li><li>    SDA_LOW;                    //拉低数据线</li><li>    SCL_HIGH;                    //拉高时钟线</li><li>    Delay5us();                 //延时</li><li>    SDA_HIGH;                    //产生上升沿</li><li>    Delay5us();                 //延时</li><li>}</li><li></li><li>/**************************************</li><li>发送应答信号</li><li>入口参数:ack (0:ACK 1:NAK)</li><li>**************************************/</li><li>void ADXL345_SendACK(unsigned char ack)</li><li>{</li><li>    SET_SDA_OUT;</li><li>    if(ack)</li><li>      SDA_HIGH;                //写NACK应答信号</li><li>    else</li><li>      SDA_LOW;                 //写ACK应答信号</li><li>    SCL_HIGH;                    //拉高时钟线</li><li>    Delay5us();                 //延时</li><li>    SCL_LOW;                    //拉低时钟线</li><li>    Delay5us();                 //延时</li><li>}</li><li></li><li>/**************************************</li><li>接收应答信号</li><li>**************************************/</li><li>unsigned char ADXL345_RecvACK(void)</li><li>{</li><li>    unsigned char ack;</li><li>    //------------------//</li><li>    //一下两句切不可调换顺序,否则会导致时序错误</li><li>    SET_SDA_IN;</li><li>    SCL_HIGH;                    //拉高时钟线  </li><li>    //-----------------//</li><li>    Delay5us();                 //延时</li><li>    ack = SDA_IN;                   //读应答信号</li><li>    SCL_LOW;                    //拉低时钟线</li><li>    Delay5us();                 //延时</li><li>    return ack;</li><li>}</li><li></li><li>/**************************************</li><li>向IIC总线发送一个字节数据</li><li>**************************************/</li><li>void ADXL345_Senduchar(unsigned char dat)</li><li>{</li><li>    unsigned char i,m;</li><li>    SET_SDA_OUT;</li><li>    for (i=8; i!=0; i--)         //8位计数器</li><li>    {</li><li>        m=dat & 0x80;           //移出数据的最高位</li><li>        if(m == 0x80)</li><li>            SDA_HIGH;</li><li>        else</li><li>            SDA_LOW;</li><li>        SCL_HIGH;                //拉高时钟线</li><li>        Delay5us();             //延时</li><li>        SCL_LOW;                //拉低时钟线</li><li>        dat=dat<<1;</li><li>        Delay5us();             //延时</li><li>    }</li><li>    ADXL345_RecvACK();</li><li>}</li><li></li><li>/**************************************</li><li>从IIC总线接收一个字节数据</li><li>**************************************/</li><li>unsigned char  ADXL345_Recvuchar(void)</li><li>{</li><li>    unsigned char  i;</li><li>    unsigned char dat = 0;</li><li>    unsigned char m;</li><li>    SDA_HIGH;                    //使能内部上拉,准备读取数据,</li><li>    SET_SDA_IN;</li><li>    for (i=8; i!=0; i--)         //8位计数器</li><li>    {</li><li>        dat <<= 1;</li><li>        SCL_HIGH;                //拉高时钟线</li><li>        SET_SDA_IN;</li><li>        m = SDA_IN;</li><li>        if(m == I2C_SDA)</li><li>            dat = dat|0x01;</li><li>        Delay5us();             //延时</li><li>        SCL_LOW;                //拉低时钟线</li><li>        Delay5us();             //延时</li><li>    }</li><li>    return dat;</li><li>}</li><li></li><li>//******单字节写入*******************************************</li><li></li><li>void Single_Write_ADXL345(unsigned char REG_Address,unsigned char REG_data)</li><li>{</li><li>    ADXL345_Start();                  //起始信号</li><li>    ADXL345_Senduchar(SlaveAddress);   //发送设备地址+写信号</li><li>    ADXL345_Senduchar(REG_Address);    //内部寄存器地址,请参考中文pdf22页</li><li>    ADXL345_Senduchar(REG_data);       //内部寄存器数据,请参考中文pdf22页</li><li>    ADXL345_Stop();                   //发送停止信号</li><li>}</li><li></li><li>//********单字节读取*****************************************</li><li>unsigned char  Single_Read_ADXL345(unsigned char  REG_Address)</li><li>{  unsigned char REG_data=0;</li><li>    ADXL345_Start();                          //起始信号</li><li>    ADXL345_Senduchar(SlaveAddress);           //发送设备地址+写信号</li><li>    ADXL345_Senduchar(REG_Address);                   //发送存储单元地址,从0开始</li><li>    ADXL345_Start();                          //起始信号</li><li>    ADXL345_Senduchar(SlaveAddress+1);         //发送设备地址+读信号</li><li>    REG_data=ADXL345_Recvuchar();              //读出寄存器数据</li><li>    ADXL345_SendACK(1);                     //NACK</li><li>    ADXL345_Stop();                           //停止信号</li><li>    return REG_data;</li><li>}</li><li>//********多字节读取*****************************************</li><li>int  Double_Read_ADXL345(unsigned char  REG_Address)</li><li>{</li><li>    unsigned char ValueL=0;</li><li>    int Value=0;</li><li>    ADXL345_Start();                            //起始信号</li><li>    ADXL345_Senduchar(SlaveAddress);            //发送设备地址+写信号</li><li>    ADXL345_Senduchar(REG_Address);             //发送存储单元地址,从0开始</li><li>    ADXL345_Start();                            //起始信号</li><li>    ADXL345_Senduchar(SlaveAddress+1);          //发送设备地址+读信号</li><li>   </li><li>    Value=ADXL345_Recvuchar();                  //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    ValueL=ADXL345_Recvuchar();                 //读出寄存器数据</li><li>    ADXL345_SendACK(1);                         //NACK</li><li>   </li><li>    ADXL345_Stop();                             //停止信号</li><li>    Value=(Value<<8)+ValueL;</li><li>    return Value;</li><li>}</li><li></li><li>struct MPU6050Struct *ReadMPU6050All()</li><li>{</li><li>  unsigned char TempAcc1=0,TempAcc2=0,TempAcc3=0,TempAcc4=0,TempAcc5=0,TempAcc6=0;</li><li>  unsigned char TempGyro1=0,TempGyro2=0,TempGyro3=0,TempGyro4=0,TempGyro5=0,TempGyro6=0;</li><li></li><li>    ADXL345_Start();                            //起始信号</li><li>    ADXL345_Senduchar(SlaveAddress);            //发送设备地址+写信号</li><li>    ADXL345_Senduchar(0x3B);                    //发送存储单元地址,从0x3b开始</li><li>    ADXL345_Start();                            //起始信号</li><li>    ADXL345_Senduchar(SlaveAddress+1);          //发送设备地址+读信号</li><li>   </li><li>    TempAcc2=ADXL345_Recvuchar();                  //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempAcc1=ADXL345_Recvuchar();                 //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempAcc4=ADXL345_Recvuchar();                  //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempAcc3=ADXL345_Recvuchar();                 //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempAcc6=ADXL345_Recvuchar();                  //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempAcc5=ADXL345_Recvuchar();                 //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    ADXL345_Recvuchar();                         //丢弃不连续地址的数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    ADXL345_Recvuchar();                         //丢弃不连续地址的数据</li><li>    ADXL345_SendACK(0);</li><li>   </li><li>    TempGyro2=ADXL345_Recvuchar();                  //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempGyro1=ADXL345_Recvuchar();                 //读出寄存器数据</li><li>    ADXL345_SendACK(0);</li><li>   </li><li>    TempGyro4=ADXL345_Recvuchar();                  //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempGyro3=ADXL345_Recvuchar();                 //读出寄存器数据</li><li>    ADXL345_SendACK(0);</li><li>   </li><li>    TempGyro6=ADXL345_Recvuchar();                  //读出寄存器数据</li><li>    ADXL345_SendACK(0);                         //ACK</li><li>   </li><li>    TempGyro5=ADXL345_Recvuchar();                 //读出寄存器数据</li><li>    ADXL345_SendACK(1);                         //NACK</li><li>   </li><li>    ADXL345_Stop();</li><li></li><li>    MPU6050Data.MPU6050_ACC_X=(TempAcc2<<8) + TempAcc1;</li><li>    MPU6050Data.MPU6050_ACC_Y=(TempAcc4<<8) + TempAcc3;</li><li>    MPU6050Data.MPU6050_ACC_Z=(TempAcc6<<8) + TempAcc5;</li><li>   </li><li>    MPU6050Data.MPU6050_GYRO_X=(TempGyro2<<8) + TempGyro1;</li><li>    MPU6050Data.MPU6050_GYRO_Y=(TempGyro4<<8) + TempGyro3;</li><li>    MPU6050Data.MPU6050_GYRO_Z=(TempGyro6<<8) + TempGyro5;</li><li>    return (&MPU6050Data);</li><li>}</li><li></li><li></li><li>/*</li><li> * This file contains some uSCI_A0 operation.</li><li> * By IC爬虫 (<a href="mailto:1394024051@qq.com">1394024051@qq.com</a>)</li><li> * 2014-4-28 v1.0</li><li> */</li><li>//#include "msp430g2553.h"</li><li>#include "USCI_A0.h"</li><li>//#include "stdio.h"</li><li>#include "mpu6050.h"</li><li>#include "IMU.h"</li><li></li><li>#define uchar unsigned char</li><li>#define uint unsigned int</li><li></li><li>//将“int”类型的数据分成两个单字节的数据</li><li>#define BYTE0(dwTemp)       (*(char *)(&dwTemp))</li><li>#define BYTE1(dwTemp)       (*((char *)(&dwTemp) + 1))</li><li>#define BYTE2(dwTemp)       (*((char *)(&dwTemp) + 2))</li><li>#define BYTE3(dwTemp)       (*((char *)(&dwTemp) + 3))</li><li></li><li>/*********************************************************</li><li>*名称:USCI_A0_init</li><li>*功能:串口初始化</li><li>*入口参数:无</li><li>*出口参数:无</li><li>*说明:设置为P1.1和P1.2为串口通信端口</li><li>**********************************************************/</li><li>void USCI_A0_init(void)</li><li>{</li><li>  P1SEL = BIT1 + BIT2 ;   // P1.1 = RXD, P1.2=TXD</li><li>  P1SEL2 = BIT1 + BIT2;                     </li><li>  UCA0CTL1 |= UCSSEL_2;   // SMCLK</li><li>  /*</li><li>  UCA0BR0 = 0x45;         // 8MHz 115200</li><li>  UCA0BR1 = 0;            // 8MHz 115200</li><li>  UCA0MCTL = 0x4a;        // 8MHz 115200  */   </li><li>  /*</li><li>  UCA0BR0 = 0x68;</li><li>  UCA0BR1 = 0;</li><li>  UCA0MCTL = 0x40;</li><li>  */</li><li>  UCA0MCTL = UCBRF_0 | UCBRS_4;</li><li>   </li><li>    /* Baud rate control register 0 */</li><li>    UCA0BR0 = 69;</li><li>  UCA0CTL1 &= ~UCSWRST;          // **Initialize USCI state machine**</li><li>  </li><li>  //IE2 |= UCA0RXIE + UCA0TXIE;  // Enable USCI_A0 TX/RX interrupt</li><li>  //IE2 |= UCA0RXIE;             // Enable USCI_A0 RX interrupt</li><li>  //__bis_SR_register(GIE);      // Enter LPM3 w/ interrupts enabled</li><li>}</li><li></li><li></li><li>/*********************************************************</li><li>*名称:UartTX_Send_String</li><li>*功能:串口发送字符串函数</li><li>*入口参数:*data:数据指针        len :数据长度</li><li>*出口参数:无</li><li>*说明:</li><li>**********************************************************/</li><li>void UartTX_Send_String(unsigned char *Data,int len)</li><li>{</li><li>  int j;</li><li>  for(j=0;j<len;j++)</li><li>  {</li><li>    UartTX_Send_char(*Data++);</li><li>  }</li><li>}</li><li></li><li>/*********************************************************</li><li>*名称:UartTX_Send_char</li><li>*功能:串口发送字符函数</li><li>*入口参数:c</li><li>*出口参数:无</li><li>*说明:</li><li>**********************************************************/</li><li>unsigned char UartTX_Send_char(unsigned char c)</li><li>{</li><li>    UCA0TXBUF=c;   </li><li>    while(!(IFG2&UCA0TXIFG));</li><li>    IFG2&=~UCA0TXIFG;</li><li>    return c;</li><li>}</li><li>/*********************************************************</li><li>*名称:int putchar</li><li>*功能:串口发送字符函数</li><li>*入口参数:ch</li><li>*出口参数:无</li><li>*说明:</li><li>**********************************************************/</li><li>int putchar(int ch)</li><li>{</li><li>  UCA0TXBUF=ch;</li><li>  while(!(IFG2&UCA0TXIFG));</li><li>   //UCA0TXBUF=ch;</li><li>  IFG2&=~UCA0TXIFG;</li><li>   return ch;</li><li>}</li><li></li><li></li><li>void sendChar(unsigned char c)</li><li> {</li><li>   while(!(IFG2&UCA0TXIFG));</li><li>   UCA0TXBUF=c;</li><li> }</li><li></li><li>void sendStr(unsigned char *s)</li><li>{</li><li>  while(*s!='\0')</li><li>  {</li><li>    sendChar(*s);</li><li>    s++;</li><li>  }</li><li>}</li><li></li><li>/*********************************************************</li><li>*名称:void Uart1_Send_AF</li><li>*功能:串口发送姿态数据</li><li>*入口参数:无</li><li>*出口参数:无</li><li>*说明:每一次执行这个函数就算是一帧数据,帧头为0X88,功能字</li><li>*      为0XAF</li><li>**********************************************************/</li><li>void Uart1_Send_AF(void)</li><li>{</li><li>  unsigned char sum = 0;//累加串口发送的数据的值,做校验用</li><li>  unsigned int _temp;   </li><li>  sum += UartTX_Send_char(0x88);  //帧头</li><li>  sum += UartTX_Send_char(0xAF);  //功能字</li><li>  </li><li>  sum += UartTX_Send_char(0x1c);</li><li>  sum += UartTX_Send_char( BYTE1(MPU6050_ACC_LAST_X) ); //发送加速度X轴数据的高8位</li><li>  sum += UartTX_Send_char( BYTE0(MPU6050_ACC_LAST_X) ); //发送加速度X轴数据的低8位</li><li>  </li><li>  sum += UartTX_Send_char( BYTE1(MPU6050_ACC_LAST_Y) ); //发送加速度Y轴数据的高8位</li><li>  sum += UartTX_Send_char( BYTE0(MPU6050_ACC_LAST_Y) ); //发送加速度Y轴数据的低8位</li><li>  </li><li>  sum += UartTX_Send_char( BYTE1(MPU6050_ACC_LAST_Z) ); //发送加速度Z轴数据的高8位</li><li>  sum += UartTX_Send_char( BYTE0(MPU6050_ACC_LAST_Z) ); //发送加速度Z轴数据的低8位</li><li>  </li><li>  sum += UartTX_Send_char( BYTE1(MPU6050_GYRO_LAST_X) ); //发送陀螺仪X轴数据的高8位</li><li>  sum += UartTX_Send_char( BYTE0(MPU6050_GYRO_LAST_X) ); //发送陀螺仪X轴数据的低8位</li><li>  </li><li>  sum += UartTX_Send_char( BYTE1(MPU6050_GYRO_LAST_Y) ); //发送陀螺仪Y轴数据的高8位</li><li>  sum += UartTX_Send_char( BYTE0(MPU6050_GYRO_LAST_Y) ); //发送陀螺仪Y轴数据的低8位</li><li>  </li><li>  sum += UartTX_Send_char( BYTE1(MPU6050_GYRO_LAST_Z) ); //发送陀螺仪Z轴数据的高8位</li><li>  sum += UartTX_Send_char( BYTE0(MPU6050_GYRO_LAST_Z) ); //发送陀螺仪Z轴数据的低8位</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>        </li><li>  _temp = (long int)(Q_ANGLE_X*100);</li><li>  sum += UartTX_Send_char( BYTE1(_temp) );</li><li>  sum += UartTX_Send_char( BYTE0(_temp) );</li><li>  _temp = (long int)(Q_ANGLE_Y*100);</li><li>  sum += UartTX_Send_char( BYTE1(_temp) );</li><li>  sum += UartTX_Send_char( BYTE0(_temp) );</li><li>        </li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  sum += UartTX_Send_char(0);</li><li>  </li><li>  UartTX_Send_char(sum); //串口发送累加值用于校验</li><li>}</li><li></li><li></li><li>/*</li><li> * This file contains some IMU operation.</li><li> * By IC爬虫 (<a href="mailto:1394024051@qq.com">1394024051@qq.com</a>)</li><li> * 2014-4-29 v1.0</li><li> */</li><li>#include "IMU.h"</li><li></li><li>#define RtA           57.324841  //弧度到角度</li><li>#define AtR              0.0174533  //度到角度</li><li>#define Acc_G           0.0011963  //加速度变成G</li><li>#define Gyro_G           0.0152672  //角速度变成度</li><li>#define Gyro_Gr          0.0002663                                </li><li>#define FILTER_NUM 20</li><li></li><li>int   ACC_AVG_X,ACC_AVG_Y,ACC_AVG_Z;      //平均值滤波后的ACC</li><li>float GYRO_I_X,GYRO_I_Y,GYRO_I_Z;         //陀螺仪积分</li><li>float EXP_ANGLE_X,EXP_ANGLE_Y,EXP_ANGLE_Z;//期望角度</li><li>float DIF_ANGLE_X,DIF_ANGLE_Y,DIF_ANGLE_Z;//期望角度和实际角度的差</li><li>float Q_ANGLE_X,Q_ANGLE_Y,Q_ANGLE_Z;      //四元数计算出的角度</li><li></li><li>int ACC_X_BUF[FILTER_NUM],ACC_Y_BUF[FILTER_NUM],ACC_Z_BUF[FILTER_NUM];        //加速度滑动窗口滤波数组</li><li></li><li>/**********************************************************/</li><li>//函数名称:Prepare_Data</li><li>//入口参数:无</li><li>//出口参数:无</li><li>//函数功能:读取MPU6050数据进行平滑滤波,为后续计算准备数据</li><li>/**********************************************************/</li><li>void Prepare_Data(void)</li><li>{</li><li>  static unsigned char filter_cnt=0;</li><li>  long int temp1=0,temp2=0,temp3=0;</li><li>  unsigned char i;</li><li>        </li><li>  MPU6050_Dataanl();//完成传感器数据的读取和计算,并且对数据简单处理</li><li>        </li><li>  ACC_X_BUF[filter_cnt] = MPU6050_ACC_LAST_X;//更新滑动窗口数组</li><li>  ACC_Y_BUF[filter_cnt] = MPU6050_ACC_LAST_Y;</li><li>  ACC_Z_BUF[filter_cnt] = MPU6050_ACC_LAST_Z;</li><li>  </li><li>  for(i=0;i<FILTER_NUM;i++)</li><li>  {</li><li>    temp1 += ACC_X_BUF<i>;</i></li><li><i>    temp2 += ACC_Y_BUF<i>;</i></i></li><li><i><i>    temp3 += ACC_Z_BUF<i>;</i></i></i></li><li><i><i><i>  }</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  ACC_AVG_X = temp1 / FILTER_NUM;</i></i></i></li><li><i><i><i>  ACC_AVG_Y = temp2 / FILTER_NUM;</i></i></i></li><li><i><i><i>  ACC_AVG_Z = temp3 / FILTER_NUM;</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  filter_cnt++;</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  if(filter_cnt==FILTER_NUM)  filter_cnt=0;</i></i></i></li><li><i><i><i>        </i></i></i></li><li><i><i><i>  GYRO_I_X += MPU6050_GYRO_LAST_X*Gyro_G*0.02;//0.0001是时间间隔,两次prepare函数的执行周期</i></i></i></li><li><i><i><i>  GYRO_I_Y += MPU6050_GYRO_LAST_Y*Gyro_G*0.02;//示波器测量的得到的时间是20ms.</i></i></i></li><li><i><i><i>  GYRO_I_Z += MPU6050_GYRO_LAST_Z*Gyro_G*0.02;</i></i></i></li><li><i><i><i>}</i></i></i></li><li></li><li><i><i><i>void Get_Attitude(void)</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  IMUupdate( MPU6050_GYRO_LAST_X*Gyro_Gr,</i></i></i></li><li><i><i><i>            MPU6050_GYRO_LAST_Y*Gyro_Gr,</i></i></i></li><li><i><i><i>            MPU6050_GYRO_LAST_Z*Gyro_Gr,</i></i></i></li><li><i><i><i>            ACC_AVG_X,ACC_AVG_Y,ACC_AVG_Z);        //*0.0174转成弧度</i></i></i></li><li><i><i><i>}</i></i></i></li><li><i><i><i>////////////////////////////////////////////////////////////////////////////////</i></i></i></li><li><i><i><i>#define Kp 10.0f        // proportional gain governs rate of convergence to accelerometer/magnetometer</i></i></i></li><li><i><i><i>#define Ki 0.008f       // integral gain governs rate of convergence of gyroscope biases</i></i></i></li><li><i><i><i>#define halfT 0.004f    // half the sample period采样周期的一半</i></i></i></li><li></li><li><i><i><i>float q0 = 1, q1 = 0, q2 = 0, q3 = 0;    // quaternion elements representing the estimated orientation</i></i></i></li><li><i><i><i>float exInt = 0, eyInt = 0, ezInt = 0;    // scaled integral error</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>//函数名称:IMUupdate</i></i></i></li><li><i><i><i>//入口参数:gx:浮点型的陀螺仪x轴数据</i></i></i></li><li><i><i><i>//          gy:浮点型的陀螺仪y轴数据</i></i></i></li><li><i><i><i>//          gz:浮点型的陀螺仪z轴数据</i></i></i></li><li><i><i><i>//          ax:浮点型的加速度x轴数据</i></i></i></li><li><i><i><i>//          ay:浮点型的加速度y轴数据</i></i></i></li><li><i><i><i>//          az:浮点型的加速度z轴数据</i></i></i></li><li><i><i><i>//出口参数:无</i></i></i></li><li><i><i><i>//函数功能:通过陀螺仪和加速度传感器的数据用四元数计算姿态</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  float norm;</i></i></i></li><li><i><i><i>//  float hx, hy, hz, bx, bz;</i></i></i></li><li><i><i><i>  float vx, vy, vz;// wx, wy, wz;</i></i></i></li><li><i><i><i>  float ex, ey, ez;</i></i></i></li><li></li><li><i><i><i>  //先把这些需要用到的值弄好</i></i></i></li><li><i><i><i>  float q0q0 = q0*q0;</i></i></i></li><li><i><i><i>  float q0q1 = q0*q1;</i></i></i></li><li><i><i><i>  float q0q2 = q0*q2;</i></i></i></li><li><i><i><i>//  float q0q3 = q0*q3;</i></i></i></li><li><i><i><i>  float q1q1 = q1*q1;</i></i></i></li><li><i><i><i>//  float q1q2 = q1*q2;</i></i></i></li><li><i><i><i>  float q1q3 = q1*q3;</i></i></i></li><li><i><i><i>  float q2q2 = q2*q2;</i></i></i></li><li><i><i><i>  float q2q3 = q2*q3;</i></i></i></li><li><i><i><i>  float q3q3 = q3*q3;</i></i></i></li><li><i><i><i>        </i></i></i></li><li><i><i><i>  if(ax*ay*az==0) return;</i></i></i></li><li><i><i><i>               </i></i></i></li><li><i><i><i>  norm = sqrt(ax*ax + ay*ay + az*az);//acc数据归一化</i></i></i></li><li><i><i><i>  ax = ax /norm;</i></i></i></li><li><i><i><i>  ay = ay / norm;</i></i></i></li><li><i><i><i>  az = az / norm;</i></i></i></li><li></li><li><i><i><i>  // estimated direction of gravity and flux (v and w)   估计重力方向和流量/变迁</i></i></i></li><li><i><i><i>  vx = 2*(q1q3 - q0q2);        //四元数中xyz的表示</i></i></i></li><li><i><i><i>  vy = 2*(q0q1 + q2q3);</i></i></i></li><li><i><i><i>  vz = q0q0 - q1q1 - q2q2 + q3q3 ;</i></i></i></li><li></li><li><i><i><i>  // error is sum of cross product between reference direction of fields and direction measured by sensors</i></i></i></li><li><i><i><i>  ex = (ay*vz - az*vy) ;   //向量外积在相减得到差分就是误差</i></i></i></li><li><i><i><i>  ey = (az*vx - ax*vz) ;</i></i></i></li><li><i><i><i>  ez = (ax*vy - ay*vx) ;</i></i></i></li><li></li><li><i><i><i>  exInt = exInt + ex * Ki; //对误差进行积分</i></i></i></li><li><i><i><i>  eyInt = eyInt + ey * Ki;</i></i></i></li><li><i><i><i>  ezInt = ezInt + ez * Ki;</i></i></i></li><li></li><li><i><i><i>  // adjusted gyroscope measurements</i></i></i></li><li><i><i><i>  gx = gx + Kp*ex + exInt; //将误差PI后补偿到陀螺仪,即补偿零点漂移</i></i></i></li><li><i><i><i>  gy = gy + Kp*ey + eyInt;</i></i></i></li><li><i><i><i>  gz = gz + Kp*ez + ezInt; //这里的gz由于没有观测者进行矫正会产生漂移,变现出来的就是积分自增或者自减</i></i></i></li><li></li><li><i><i><i>  // integrate quaternion rate and normalise //四元数的微分方程</i></i></i></li><li><i><i><i>  q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;</i></i></i></li><li><i><i><i>  q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;</i></i></i></li><li><i><i><i>  q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;</i></i></i></li><li><i><i><i>  q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;</i></i></i></li><li></li><li><i><i><i>  // normalise quaternion</i></i></i></li><li><i><i><i>  norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);</i></i></i></li><li><i><i><i>  q0 = q0 / norm;</i></i></i></li><li><i><i><i>  q1 = q1 / norm;</i></i></i></li><li><i><i><i>  q2 = q2 / norm;</i></i></i></li><li><i><i><i>  q3 = q3 / norm;</i></i></i></li><li></li><li><i><i><i>  //Q_ANGLE.Yaw = atan2(2 * q1 * q2 + 2 * q0 * q3, -2 * q2*q2 - 2 * q3* q3 + 1)* 57.3; // yaw</i></i></i></li><li><i><i><i>  Q_ANGLE_Y  = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch</i></i></i></li><li><i><i><i>  Q_ANGLE_X = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll</i></i></i></li><li><i><i><i>}</i></i></i></li><li></li><li></li><li></li><li></li><li><i><i><i>/*</i></i></i></li><li><i><i><i> * This file contains some I2C operation.</i></i></i></li><li><i><i><i> * By IC爬虫 (<a href="mailto:1394024051@qq.com">1394024051@qq.com</a>)</i></i></i></li><li><i><i><i> * 2014-4-13 v1.0</i></i></i></li><li><i><i><i> */</i></i></i></li><li><i><i><i>#include "HardWareIIC.h"</i></i></i></li><li></li><li><i><i><i>uchar I2CSendBuffer[2],I2CRecvBuffer; //I2C发送缓存和接收缓存</i></i></i></li><li></li><li><i><i><i>int I2CSendPtr=0;</i></i></i></li><li></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>//函数名称:void I2C_Init</i></i></i></li><li><i><i><i>//入口参数:SlaveAddr:从机的设备地址</i></i></i></li><li><i><i><i>//出口参数:无</i></i></i></li><li><i><i><i>//函数功能:I2C初始化,P1.6->SCL ,P1.7->SDA</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>void I2C_Init (unsigned char SlaveAddr)</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  P1SEL |= BIT6+BIT7;               // Assign I2C pins to USCI_B0</i></i></i></li><li><i><i><i>  P1SEL2|= BIT6+BIT7;               // Assign I2C pins to USCI_B0</i></i></i></li><li><i><i><i>  UCB0CTL1 |= UCSWRST;              // Enable SW reset</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0CTL0 = UCMST+UCMODE_3+UCSYNC; // I2C Master, synchronous mode</i></i></i></li><li><i><i><i>  UCB0CTL0 &= ~(UCSLA10+UCA10);                        //7 bit add of slave and master</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0CTL1 = UCSSEL_2+UCSWRST;      // Use SMCLK, keep SW reset</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0BR0 = 80;                     // fSCL = SMCLK/12 = ~100kHz</i></i></i></li><li><i><i><i>  UCB0BR1 = 0;</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0I2COA = 0x01A5;                                                                //set own address</i></i></i></li><li><i><i><i>  UCB0I2CSA = SlaveAddr;            // Set slave address</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  IE2 &= ~(UCB0RXIE+UCB0TXIE);         // disenable  TX&RX interrupt</i></i></i></li><li><i><i><i>  UCB0CTL1 &= ~UCSWRST;             // Clear SW reset, resume operation</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>}</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>//函数名称:void I2C_WriteInit</i></i></i></li><li><i><i><i>//入口参数:无</i></i></i></li><li><i><i><i>//出口参数:无</i></i></i></li><li><i><i><i>//函数功能:I2C写数据初始化,发送模式,接收中断关闭,发送中断关闭</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>void I2C_WriteInit()</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  UCB0CTL1 |= UCTR;            // UCTR=1 => Transmit Mode (R/W bit = 0)</i></i></i></li><li><i><i><i>  IFG2 &= ~UCB0TXIFG;                //clean TX interrupt sign</i></i></i></li><li><i><i><i>  IE2 &= ~UCB0RXIE;           // disable Receive ready interrupt</i></i></i></li><li><i><i><i>  IE2 &= ~UCB0TXIE;     // disable Transmit ready interrupt</i></i></i></li><li><i><i><i>}</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>//函数名称:void I2C_ReadInit</i></i></i></li><li><i><i><i>//入口参数:无</i></i></i></li><li><i><i><i>//出口参数:无</i></i></i></li><li><i><i><i>//函数功能:I2C读数据初始化,接收模式,接收中断关闭,发送中断关闭</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>void I2C_ReadInit()</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  UCB0CTL1 &= ~UCTR;   // UCTR=0 => Receive Mode (R/W bit = 1)</i></i></i></li><li><i><i><i>  IFG2 &= ~UCB0RXIFG;</i></i></i></li><li><i><i><i>  IE2 &= ~UCB0TXIE;    // disable Transmit ready interrupt</i></i></i></li><li><i><i><i>  IE2 &= ~UCB0RXIE;     // disable Receive ready interrupt</i></i></i></li><li><i><i><i>}</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>//函数名称:I2C_Write</i></i></i></li><li><i><i><i>//入口参数:address:需要写入数据的设备的地址</i></i></i></li><li><i><i><i>//          data:发送的数据</i></i></i></li><li><i><i><i>//出口参数:无</i></i></i></li><li><i><i><i>//函数功能:I2C发送数据</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>void I2C_Write(uchar address,uchar data)</i></i></i></li><li><i><i><i>{</i></i></i></li><li></li><li><i><i><i>  I2C_WriteInit();</i></i></i></li><li><i><i><i>  UCB0CTL1 |= UCTXSTT;          //generate start condition</i></i></i></li><li><i><i><i>  //while(UCB0CTL1 & UCTXSTT);        //generate start condition ,and transmit slave address and write bit</i></i></i></li><li><i><i><i>  while(!(IFG2 & UCB0TXIFG));   //wait start condition and equipment address transmitted</i></i></i></li><li><i><i><i>  IFG2 &= ~UCB0TXIFG;           //clean UCB0TXIFG</i></i></i></li><li><i><i><i>  while(UCB0CTL1 & UCTXSTT);    //wait slave acknowledge</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0TXBUF=address;                //send address code</i></i></i></li><li><i><i><i>  while(!(IFG2 & UCB0TXIFG ));        //wait sending over</i></i></i></li><li><i><i><i>  IFG2 &= ~UCB0TXIFG;            // Clear USCI_B0 TX int flag</i></i></i></li><li><i><i><i>   </i></i></i></li><li><i><i><i>  UCB0TXBUF=data;                //send  data</i></i></i></li><li><i><i><i>  while(!(IFG2 & UCB0TXIFG ));                //wait sending over</i></i></i></li><li><i><i><i>  IFG2 &= ~UCB0TXIFG;            // Clear USCI_B0 TX int flag</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0CTL1 |= UCTXSTP;            // I2C stop condition</i></i></i></li><li><i><i><i>  while (UCB0CTL1 & UCTXSTP);     // Ensure stop condition got sent</i></i></i></li><li><i><i><i>}</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>//函数名称:uchar I2C_Read</i></i></i></li><li><i><i><i>//入口参数:address:需要读数据的设备的地址</i></i></i></li><li><i><i><i>//出口参数:无</i></i></i></li><li><i><i><i>//函数功能:I2C接收数据</i></i></i></li><li><i><i><i>/**********************************************************/</i></i></i></li><li><i><i><i>uchar I2C_Read(uchar address)</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  unsigned char data;</i></i></i></li><li><i><i><i>  while (UCB0STAT & UCBUSY); // wait until I2C module has finished all operations</i></i></i></li><li><i><i><i>  I2C_WriteInit();</i></i></i></li><li><i><i><i>  UCB0CTL1 |= UCTXSTT;       // start condition generation</i></i></i></li><li><i><i><i>  while(UCB0CTL1 & UCTXSTT);</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0TXBUF=address;                                                        //send address code</i></i></i></li><li><i><i><i>  while(!(IFG2 & UCB0TXIFG ));                //wait sending over</i></i></i></li><li><i><i><i>  IFG2 &= ~UCB0TXIFG;            // Clear USCI_B0 TX int flag</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i> // __disable_interrupt();</i></i></i></li><li><i><i><i> I2C_ReadInit();</i></i></i></li><li><i><i><i>  while(UCB0RXIFG & IFG2);</i></i></i></li><li><i><i><i>  IFG2 &= ~UCB0RXIFG;</i></i></i></li><li><i><i><i>  data  = UCB0RXBUF;</i></i></i></li><li><i><i><i>  </i></i></i></li><li><i><i><i>  UCB0CTL1 |= UCTXSTP;            // I2C stop condition</i></i></i></li><li><i><i><i>  while (UCB0CTL1 & UCTXSTP);     // Ensure stop condition got sent</i></i></i></li><li><i><i><i>  return data;</i></i></i></li><li><i><i><i>}</i></i></i></li><li></li><li><i><i><i>/*----------------------------------------------------------------------------*/</i></i></i></li><li><i><i><i>// Description:</i></i></i></li><li><i><i><i>//   Acknowledge Polling. The EEPROM will not acknowledge if a write cycle is</i></i></i></li><li><i><i><i>//   in progress. It can be used to determine when a write cycle is completed.</i></i></i></li><li><i><i><i>/*----------------------------------------------------------------------------*/</i></i></i></li><li><i><i><i>void I2C_AckPolling(void)</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  while (UCB0STAT & UCBUSY)</i></i></i></li><li><i><i><i>  {     </i></i></i></li><li><i><i><i>    ;// wait until I2C module has</i></i></i></li><li><i><i><i>  }  // finished all operations</i></i></i></li><li></li><li><i><i><i>  do</i></i></i></li><li><i><i><i>  {</i></i></i></li><li><i><i><i>    UCB0STAT = 0x00;              // clear I2C interrupt flags</i></i></i></li><li><i><i><i>    UCB0CTL1 |= UCTR;             // I2CTRX=1 => Transmit Mode (R/W bit = 0)</i></i></i></li><li><i><i><i>    UCB0CTL1 &= ~UCTXSTT;</i></i></i></li><li><i><i><i>    UCB0CTL1 |= UCTXSTT;          // start condition is generated</i></i></i></li><li><i><i><i>    while (UCB0CTL1 & UCTXSTT)    // wait till I2CSTT bit was cleared</i></i></i></li><li><i><i><i>    {   </i></i></i></li><li><i><i><i>      if (!(UCNACKIFG & UCB0STAT))</i></i></i></li><li><i><i><i>      {  </i></i></i></li><li><i><i><i>        break;// Break out if ACK received</i></i></i></li><li><i><i><i>      }</i></i></i></li><li><i><i><i>    }</i></i></i></li><li><i><i><i>    UCB0CTL1 |= UCTXSTP;          // stop condition is generated after</i></i></i></li><li><i><i><i>                                  // slave address was sent => I2C communication is started</i></i></i></li><li><i><i><i>    while (UCB0CTL1 & UCTXSTP)</i></i></i></li><li><i><i><i>    {   </i></i></i></li><li><i><i><i>      ;// wait till stop bit is reset</i></i></i></li><li><i><i><i>    }</i></i></i></li><li><i><i><i>    __delay_cycles(500);          // Software delay</i></i></i></li><li><i><i><i>   </i></i></i></li><li><i><i><i>  } while (UCNACKIFG & UCB0STAT);</i></i></i></li><li><i><i><i>}</i></i></i></li><li></li><li></li><li><i><i><i>// USCI_B0 Data ISR</i></i></i></li><li><i><i><i>// Notice : UCSIAB0RX_ISR should be handle with UCSIAB0TX_ISR</i></i></i></li><li><i><i><i>#pragma vector = USCIAB0TX_VECTOR</i></i></i></li><li><i><i><i>__interrupt void USCIAB0TX_ISR(void)</i></i></i></li><li><i><i><i>{</i></i></i></li><li><i><i><i>  if (UCB0TXIFG & IFG2)      // TX</i></i></i></li><li><i><i><i>  {</i></i></i></li><li><i><i><i>    UCB0TXBUF = I2CSendBuffer[I2CSendPtr]; // Load TX buffer</i></i></i></li><li><i><i><i>    I2CSendPtr--;                          // Decrement TX byte counter</i></i></i></li><li><i><i><i>    if (I2CSendPtr < 0)</i></i></i></li><li><i><i><i>    {               </i></i></i></li><li><i><i><i>      while (!(IFG2 & UCB0TXIFG));         // wait for tx complete</i></i></i></li><li><i><i><i>      IE2 &= ~UCB0TXIE;                    // disable interrupts.</i></i></i></li><li><i><i><i>      IFG2 &= ~UCB0TXIFG;                  // Clear USCI_B0 TX int flag</i></i></i></li><li><i><i><i>      __bic_SR_register_on_exit(LPM0_bits);// Exit LPM0</i></i></i></li><li><i><i><i>    }</i></i></i></li><li><i><i><i>  }</i></i></i></li><li><i><i><i>  else if (UCB0RXIFG & IFG2) // RX</i></i></i></li><li><i><i><i>  {</i></i></i></li><li><i><i><i>    I2CRecvBuffer = UCB0RXBUF;             // store received data in buffer</i></i></i></li><li><i><i><i>    __bic_SR_register_on_exit(LPM0_bits);  // Exit LPM0</i></i></i></li><li><i><i><i>  }</i></i></i></li><li><i><i><i>}
  2. </i></i></i></li></ul><i><i><i>


  3. </i></i></i>
复制代码


0
2018-6-26 06:30:10   评论 邀请回答

只有小组成员才能发言,加入小组>>

36个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /7 下一条

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