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.

[参考译文] TM4C123GH6PM:SMBus 从器件不发送数据

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1275878/tm4c123gh6pm-smbus-slave-not-sending-data

器件型号:TM4C123GH6PM

您好!

我正在使用为 SMBus 通信提供的库(SMBus.h 和 SMBus.c)实现 SMBus 从设备。  我使用基于中断的方法、并且使用 SW-TM4C-UTILS-UG 文档中提供的基本代码作为代码模板。 当通信开始时、从器件只能在第一个字上正确发送数据。 在后续的读取字操作中、从器件不发送预期数据、并且在每个字节中仅发送0xFF。 我一直在努力弄清楚它,但到目前为止,没有运气。 如果能对此提供一些帮助、我将不胜感激。 检查以下从 ISR 代码以及一段 SMBus 捕获的屏幕截图。  

结构 battData{
uint8_t 电压[2];
uint8_t Current[2];
uint8_t 关联[2];
uint8_t remCap [2];
uint8_t fullCap[2];
uint8_t time2empty[2];
uint8_t STATUS[2];
uint8_t 温度[2];
};

struct battData battery ={{0x01、0x02}、{0x03、0x04}、{0x05、0x06}、{0x07、0x08}、{0x09、0x0A}、{0x0B、0x0C}、{0x0D、0x0E}、{0x0F、0x10};

void I2C0SlaveIntHandler (void){
  tSMBusStatus EStatus;
  EStatus = SMBusSlaveIntProcess (&g_sSlave);

  //查看是否接收到第一个字节/命令。
  if (EStatus == SMBUS_SLAVE_FIRST_BYTE){

    开关(SMBusSlaveCommandGet (&G)){

      案例 SMBUS_VOLTAGE:
      {
      SMBusSlaveTxBufferSet (&G、Slave、battery.voltage2);
      中断;
      }

      案例 SMBUS_CURRENT:
      {
      SMBusSlaveTxBufferSet (&G、Slave、battery.current2);
      中断;
      }

      案例 SMBus_Relative _State_of_Charge:
      {
      SMBusSlaveTxBufferSet (&g_sSlavebattery.relocc2);
      中断;
      }

      案例 SMBus_Remaining_Capacity:
      {
      SMBusSlaveTxBufferSet (&G、Slave、battery.remCap2);
      中断;
      }

      案例 SMBUS_FULL_CHARGE_CAPACITY:
      {
      SMBusSlaveTxBufferSet (&G、Slave、battery.fullCap2);
      中断;
      }

      案例 SMBUS_RUN_TIME_TO_EMPTY:
      {
      SMBusSlaveTxBufferSet (&G、Slave、battery.time2Empty2);
      中断;
      }

      案例 SMBUS_BATTERY_STATUS:
      {
      SMBusSlaveTxBufferSet (&G、Slave、battery.status、2);
      中断;
      }

      外壳 SMBUS_TEMPERATURE:
      {
      SMBusSlaveTxBufferSet (&g_sSlavebattery.temperature2);
      中断;
      }
    }
  }

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

    您好!

     如果您在  I2C0SlaveIntHandler 中放入一个断点、那么在您即将发送"FF"数据时 CPU 是否会被暂停?

      EStatus 返回什么内容?

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

    尊敬的 Charles:

    每次接收到数据时都会执行 ISR。 EStatus 按预期返回 SMBus_slave_first_BYTE。 此外、我在 switch 语句中的每个 case 的内部切换了 GPIO、以确保检测到命令并将其切换。 下面的屏幕截图显示了我执行的另一个调试。 如果 EStatus 返回 SMBUS_SLAVE_NOT_READY、并且您可以看到始终为低电平、则通道2 (红色标记)应该变为高电平。 每次 sStatus 返回 SMBus_TRANSMIT_COMPLETE 时、通道3都会切换。 因此、一般来说、一切看起来都很好、但数据不会相应地发送。  

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

    Alberto、

     我还在努力让自己明白。 通过比较 TM4C129和 TM4C123数据表可以看出、TM4C123 MCU 似乎不支持 SMBus、至少作为主器件是如此。 TM4C129数据表中有一节关于 SMBus 的内容以及有关如何支持 SMBus 的详细寄存器说明、但在 TM4C123 MCU 中找不到此信息。 至少从 SMBus 主视角来看、不支持 SMBus。 至于从属方、我不知道发送0xFF 的问题是什么、因为我自己对 smbus.c 文件不是很熟悉。  

     您是否可以 从第3994行开始单步执行 SMBusSlaveIntProcess、并将前两个字节成功传输时的时间与下两个字节之间的时间进行比较、将这两个字节作为0xFF 传输。 我想知道是否某些条件未被满足并导致0xFF 被传输。  

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

    Charles

    问题在于、状态机卡在 SMBus_State_WRITE_DONE 状态。 在 SMBus.c 的第4294行中、您可以看到没有对下一状态的分配、因此、从器件始终发送0xFF。 这似乎是一个错误。 你有什么建议?  

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

    您好!

     我必须说、我在 SMBus 方面一般没有太多经验。 这是我第一次读取 smbus.c 文件。 该文件已在 TivaWare SDK 中存在很长时间、并可从上一代 Stellaris MCU 中继承。 虽然客户很少使用(在过去几年中、您可能是第一个提出 smbus.c 相关问题的人)、但我倾向于认为它应该经过全面测试。 也许它可能有一些东西来帮助正确使用 SMBus 堆栈、但我真的不知道您当前的情况有什么问题。  

     话虽如此,我认为 SMBusSlaveTxBufferSet()似乎只将数据放在 TX 缓冲区中。 不会启动 I2C 总线事务。 我想知道如果在调用  SMBusSlaveTxBufferSet 后立即中断、事务是如何开始的。 您能否 在 SMBusSlaveTxBufferSet 之后进行调用 SMBusSlaveIntProcess 的实验。 我想知道这有什么作用。  

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

    尊敬的 Charles:

    我能够使它工作。 有一个名为  SMBusSlaveTransferInit 的 API 需要在每次完成 SMBus 传输时调用。  遗憾的是、在任何地方都没有提到这一点。 从文档的角度来看、还有很大的改进空间。 ISR 代码如下所示:

    void I2C0SlaveIntHandler(void){
        tSMBusStatus eStatus;
        eStatus = SMBusSlaveIntProcess(&g_sSlave);
    
        // See if the first byte/command was received.
        if(eStatus == SMBUS_SLAVE_FIRST_BYTE){
    
            switch(SMBusSlaveCommandGet(&g_sSlave)){
    
                case SMBUS_VOLTAGE:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.voltage, 2);
                break;
                }
    
                case SMBUS_CURRENT:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.current, 2);
                break;
                }
    
                case SMBUS_RELATIVE_STATE_OF_CHARGE:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.relsoc, 2);
                break;
                }
    
                case SMBUS_REMAINING_CAPACITY:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.remCap, 2);
                break;
                }
    
                case SMBUS_FULL_CHARGE_CAPACITY:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.fullCap, 2);
                break;
                }
    
                case SMBUS_RUN_TIME_TO_EMPTY:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.time2empty, 2);
                break;
                }
    
                case SMBUS_BATTERY_STATUS:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.status, 2);
                break;
                }
    
                case SMBUS_TEMPERATURE:
                {
                SMBusSlaveTxBufferSet(&g_sSlave, battery.temperature, 2);
                break;
                }
                
            }
        }
        else if(eStatus == SMBUS_TRANSFER_COMPLETE){
                SMBusSlaveTransferInit(&g_sSlave);
            }
    }

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

    尊敬的 Alberto、

     非常感谢您对  SMBusSlaveTransferInit 要求的调查理解文档有点欠缺。 如果有任何东西、我还会学习一些针对我自己的新东西。 我会将此帖子作为书签以供将来参考。