This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

求助关于MSP430LAUNCHPAD Using the USCI I2C Master的使用方法?

Other Parts Discussed in Thread: MSP430G2553

最近打算使用MSP430的i2c驱动MPU6050.

我更改了TI_USCI_I2C_master.h头文件中的一些定义:
#define SDA_PIN 0x80                                  // msp430g2553 UCB0SDA pin
#define SCL_PIN 0x40                                  // msp430g2553 UCB0SCL pin
 

 
就是将SDA和SCL这两个引脚对应到MSP430LAUNCHPAD的引脚上。

对MPU6050的初始化我只用了这个的函数TI_USCI_I2C_transmitinit(MPU6050_DEFAULT_ADDRESS, 12);

在主函数中:我使用TI_USCI_I2C_slave_present(MPU6050_DEFAULT_ADDRESS);得到返回值如下



  1.   _EINT();
  2.   MPU6050Init();
  3.   while(1)
  4.   {
  5.           result= TI_USCI_I2C_slave_present(MPU6050_DEFAULT_ADDRESS);
  6.   }

TI_USCI_I2C_slave_present(unsigned char slave_address);函数的解释如下


下面的图示我用示波器抓的图,表明从地址已发送,mpu6050也应答了。

TI提供的程序:

http://www.deyisupport.com/cfs-file.ashx/__key/communityserver-discussions-components-files/55/3823.Using-the-USCI-I2C-Master.zip

MPU6050的地址也正确发送了

我的问题是:我打算使用TI提供的USCI I2C驱动程序来读取MPU6050的数据,但是 MPU6050 里面的寄存器也要初始化,那我该怎么调用函数呢? 向MPU6050中的寄存器赋值呢?

  • 函数1: void TI_USCI_I2C_receiveinit(unsigned char slave_address,  unsigned char prescale)

         这个函数用来初始化I2C模块,建议在上电初始化时使用,为了让系统健壮性更好,可以在检测到I2C错误,或者I2C总线挂掉时重新调用下本函数. 

    函数2: TI_USCI_I2C_slave_present(MPU6050_DEFAULT_ADDRESS);

       函数是用来检测从设备是否在线的。这个函数在读写操作调用之前调用,确保从设备地址是正确的。如果不判断这个,有可能造成I2C总线挂掉。具体原因以后探讨。

    函数3: void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field)

        本函数用来发送I2C数据,可以用在主机写从机寄存器的应用。 在使用本函数前把需要设置的从设备寄存器及数值放到*field指定的缓冲区中。 楼主要初始化MPU6050的寄存器就用该函数。

    函数4: void TI_USCI_I2C_receive(unsigned char byteCount, unsigned char *field)

      这个函数用来主机读从机数据。这是个基本函数,应用到具体芯片,需要和函数3配合使用。例如如果要读MPU6050的寄存器0X05的数值,

    需要如下调用:

     unsigned char TXBUF[10]={0x05,0x00,};

     unsigned char RXBUF[10];

     

      TI_USCI_I2C_transmit(1, TXBUF);

      TI_USCI_I2C_receive(1,RXBUF);

     

     

  • #include "mpu6050.h"

    根据6050 的数据手册,单字节写 是  从机地址 + 器件内部地址 + 写入数据,依次将这些数据写入下面数组中
    unsigned char PWR_MGMT[10]={MPU6050_DEFAULT_ADDRESS,PWR_MGMT_1,0x00};
    unsigned char SMPLRT[10]={MPU6050_DEFAULT_ADDRESS,SMPLRT_DIV, 0x07};
    unsigned char CON[10]={MPU6050_DEFAULT_ADDRESS,CONFIG, 0x06};
    unsigned char GYRO[10]={MPU6050_DEFAULT_ADDRESS,GYRO_CONFIG, 0x18};
    unsigned char ACCEL[10]={MPU6050_DEFAULT_ADDRESS,ACCEL_CONFIG, 0x01};

    void MPU6050Init()
    {
    TI_USCI_I2C_transmitinit(MPU6050_DEFAULT_ADDRESS, 12);
    while(TI_USCI_I2C_notready());
    if(TI_USCI_I2C_slave_present(MPU6050_DEFAULT_ADDRESS))
    {
      TI_USCI_I2C_transmit(3, PWR_MGMT);
      while(TI_USCI_I2C_notready());
      TI_USCI_I2C_transmit(3, SMPLRT);
      while(TI_USCI_I2C_notready());
      TI_USCI_I2C_transmit(3, CON);
      while(TI_USCI_I2C_notready());
      TI_USCI_I2C_transmit(3, GYRO);
      while(TI_USCI_I2C_notready());
      TI_USCI_I2C_transmit(3, ACCEL);
     }
    }

    问题是MSP430的UCB0TXBUF一直在发送0x01;我用示波器看波形,还是上面那个我抓的图。不知道是什么原因?

  • 单步看一下程序停在哪个地方了。

  • 大多数情况停留在while (UCB0CTL1 & UCTXSTP);    语句

  • 还是老话,你先要看I2C协议啊,不看协议怎么分析波形。

    你上面的波形是发送一个写操作的地址给从机,从机的设备地址为(68H,也可以说是D0H), 在这个波形之后才是送给TXBUF的值。

    你调试时代码停在那条语句是因为你没有发出STOP信号.

  • I2C从设备地址在TI_USCI_I2C_transmit函数中自动发送,即在设置START信号时产生,不需要再在你的数组中发一次,你在发一次地址的结果就造成了MPU6050的寄存器地址出错,设备可能不给响应。把上面数组中定义的MPU6050_DEFAULT_ADDRESS去掉,发送字节数减去1即可。

  • 我在原函数TI_USCI_I2C_receive()中添加了一句UCB0CTL1 &= ~UCTR;

    void TI_USCI_I2C_receive(unsigned char byteCount, unsigned char *field){
    TI_receive_field = field;
    UCB0CTL1 &= ~UCTR; //Receiver
    if ( byteCount == 1 ){
    byteCtr = 0 ;
    __disable_interrupt();
    UCB0CTL1 |= UCTXSTT; // I2C start condition
    while (UCB0CTL1 & UCTXSTT); // Start condition sent?
    UCB0CTL1 |= UCTXSTP; // I2C stop condition
    __enable_interrupt();
    } else if ( byteCount > 1 ) {
    byteCtr = byteCount - 2 ;
    UCB0CTL1 |= UCTXSTT; // I2C start condition
    } else
    while (1); // illegal parameter
    }

    接收寄存器收到数据了,

    但是把这个UCB0CTL1 &= ~UCTR;去掉就接受不到数据了。

    这是我的程序

    http://www.deyisupport.com/cfs-file.ashx/__key/communityserver-discussions-components-files/55/6888.TI_5F00_USCI_5F00_I2C_5F00_master.zip

  • 是的,还是建议按照TRITON说的先看看IIC协议,在看看USCIB的users guide;

    上面的波形第8位是低,代表transmit data from master to salve,从机等着接数据,所以主机不可能接到数据的;

    UCB0CTL1 &= ~UCTR;就是配置主机位receiver,这是再抓一下波形,第一BYTE第8位是为高。