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.

[参考译文] MSP430G2553:未连接到 PC 时出现 I2C 问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1352175/msp430g2553-i2c-issues-when-not-connected-to-pc

器件型号:MSP430G2553

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

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

    在未连接到 Launchpad 时、您的系统如何供电?

    我看到的 MPU6050电路板(在 Amazon 和类似的电路板中)从5V 运行、具有低至3V 的板载稳压器。 Launchpad 上提供5V 电压(通过 USB 提供)、但如果无法提供、则必须自行提供。

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

    感谢您的答复。 该 PCB 有一个可降至3.3V 的板载稳压器。该问题与板供电无关、因为当我没有使用任何 I2C 功能时、该板可以执行代码、没有问题。

    使用外部电源为外部电路板供电时、我还将代码闪存到外部电路板上、同时仅连接到 LaunchPad 的 SBWCLK、SBWTDIO 和 GND。 通过这种设置、该板甚至可以使用 I2C 功能。 但当从 LaunchPad 上断开并将~RST 引脚拉高时,它似乎卡在 TransmitByte()中。 奇怪的是,这种精确的设置适用于运行其他类型的功能(定时器,GPIO ),但不适用于我的 I2C 功能。  

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

    抱歉、我第一次看到你的回答时、会误解你的回答。  

    我用3.3V 电压为 MPU6050供电。我还有一个来自 Amazon 的 mpu6050模块、我用3.3V 电压为该模块供电、该模块工作正常。 此外、在连接到 Launchpad 且断开5V 跳线的情况下、组装到 PCB 上的跳线可以在 Vcc=3.3V 的条件下工作。 我认为问题与为电路板供电无关、但可能是错误的。  

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

    MPU6050可在3.3V 下正常运行。 我提到的板(所有?) 看起来是从5V 开始运行、或许可以容纳5V Arduino 板。

    值得注意的是、它们也提供 I2C 上拉电阻。 您如何提供这些功能?

    作为一个编码问题、对于 TransmitByte 和 ReceiveByte 检查 UCB0STAT:UCNACKIFG 都是一个好主意、尤其是在第二个 TXIFG 循环期间。 这将有助于区分死 IMU 器件和(例如)挂起总线。

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

    感谢您发送编修。

    是的,我认为它是容纳 Arduino。 我仔细查看了具有的模块的数据表、3.3 Vcc 是可以接受的、因此我认为这不是这个问题的根源。 是的、我在 SCL 和 SDA 线路上提供了上拉电阻器。

    这是一个很好的建议、当 Im 回到办公桌前时、我 会包括这些检查、并看看结果如何。

    Im 完全无法理解为什么当 Im 连接到 LaunchPad SBWCLK、SBWTDIO 和 GND 引脚时、Im 能够从 MPU 进行发送和接收。 试图浏览数据表、找到原因的提示、但找不到任何线索。 我的设置在不连接到 launchpad 的情况下完美地运行其他东西、但它似乎与 I2C…不一样 很困惑

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

    根据您的描述、我很确定它必须(以某种方式)处理电源。

    如果您有一个示波器、示波器非常方便。"

    [编辑:I (模糊)回想一下、MPU6050需要大约10s 的时间来启动。 如果您同时为这些器件供电、则在与 IMU 通信时可能未准备就绪。 考虑插入类似以下内容:

    __delay_cycles (35000UL);// 35mS 多或少、用于 IMU 启动

    看看它是否起了作用。]

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

    谢谢 Bruce、您是正确的。 由于您的建议增加了延迟、问题已得到解决。

    感谢您的帮助!