我在 PCB 上的 msp430g2553上使用 I2C 时遇到问题。 当我通过 Launchpad 的 ezFET 侧连接代码、将代码刷写到外部电路板上时、没有问题(即使在 CCS 上加载而不是进入调试模式时也是如此)。 然而,在闪存我的代码并从 launchpad 上断开连接后,我的程序会卡在 InitMPU ()函数中。 initMPU()函数仅使用 i2c.c 中的 TransmitByte()函数传输数据(见下文)。
这是我的 i2c.c 文件,其中 initI2C()和 TransmitByte()是从 main 调用的。
/* * i2c.c * * Created on: 4 Apr 2024 * Author: Chris */ #include "i2c.h" // Function to config I2C regs - 400 kHz operating freq void initI2C(void) { P1SEL |= SCL + SDA; // Config P1.6 SCL and 1.7 SDA P1SEL2 |= SCL + SDA; UCB0CTL1 |= UCSWRST; // Enable SW reset - known state UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Make MCU master & put in synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // SMCLK approx 1 MHz UCB0BR0 = 9; // /3 to get fast rate approx 400 kHz UCB0BR1 = 1; UCB0I2CSA = MPU_SLAVE_ADDRESS; // Set slave address of mpu6050 UCB0CTL1 &= ~UCSWRST; // Exit SW reset now that registers are configured } int IsI2CBusy(){ if(UCB0STAT & UCBBUSY){ return 1; // BUS BUSY } else{ return 0; // BUS NOT BUSY } } // Function to read a single byte of given I2C Slave Address char ReceiveByte(char register_address){ volatile char byte; while (UCB0CTL1 & UCTXSTP); // Wait for our prev stop condition to be sent (just in case..) UCB0CTL1 |= UCTR + UCTXSTT; // Lets start in transmit MODE while((IFG2 & UCB0TXIFG) == 0); // Wait for MPU66050 Device Address to be sent UCB0TXBUF = register_address; // After we get ACK, lets send register address we want to read while((IFG2 & UCB0TXIFG) == 0); // Wait for ACK... UCB0CTL1 &= ~UCTR ; // Now we can receive data from the register address UCB0CTL1 |= UCTXSTT + UCTXNACK; // Send START and we respond with NACK for single byte read while (UCB0CTL1 & UCTXSTT); // Wait for start to complete... UCB0CTL1 |= UCTXSTP; // Send stop while(!(IFG2 & UCB0RXIFG)); // Wait until we receive byte = UCB0RXBUF; // Read the byte return byte; } void TransmitByte(char register_address, char data){ while (UCB0CTL1 & UCTXSTP); // Wait for our prev stop condition to be sent (just in case..) UCB0CTL1 |= UCTR + UCTXSTT; // while((IFG2 & UCB0TXIFG) == 0); // Wait for MPU66050 Device Address to be sent UCB0TXBUF = register_address; // After we get ACK, lets send register address we want to read while((IFG2 & UCB0TXIFG) == 0); // Wait until our reg address is sent UCB0TXBUF = data; // Now we can send our data to that address while((IFG2 & UCB0TXIFG) == 0); // Wait... UCB0CTL1 |= UCTXSTP; // STOP IFG2 &= ~UCB0TXIFG; // Clear Flag }
下面是我的主要内容(缩短版)。 同样,InitMPU()只需从 i2c.c 调用 TransmitByte()。 当我不调用 InitMPU()时,当电路板由外部供电且未连接到 launchpad 时,代码将按预期工作。 当我调用 InitMPU()时,程序必须卡在 TransmitByte()中的 while 循环中。 当未连接到 Launchpad 的 ezFET 侧时、我不知道为什么会出现这种情况、因为它在 正常连接的情况下工作。
int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer __enable_interrupt(); IFG2 = 0x00; // Reset IFG2 initI2C(); // Init I2C for reading mpu6050 while ( IsI2CBusy() ); initMPU(); }