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.

[参考译文] CCS/MSP430FR2476:I2C 通信不读取实际数据

Guru**** 2535150 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/943288/ccs-msp430fr2476-i2c-communication-not-reading-in-real-data

器件型号:MSP430FR2476

工具/软件:Code Composer Studio

我正在尝试对 MSP430和电池电量监测计(LTC2943)之间的 I2C 通信进行编程。 我的读取函数仅返回零。 这是读取函数:
void i2cReceive (uint8_t regAddress、uint8_t buffer、uint8_t buffersize){
uint8_t i;

EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE、LTC2943_SLAVE_ADDRESS);
EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit 模式);
EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);

while (EUSCI_B_I2C_Sending = EUSCI_B_I2C_masterIsStopSent (EUSCI_B0_BASE));
EUSCI_B_I2C_masterSendStart (EUSCI_B0_BASE);

//切换到接收器模式
EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_mode);

for (i=0;<bufferSize; i++){
缓冲区= EUSCI_B_I2C_masterReceiveMultiByteNext (EUSCI_B0_BASE);
Buffer++;
}

EUSCI_B_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
}

这是从特定寄存器读取的函数之一:

uint8_t getControl(){
uint8_t CONTROL = 0;
i2cReceive (control_address、control、sizeof (control));

返回控制;
} 

有时它会在 i2cReceive()中的 while 循环中卡住:
while (EUSCI_B_I2C_Sending = EUSCI_B_I2C_masterIsStopSent (EUSCI_B0_BASE)); 
当我注释掉该行时、它将运行、但每个寄存器将返回零。  我还尝试了使用不同的函数、例如 EUSCI_B_I2C_slaveGetData() 、每次返回255个函数。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    >    EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
    >    EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
    我认为您需要将 regAddress 发送到这里的某个位置、可能类似于
    >    EUSCI_B_I2C_masterSendSingleByte(EUSCI_B0_BASE, regAddress);
    >    EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
    >    EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);

     

     

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

    没错、我忘记了发送寄存器地址。 我更新了我的代码以包含此内容、但我将获得相同的结果。  

    以下是我的更新代码:

    void i2cReceive (uint8_t regAddress、uint8_t * buffer、uint8_t buffersize){
    uint8_t i;
    
    EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE、LTC2943_SLAVE_ADDRESS);
    EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit 模式);
    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);
    
    
    EUSCI_B_I2C_masterSendStart (EUSCI_B0_BASE);
    EUSCI_B_I2C_slavePutData (EUSCI_B0_BASE、regAddress);
    
    //切换到接收器模式
    EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_mode);
    
    EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
    
    for (i=0;<bufferSize; i++){
    *缓冲区= EUSCI_B_I2C_masterReceiveMultiByteNext (EUSCI_B0_BASE);
    Buffer++;
    }
    
    EUSCI_B_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    while (EUSCI_B_I2C_Sending _stop = EUSCI_B_I2C_masterIsStopSent (EUSCI_B0_BASE));
    }
    
    uint8_t getControl (){
    uint8_t CONTROL = 0;
    i2cReceive (control_address、&control、sizeof (control));
    
    返回控制;
    } 

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

     slavePutData doesn't do what you want (it doesn't wait for TXIFG). Did masterSendSingleByte not work?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果我将其更改为 masterSendSingleByte、它会在这个 while 环路中停留在 SendmasterSingleByte 中 

    //轮询发送中断标志。 while (!(HWREG16 (baseAddress + OFS_UCBxIFG)& UCTXIFG));

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

    只需清除:SendSingleByte 执行启动、传输和停止操作、因此、如果您使用它、则不应单独调用 SendStart。

     LTC2943_SLAVE_ADDRESS 的值是什么? 一方面、我认为如果不正确、你不会走这么远、但另一方面、如果你遇到 NACK、我希望代码行会失败。 根据数据表(2943FA) 图5、我希望它为0x64。

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

    我也为该地址获取了0x64。 我刚才在 sendSingleByte 之前注释了 sendStart、它仍然卡在同一 while 循环中。

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

    查看源 、EUSCI_B_I2C_masterReceiveMultiByteNext 不会等待 RXIFG 被置位。 (对我来说、这也不是显而易见的。) 等待 RXIFG 的变体是 EUSCI_B_I2C_masterReceiveSingle。

    我没有您的器件、但我能够使用以下版本从 LIS3DH 中(反复)读取 WHO _AM_I (0x0F)寄存器:

    void i2cReceive (uint8_t regAddress、uint8_t * buffer、uint8_t buffersize){
    uint8_t i;
    
    EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE、LTC2943_SLAVE_ADDRESS);
    EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit 模式);
    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);
    #IF BMC
    EUSCI_B_I2C_masterSendSingleByte (EUSCI_B0_BASE、regAddress);
    EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_mode);
    EUSCI_B_I2C_masterSendStart (EUSCI_B0_BASE);
    #else
    EUSCI_B_I2C_masterSendStart (EUSCI_B0_BASE);
    EUSCI_B_I2C_slavePutData (EUSCI_B0_BASE、regAddress);
    //切换到接收器模式
    EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_mode);
    EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
    #endif // BMC
    
    for (i=0;<bufferSize; i++){ #if BMC
    
    *缓冲区= EUSCI_B_I2C_masterReceiveSingle (EUSCI_B0_BASE);
    #else
    *缓冲区= EUSCI_B_I2C_masterReceiveMultiByteNext (EUSCI_B0_BASE);
    #endif
    Buffer++;
    }
    EUSCI_B_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    while (EUSCI_B_I2C_Sending _stop = EUSCI_B_I2C_masterIsStopSent (EUSCI_B0_BASE));
    }
    

    [编辑:修复了重复代码(仍然有效)。 发布它需要几次尝试。]