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.
最近打算使用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);得到返回值如下
TI_USCI_I2C_slave_present(unsigned char slave_address);函数的解释如下
下面的图示我用示波器抓的图,表明从地址已发送,mpu6050也应答了。
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;我用示波器看波形,还是上面那个我抓的图。不知道是什么原因?
还是老话,你先要看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;去掉就接受不到数据了。
是的,还是建议按照TRITON说的先看看IIC协议,在看看USCIB的users guide;
上面的波形第8位是低,代表transmit data from master to salve,从机等着接数据,所以主机不可能接到数据的;
UCB0CTL1 &= ~UCTR;就是配置主机位receiver,这是再抓一下波形,第一BYTE第8位是为高。