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.

[参考译文] MSP430FR2433:I2C 总线始终处于繁忙状态

Guru**** 2482105 points
Other Parts Discussed in Thread: TCA9535

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1263803/msp430fr2433-i2c-bus-is-always-busy

器件型号:MSP430FR2433
主题中讨论的其他器件:TCA9535

当我运行以下程序时、它永远不会越过检查 I2C 总线是否繁忙的第一个 while 循环-这是为什么?

/* --COPYRIGHT--,BSD
 * Copyright (c) 2017, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
//******************************************************************************
//
//! This example shows how to configure the I2C module as a master for
//! multi byte transmission in interrupt driven mode. The address of the slave
//! module is set in this example.
//!
//!  Demo - EUSCI_B0 I2C Master TX multiple bytes to MSP430 Slave
//!
//!  Description: This demo connects two MSP430's via the I2C bus. The master
//!  transmits to the slave. This is the MASTER CODE. It cntinuously
//!  transmits an array of data and demonstrates how to implement an I2C
//!  master transmitter sending multiple bytes using the USCI_B0 TX interrupt.
//!  ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1MHz
//!
//!                                /|\  /|\
//!          MSP430FR2xx_4xx Board 10k  10k MSP430FR2xx_4xx Board
//!                   slave         |    |         master
//!             -----------------   |    |   -----------------
//!            |          UCB0SDA|<-|----+->|UCB0SDA          |
//!            |                 |  |       |                 |
//!            |                 |  |       |                 |
//!            |          UCB0SCL|<-+------>|UCB0SCL          |
//!            |                 |          |                 |
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - I2C peripheral
//! - GPIO Port peripheral (for I2C pins)
//! - SCL
//! - SDA
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - USCI_B0_VECTOR.
//
//******************************************************************************
#include "driverlib.h"
#include "Board.h"

//*****************************************************************************
//
//Set the address for slave module. This is a 7-bit address sent in the
//following format:
//[A6:A5:A4:A3:A2:A1:A0:RS]
//
//A zero in the "RS" position of the first byte means that the master
//transmits (sends) data to the selected slave, and a one in this position
//means that the master receives data from the slave.
//
//*****************************************************************************
#define SLAVE_ADDRESS 0x77

//*****************************************************************************
//
//Target frequency for SMCLK in kHz
//
//*****************************************************************************
#define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ   1000

//*****************************************************************************
//
//SMCLK/FLLRef Ratio
//
//*****************************************************************************
#define CS_SMCLK_FLLREF_RATIO   30

// Pointer to TX data
uint8_t TXData = 0;
uint8_t TXByteCtr;

void main(void)
{
    WDT_A_hold(WDT_A_BASE);

    //Set DCO FLL reference = REFO
    CS_initClockSignal(
            CS_FLLREF,
            CS_REFOCLK_SELECT,
            CS_CLOCK_DIVIDER_1
        );

    //Set Ratio and Desired MCLK Frequency and initialize DCO
    CS_initFLLSettle(
            CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ,
            CS_SMCLK_FLLREF_RATIO
            );

    //Set ACLK = VLO with frequency divider of 1
    CS_initClockSignal(
            CS_ACLK,
            CS_VLOCLK_SELECT,
            CS_CLOCK_DIVIDER_1
            );

    //Set SMCLK = DCO with frequency divider of 1
    CS_initClockSignal(
            CS_SMCLK,
            CS_DCOCLKDIV_SELECT,
            CS_CLOCK_DIVIDER_1
            );

    //Set MCLK = DCO with frequency divider of 1
    CS_initClockSignal(
            CS_MCLK,
            CS_DCOCLKDIV_SELECT,
            CS_CLOCK_DIVIDER_1
            );

    // Configure Pins for I2C
    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_UCB0SCL,
        GPIO_PIN_UCB0SCL,
        GPIO_FUNCTION_UCB0SCL
    );
    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_UCB0SDA,
        GPIO_PIN_UCB0SDA,
        GPIO_FUNCTION_UCB0SDA
    );

    /*
     * Disable the GPIO power-on default high-impedance mode to activate
     * previously configured port settings
     */
    PMM_unlockLPM5();

    EUSCI_B_I2C_initMasterParam param = {0};
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk = CS_getSMCLK();
    param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
    param.byteCounterThreshold = 0;
    param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
    EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);

    //Specify slave address
    EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,
            SLAVE_ADDRESS
            );

    //Set Master in receive mode
    EUSCI_B_I2C_setMode(EUSCI_B0_BASE,
            EUSCI_B_I2C_TRANSMIT_MODE
            );

    //Enable I2C Module to start operations
    EUSCI_B_I2C_enable(EUSCI_B0_BASE);

    EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
            EUSCI_B_I2C_NAK_INTERRUPT
            );

    // Wait for I2C bus to be idle
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE));

    // Send the start condition
    EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, 0x06);

    // Wait for the start condition to be sent
    while (!(EUSCI_B_I2C_getInterruptStatus(EUSCI_B0_BASE, EUSCI_B_I2C_START_INTERRUPT)));

    // Clear the start condition flag
    EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_START_INTERRUPT);

    // send data byte
    EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, 0x00);


    while(1)
    {

    }
}

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

    Michael、您好!

    IIC 线路在 SDA 和 SCL 线路中需要上拉电阻器、您是否确认您的硬件连接良好?

    如果问题坚持认为、请检查"EUSCI_B_I2C_isBusBusy"返回哪个寄存器值、然后在用户指南中查找相关说明。

    B.R.

    萨尔

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

    大家好、

    我当前连接到了 TCA9535、我可以确认这些线路已被拉至高电平。

    当我运行未经修改的示例时、一切都正常、并且我在 SDA 线路上看到数据。

    使用修改后的示例、我可以确认 UCBBUSY 寄存器为1。

    在单步执行代码时、它似乎在启用 I2C 模块后马上变得繁忙(第178行)。

    这可能是什么原因造成的?

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

    数据表(SCPS201E)表7-2显示了可能的 I2C 地址、0x77不是其中的一个。 引脚 A2-A0是如何配置的?

    我通常期望 NACK 在稍后显示、但也许如果您运行程序两次(因为目标不知道)、您可以看到此结果。

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

    Bruce:

    我知道这一部分都能正常工作、因为我可以打开/关闭 TCA9535上的 LED。 地址实际上为0x77。

    当我没有正确的地址时、我在线路上看到了 NACK (我正在使用逻辑分析仪)。 我正在将此 EVM 用于 TCA9535。

    我还发表了一篇关于在轮询 UCTXIFG 时遇到困难的文章-这些可能是相关的吗?

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

    Michael、您好!

    根据您的说明、我认为 IIC 的初始化代码在未 修改的示例和修改的示例中可能有一些差异。 请仔细检查、可能的原因可能与此相关。

    顺便说一下、启用 IIC 后 SDA 和 SCL 线路的状态是什么?

    另外、主器件接收模式的过程参考以下、大家也可以掌握 SDA 和 SCL 的波形、然后发现 异常波形:

    B.R.

    萨尔

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

    SAL

    代码有时会正常工作、但当我进入调试模式并单步执行代码时、问题就出现了。

    我必须对 MSP430进行完全复位(断电、等待几分钟)、以使完全一样的代码再次开始工作。

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

    Michael、您好!

    如果需要从430复位、我假定430器件使 IIC 线路处于繁忙状态。

    您是否可以与未修改的代码(IIC 初始化部分)共享您的代码的差异?

    此外、您是否可以共享 IIC 波形、它可能有助于找到更多信息:

    SCL+SDA 线路: 无错误的自由运行;

    SCL+SDA 线路: 调试步骤、电源复位->初始 IIC ->忙

    B.R.

    萨尔

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

    我不使用驱动程序库、但可以观察到以下几点:

    setMode 调用是冗余的、因为启动调用会设置该调用。

    因为中断标志在复位中被清除、所以清除中断标志也是冗余的。 嗯、图表24-32和表24-19在复位后 TXIFG0状态上的冲突。

    您不会完成 I2C 事务、因此绝不会生成 STOP。 UCBBUSY 在一个起始条件时被置位、在一个停止时被清零。