我在 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();
}