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.

[参考译文] CCS/MSP432P401R:与 MPU6050进行 I2C 通信:未正确发送 DriverLib 通信停止条件?

Guru**** 2616675 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/669055/ccs-msp432p401r-i2c-communication-with-mpu6050-driverlib-communication-stop-condition-not-sent-correctly

器件型号:MSP432P401R

工具/软件:Code Composer Studio

问题:MSP432 EUSCI_B0模块(I2C 主器件)和 MPU6050 (I2C 从器件)之间的通信可用于一次迭代。 我能够写入寄存器进行初始化。 我通过多个单字节写入操作来执行此操作、因为要写入的寄存器是不连续的。  我还能够使用突发读取序列从 MPU6050读取这些(或任何其他)寄存器。 但是、之后不能再对 I2C 从设备进行读取/写入操作。 在可以再次读取/写入之前、我必须对 MPU6050进行循环供电。 在我关闭 MPU6050并打开 MPU6050之前,即使是具有电路板复位功能的同一代码的另一次运行也不能再运行。 我怀疑这是因为在突发读取结束时没有适当的停止条件被发送到从器件。 driverlib 在发送单字节和多字节序列时的行为与我在阅读文档时所期望的不完全相同、或者可能只是我缺乏理解。 我用下面的代码示例进行解释。

注意:这是一个后续问题/我之前创建的主题的进度:"e2e.ti.com/.../668144"
此处介绍了硬件、我已验证硬件是否正常工作。

以下用于写入序列的函数(在 POST 结束时) MPU6050_setup()工作正常。 如您所注意到的那样、序列(如文档所建议)应该是在一个给定的寄存器中写入一个字节:

  • MultibyteStart (多字节开始)(发送起始条件、器件地址和参数中的字节作为写位(第8位)的寄存器地址)
  • 2. MultibyteFinish (发送作为参数给出的字节和停止条件)
    • 而可以用 MultibyteNext 和 MultibyteStop 替代此功能

但是、您会注意到、我们必须在代码中添加额外的 MultibyteNext。 如其他论坛问题和 driverlib 示例中所述、这对于清除前两个字节的缓冲区是必需的、并且只在新写入序列的开始时才是必需的。

到目前为止、非常好。 问题是、我随后写入以下一组调用、以便进行突发读取。 它们起作用。 但是、它们只能工作一次。 如果我尝试在循环中运行相同的代码或调用两次经过此代码的函数、器件将不再使用数据值进行响应。 即使我复位 MPS432并再次运行相同的代码、也无法读取/写入。 我认为原因是突发读取结束时的开始或停止条件或第二次读取开始时的开始情况有所混乱。 我已经尝试过多种配置、但没有结果。 非常感谢您的帮助。


//.... 其他主代码
TXData[0]= 0x6B;
MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、TXData[0]);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、TXData[0]);
MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);


MAP_I2C_setMode (EUSCI_B0_BASE、EUSCI_BI2C_receive_mode);
MAP_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_receive_INTERRUPT0);
MAP_I2C_masterbstart (EUSCI_BASE);

/*这是调用 ISR 的位置、在
读取所需的14个寄存器之前运行以下 while 循环*

/ while (RXByteCtr < 14);

for (i=0;i< NUM_OF_REC_Bytes;i++){
printf (eUSCI_A0_BASE、"已完成接收:%x\n\r"、RXData[i]);
sample_buffer[cur_sample][i]= RXData[i];
}

//其余主代码 


/* I2C EUSCI_B0中断服务例程*/
void EUSCIB0_IRQHandler (void)
{
uint_fast16_t status;
STATUS = MAP_I2C_getEnabledInterruptStatus (EUSCI_B0_BASE);
MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE、STATUS);

IF (STATUS & EUSCI_B_I2C_Transmit _INTERRUPT0)
{
//printf (eUSCI_A0_BASE、"I2C_Sent!\n\n"r);
}

IF (STATUS & EUSCI_B_I2C_NAK_INTERRUPT){
printf (eUSCI_A0_BASE、"nacked\n\r");
}

if (status & eUSCI_B_I2C_ARBITATIONLOST_INTERRUPT){
printf (eUSCI_A0_BASE、"Arbit lost\n"r);
}

IF (STATUS & EUSCI_B_I2C_Receive_INTERRUPT0)
{
if (RXByteCtr < NUM_OF_REC_Bytes-1){
RXData[RXByteCTR++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_B0_BASE);
}
if (RXByteCtr =(NUM_OF_REC_Bytes-1)){
RXData[RXByteCTR++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_A0_BASE);
MAP_I2C_masterReceiveMultiByteStop (EUSCI_A0_BASE);
}

}



void MPU6050_setup(){
int i = 0;
printf (EUSCI_A0_BASE、"正在初始化 MPU6050寄存器...\n\n");

对于(i = 0;i < 5000;i++);
printf (eUSCI_A0_BASE、"...");
对于(i = 0;i < 5000;i++);
printf (eUSCI_A0_BASE、"...");
对于(i = 0;i < 5000;i++);

printf (eUSCI_A0_BASE、"唤醒...\n"\});

while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop);

/*发送初始启动条件*/
MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、0x6B);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);
//重置或唤醒0x6B REG_PWR_Mgmt_1的值
//map_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);//复位或唤醒值(0x6B REG_PWR_Mgmt_1)

对于(I = 0;I <50000;I++);//复位后的延迟/唤醒寄存器被置位
printf (eUSCI_A0_BASE、"...");
对于(i = 0;i < 5000;i++);
printf (eUSCI_A0_BASE、"...");
对于(i = 0;i < 5000;i++);

while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop);

MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、0x68);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x07);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x07);
MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);

printf (eUSCI_A0_BASE、"复位...\n"\});

while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop);

MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、MPU6050_REG_SAMPLE_RATE);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);

printf (eUSCI_A0_BASE、"采样率设置...\n");

while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop);

MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、MPU6050_REG_CONFIG);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);//禁用 DLPF、(未使用:陀螺仪输出速率= 8kHz)。 将 REG_SAMPLE_RATE 更改为1kHz

printf (eUSCI_A0_BASE、"Config reg set...\n"\});

while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop);

MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、MPU6050_REG_gyro_config);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x08);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x08);
MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);//设置陀螺仪范围:+- 500dps

printf (eUSCI_A0_BASE、"Gyro set...\n"r);

while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop);

MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、MPU6050_REG_ACCEL_CONFIG);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、0x00);
MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);//设置加速范围:+-2g

printf (eUSCI_A0_BASE、"Accel set...\n"r);

while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop);

/*for (i = 0;i < 100;i++);

MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、MPU6050_REG_PWR_Mgmt_1);
MAP_I2C_masterSendMultiByteFinish (EUSCI_B0_BASE、0x00);//禁用睡眠模式

printf (eUSCI_A0_BASE、"禁用睡眠模式...\n");*

对于(I = 0;I <50000;I++);//复位后的延迟/唤醒寄存器被置位
printf (eUSCI_A0_BASE、"...");
对于(i = 0;i < 5000;i++);
printf (eUSCI_A0_BASE、"...");
for (i = 0;i <5000;i++);
} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Farah、

    您是否确认了逻辑分析仪的问题? 如果没有、请尝试查看主器件是否未发送必要的停止条件或重复的启动条件。

    您是在每次传输后发送停止条件还是重复启动条件? 这可能不是问题、但您是否查看了 I2C 从设备(MPU 6050)数据表、以查看是否对重复启动条件有任何限制?

    您是否尝试在 SDK 中使用 I2C driverlib 示例? 所有这些示例均可与2个 MSP432P4 LaunchPad 搭配使用、其中一个用作主器件、另一个用作从器件。 这些应该是一个良好的起点。

    谢谢、
    SAI
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Farah、

    您是否能够验证我在上一帖子中建议的步骤? 如果您需要更多帮助、请告知我们。

    谢谢、
    SAI
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Farah、

    由于几周内我没有收到您的回复、我会将帖子标记为已解决并关闭帖子、希望您不需要进一步的帮助。 如果您需要有关此主题的进一步帮助、请回复该帖子、它将重新打开。

    谢谢、
    SAI