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.

[参考译文] MSP430FR2675:I2C 主器件在没有 pData 的情况下写入和读取

Guru**** 2487425 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1221804/msp430fr2675-i2c-master-write-and-read-without-pdata

器件型号:MSP430FR2675

您好!

我正在为 MSP430作为 I2C 主设备与之通信的各种传感器编写几个驱动程序。 下面是我一直用于通过 I2C 写入/读取数据的代码。 它一直运作良好。

I2CMaster_error_t I2CMaster_writeReg8(uint8_t ui8Addr, uint8_t ui8Reg, uint8_t *pData, uint8_t ui8Cnt)
{
    I2CMaster_error_t error;
    uint8_t count = UINT8_MAX;

    if (g_driver.state != I2CMaster_isIdle)
    {
        return eI2CMaster_unavailableError;
    }
    PrepForTransaction(ui8Addr, pData, ui8Cnt + 1);
    I2CMASTER__WRITEMODE;
    I2CMASTER__START;
    while (!(I2CMASTER__IFG & UCTXIFG) && 0 != count--)
    {
        if (g_driver.flags.ui8ErrorFlags != 0)
        {
            Cleanup();
            return CheckForErrors();
        }
    }
    assert(UINT8_MAX != count);
    I2CMASTER__TXBUF = ui8Reg;
    I2CMASTER__IE |= UCTXIE;
    error = FinishTransaction();
    return error;
}

I2CMaster_error_t I2CMaster_readReg8(uint8_t ui8Addr, uint8_t ui8Reg, uint8_t *pData, uint8_t ui8Cnt)
{
    I2CMaster_error_t error;
    uint8_t count = UINT8_MAX;

    if (g_driver.state != I2CMaster_isIdle)
    {
        return eI2CMaster_unavailableError;
    }
    PrepForTransaction(ui8Addr, pData, ui8Cnt);

    // Start communication by sending a start condition
    // and the slave bus address, and ensuring the slave
    // does not nack.
    I2CMASTER__WRITEMODE;
    I2CMASTER__START;
    while (!(I2CMASTER__IFG & UCTXIFG) && 0 != count--)
    {
        if (g_driver.flags.ui8ErrorFlags != 0)
        {
            Cleanup();
            return CheckForErrors();
        }
    }
    assert(UINT8_MAX != count);

    // Transmit the slave sub-register to read from
    I2CMASTER__TXBUF = ui8Reg;
    while (!(I2CMASTER__IFG & UCTXIFG) && 0 != count--)
    {
        // Handle the i8Cnt==1 case, where the stop bit is sent prematurely
        if (g_driver.flags.bStop == true)
        {
            break;
        }
        if (g_driver.flags.ui8ErrorFlags != 0)
        {
            Cleanup();
            return CheckForErrors();
        }
    }
    assert(UINT8_MAX != count);

    // Read out the data from the slave
    g_driver.flags.ui8StatusFlags = 0;
    I2CMASTER__READMODE;
    I2CMASTER__START;
    I2CMASTER__IE |= UCRXIE;
    error = FinishTransaction();

    return error;
}

I2CMaster_error_t CheckForErrors(void)
{
    if (g_driver.flags.bClockLowTimeout == true)
    {
        return eI2CMaster_busTimeoutError;
    }
    else if (g_driver.flags.bSlaveNack == true)
    {
        return eI2CMaster_slaveNackError;
    }
    else
    {
        return eI2CMaster_noError;
    }
}

void PrepForTransaction(uint8_t ui8Addr, uint8_t *pData, uint8_t ui8Cnt)
{
    I2CMASTER__SET_RST;
    g_driver.state = I2CMaster_isCommunicating;
    g_driver.flags.ui8AllFlags = 0;
    g_driver.pData = pData;
    I2CMASTER__I2CSA = ui8Addr;
    I2CMASTER__TBCNT = ui8Cnt;
    I2CMASTER__CLEAR_RST;
    I2CMASTER__IE = UCNACKIE | UCCLTOIE | UCSTPIFG;
}

void Cleanup(void)
{
    I2CMASTER__IE = 0;
    g_driver.state = I2CMaster_isIdle;
}

I2CMaster_error_t FinishTransaction(void)
{
    uint8_t count = UINT8_MAX;
    while (g_driver.flags.bStop == false && 0 != count--)
    {
        if (g_driver.flags.ui8ErrorFlags != 0)
        {
            Cleanup();
            return CheckForErrors();
        }
    }
    assert(UINT8_MAX != count);
    Cleanup();
    return CheckForErrors();
}

但是、我的传感器的功能与此代码的功能略有不同。 我附上了它的工作方式的屏幕截图。 本质上、我需要能够写入 I2C 寄存器、而不会有任何关联的 pData。 然后、我需要向 I2C 地址发送读取操作、而不设置寄存器。 例如、如果传感器的地址为0x50并且我想从寄存器0x7F 读取数据、那么我首先向寄存器0x7F 发送一个写命令、看起来像0x50 0x7F、然后向0x50发送一个读取命令、在这里我会接收所需的数据。

是否有办法编辑我的代码以运行这些命令?

谢谢。

Eric

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

    您是否尝试过使用 readReg8通过 ui8Reg=command 发出请求? 即使该图在执行命令后显示停止、但使用重复启动也可以。

    如果设备确实坚持以"停止"结尾的"命令"请求,您可能需要一个单独的 i2c_ReadData(),它只会处理 readReg8的下半部分;然后使用 ui8reg=command 和 ui8cnt=0调用 writeReg8 ,然后是 i2c_ReadData()。

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

    Bruce、您好!

    感谢您的建议。 我现在已尝试执行 readReg8、我将看到它是否起作用。 我将能够在未来一两周内对此进行测试。 如果这不起作用、我会看看您的其他建议是否起作用。

    谢谢。

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

    您好、Eric、

    关于该主题的任何更新、您是否需要其他支持?

    谢谢!

    此致

    Johnson