器件型号: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++); }