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.

[参考译文] TMS320F280039C:I2C 主器件(F280039C)能够&'t 与 INA227通信–无 ACK

Guru**** 2454880 points
Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1514681/tms320f280039c-i2c-master-f280039c-can-t-communicate-with-ina227-no-ack

器件型号:TMS320F280039C
主题:SysConfig 中讨论的其他器件

工具/软件:

[I2C 主器件(F280039C)无法与 INA227通信–无 ACK]

大家好、我使用 TI F280039C LaunchPad 通过 I2C 与位于定制 PCB 上的 INA227电源监控器进行通信。 INA227已连接到 PIC 微控制器、但在这种情况下 PIC 没有主动使用 I2C、这只是为 INA227供电。  

Tools️ 系统设置概述:

配置为 I2C 主器件的 F280039C LaunchPad INA227位于另一个 PCB 上、通过 PIC (空闲)供电

已在两个板之间确认共享 GND

接线:从 LaunchPad 的 I2C 线路通过 INA227板上的测试点连接上拉电阻器:10kΩ 至3.3V INA227/SCL 板上已存在1kΩ 上拉至3.3V PIC 侧 SDA:GPIO34 SCL:GPIO51

 Chart with upwards trend 示波器观察结果:

连接两个10kΩ 的+ 1kΩ 上拉电阻:SDA:两个短低电平脉冲、然后为高电平、每条命令重复

SCL:每个事务具有一致的10个脉冲、重复 INA227在移除1kΩ 上拉电阻后不会发出确认(仅保持10k Ω):

SDA:波形变为类似锯齿模式 SCL:每次突发仍有10个脉冲、在移除3.3V 上拉电压时重复未观察到 ACK (即、断开 VCC 与上拉电阻器的连接):

SDA 和 SCL 线路都变平(无切换活动)  

White check mark 工作/确认事项:INA227已通电(PIC 板激活、LED 确认代码正在运行) INA227在与 PIC 上拉电压通信时工作正常、GND 是共享的 F280039C I2C 生成启动/停止、时钟信号。 在 LaunchPad 和 PIC 之间共享 INA227 I2C 线路时、是否应该对其进行缓冲或保护?

提前感谢您在缩小根本原因范围方面提供的任何帮助!  

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

    您好、Antony、

    您能否提供 PIC 和 F280039C 电路板之间 I2C 通信线路的一些屏幕截图?

    此外、F280039C LaunchPad 是如何实现的? 您是否通过 BoosterPack 接头供电并仅隔离调试器信号?

    您是否使用我们的示例软件进行 I2C 通信、或者您是否有定制代码? 请注意、F280039C 可寻址16位、因此最好参考我们的示例代码来考虑这一点

    此致、

    彼得

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

    您好、Peter:

    感谢您联系我们!

    • 电源:F280039C LaunchPad 当前通过 USB 端口供电。

    • 与 INA227通信(通过 I2C):INA227传感器由外部供电(3.3V)  

    • 我未使用 BoosterPack 接头为外部器件供电-仅连接 I2C 的信号线。

    • 我并不只是隔离调试器信号;完整的 LaunchPad USB 电源和调试接口处于活动状态。

    • 我已经使用逻辑分析仪和示波器观察到了 I2C 波形。

    • SCL:显示常规时钟脉冲(开始、8–9个时钟、停止)。

    • SDA:传输地址和数据字节-但是、从器件不会发出 ACK 信号、无论 INA227是否已连接、波形看起来都相同。

    • 我将使用自定义代码(基于 TI 的 driverlib 函数)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Antony、

    您能否验证所使用的目标地址是什么? 此外、如果您可以提供正在使用的 I2C 初始化和代码、这会有所帮助

    此致、

    彼得

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

    您好、Peter:  

    这是 i2c 初始化的代码。 它是使用 SysConfig 生成的。

    void I2C1_init (){
      I2C_disableModule (I2C1_BASE);
      I2C_initController (I2C1_BASE、DEVICE_SYSCLK_FREQ、I2C1_bitrate、I2C_DUTYCYCLE_33);
      I2C_setConfig (I2C1_BASE、I2C_CONTROLLER_SEND_MODE);
      I2C_disableLoopback (I2C1_base);
      I2C_setOwnAddress (I2C1_BASE、I2C1_OWN_ADDRESS);
      I2C_setTargetAddress (I2C1_BASE、I2C1_TARGET_ADDRESS);
      I2C_setBitCount (I2C1_BASE、I2C_BITCOUNT_8);
      I2C_setDataCount (I2C1_BASE、0);
      I2C_setAddressMode (I2C1_BASE、I2C_ADDR_MODE_7BITS);
      I2C_disableFIFO (I2C1_BASE);
      I2C_clearInterruptStatus (I2C1_BASE、I2C_INT_REG_ACCESS_RDY | I2C_INT_STOP_Condition);
      I2C_enableInterrupt (I2C1_BASE、I2C_INT_REG_ACCESS_RDY | I2C_INT_STOP_Condition);
      I2C_setEmulationMode (I2C1_BASE、I2C_EMULATION_STOP_SCL_LOW);
      I2C_enableModule (I2C1_BASE);
    }    
    #define I2C1_BASE I2C2_BASE
    #define I2C1_bitrate 400000
    #define I2C1_TARGET_ADDRESS 64
    #define I2C1_OWN_ADDRESS 0
    #define I2C1_MODULE_CLOCK_FREQUENCY 10000000
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Antony、

    这个初始化代码看起来不错、我相信这是这个 INA227器件的正确目标地址。 您能否分享用于读取和写入 I2C 模块的代码?

    此致、

    彼得

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

    您好、Peter:

    感谢您的答复。  以下是我当前用于通过 I2C 与 INA227通信的代码片段:

    uint8_t id;
        I2C_readBytes (0x40、0x06、&id、1);
        I2C1_writeReg (I2C1_TARGET_ADDRESS、0x01、0xAB);
        uint8_t val = I2C1_readReg (I2C1_TARGET_ADDRESS、0x01);
     
    bool I2C_readBytes (uint16_t devAddruint16_t reg、uint8_t *data、uint16_t len)
      uint32_t 超时;

      //首先发送寄存器指针(写入阶段)
      TIMEOUT = I2C_TIMEOUT;
      while (I2C_isBusBusy (I2CB_BASE)&&-超时);
      if (TIMEOUT = 0)返回 FALSE

      I2C_setTargetAddress (I2CB_BASE、devAddr);
      I2C_setDataCount (I2CB_BASE、1);//发送寄存器指针
      I2C_setConfig (I2CB_BASE、I2C_CONTROLLER_SEND_MODE);
      I2C_sendStartCondition (I2CB_BASE);
      I2C_putData (I2CB_base、reg);

      TIMEOUT = I2C_TIMEOUT;
      while (!I2C_getStopConditionStatus (I2CB_BASE)&&-- TIMEOUT);
      if (TIMEOUT = 0)返回 FALSE

      //I2C_clearStopConditionStatus (I2CB_BASE);
      I2C_clearInterruptStatus (I2CB_BASE、I2C_INT_STOP_Condition);

      //现在读取相位
      I2C_setTargetAddress (I2CB_BASE、devAddr);
      I2C_setDataCount (I2CB_base、len);
      I2C_setConfig (I2CB_BASE、I2C_CONTROLLER_RECEIVE_MODE);
      I2C_sendStartCondition (I2CB_BASE);
      uint16_t i;
      for (i = 0;i < len;i++)
      {
        TIMEOUT = I2C_TIMEOUT;
        //while (!I2C_isRxReady (I2CB_BASE)&&-- TIMEOUT);
        if (TIMEOUT = 0)返回 FALSE

        DATA[i]= I2C_getData (I2CB_BASE);
      }

      TIMEOUT = I2C_TIMEOUT;
      while (!I2C_getStopConditionStatus (I2CB_BASE)&&-- TIMEOUT);
      if (TIMEOUT = 0)返回 FALSE

      //I2C_clearStopConditionStatus (I2CB_BASE);
      I2C_clearInterruptStatus (I2CB_BASE、I2C_INT_STOP_Condition);

      返回 true
    }
    void I2C1_writeReg (uint16_t slaveAddruint8_t reg、uint8_t 数据)
      I2C_setTargetAddress (I2CB_BASE、I2C1_TARGET_ADDRESS);
      I2C_setConfig (I2CB_BASE、I2C_CONTROLLER_SEND_MODE);
      I2C_setDataCount (I2CB_BASE、2);

      I2C_putData (I2CB_base、reg);
      I2C_putData (I2CB_BASE、DATA);

      I2C_sendStartCondition (I2CB_BASE);
      I2C_sendStopCondition (I2CB_BASE);

      while (!I2C_getStopConditionStatus (I2CB_BASE)); //等待停止
      //I2C_clearStopConditionStatus (I2CB_BASE);
      I2C_clearInterruptStatus (I2CB_BASE、I2C_INT_STOP_Condition);
    }
    uint8_t I2C1_readReg (uint16_t slaveAddruint8_t reg)
      uint8_t ReadData;

      //首先写入寄存器地址
      I2C_setTargetAddress (I2CB_BASE、I2C1_TARGET_ADDRESS);
      I2C_setConfig (I2CB_BASE、I2C_CONTROLLER_SEND_MODE);
      I2C_setDataCount (I2CB_BASE、1);

      I2C_putData (I2CB_base、reg);
      I2C_sendStartCondition (I2CB_BASE);
      while (!I2C_getStopConditionStatus (I2CB_base));
      //I2C_clearStopConditionStatus (I2CB_BASE);
      I2C_clearInterruptStatus (I2CB_BASE、I2C_INT_STOP_Condition);

      //现在读取数据
      I2C_setConfig (I2CB_BASE、I2C_CONTROLLER_RECEIVE_MODE);
      I2C_setDataCount (I2CB_BASE、1);

      I2C_sendStartCondition (I2CB_BASE);
      I2C_sendStopCondition (I2CB_BASE);

      while (!I2C_getRxFIFOStatus (I2CB_BASE)); //等待数据
      ReadData = I2C_getData (I2CB_BASE);

      while (!I2C_getStopConditionStatus (I2CB_base));
      //I2C_clearStopConditionStatus (I2CB_BASE);
      I2C_clearInterruptStatus (I2CB_BASE、I2C_INT_STOP_Condition);

      返回 ReadData;
    }   

    如果您发现可能遗漏了关于 INA227和 F28003x 系列的寻址内容或需要考虑的任何细节、请告诉我。

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

    您好、Antony、

    您是否在 I2C 通信中经常看到超时被触发? 您正在为超时定义使用什么值? 您能尝试暂时放弃超时并允许 I2C 线路适当地进行时钟延展、以防 INA227需要太长的时间来响应吗?  

    此致、

    彼得