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.

[参考译文] TM4C1290NCPDT:读取 I2C 数据时出现问题。

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1356707/tm4c1290ncpdt-having-problem-reading-i2c-data

器件型号:TM4C1290NCPDT

我正在尝试作为主设备读取一个字节的数据。  因此、I2C 总线应发送1)器件 I2C 地址、2)发送正在访问的寄存器编号、3)读取返回的值。  代码如下:

U8 RtcRead (U8寄存器){                                         //
                                                                  //
   while (I2CMasterBusy (I2C0_BASE){}                            //如果仍在运行、请等待。
   I2CMasterSlaveAddrSet (I2C0_BASE、rtcAddr、I2CRead);           //这会将 addr 向左移动1。
   I2CMasterDataPut (I2C0_BASE、寄存器);                        //
   I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);      //发送寄存器。
   while (! I2CMasterBusy (I2C0_BASE){}                         //等待主器件忙、
   while (I2CMasterBusy (I2C0_BASE)){}                            //然后等待完成。
   I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_RECEIVE);   //获取数据。
   while (! I2CMasterBusy (I2C0_BASE){}                         //等待主器件忙、
   while (I2CMasterBusy (I2C0_BASE)){}                            //然后等待完成。
   return (I2CMasterDataGet (I2C0_BASE);                          //
}                                                                 //

这是在 I2C 总线上发生的情况、而不是第二个字节上的 NAK、因为0x40是无效的寄存器编号:

谢谢、Doug

P.S.我希望对 I2C 的使用有一个比 TivaWare 手册中更好的写法-而这些示例对我没有太大帮助。  是否有很多人使用 TM4C 器件和 I2C?

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

    我尝试使用突发模式、结果如下:

        while (I2CMasterBusy (I2C0_BASE){}                            //如果仍在运行、请等待。
       I2CMasterSlaveAddrSet (I2C0_BASE、rtcAddr、I2CRead);           //这会将 addr 向左移动1。
       I2CMasterDataPut (I2C0_BASE、寄存器);                        //
       I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);      //发送寄存器。
       while (! I2CMasterBusy (I2C0_BASE){}                         //等待主器件忙、
       while (I2CMasterBusy (I2C0_BASE)){}                            //然后等待完成。
       I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_RECEIVE_FINISH);      //发送寄存器。
       while (! I2CMasterBusy (I2C0_BASE){}                         //等待主器件忙、
       while (I2CMasterBusy (I2C0_BASE)){}                            //然后等待完成。
       return (I2CMasterDataGet (I2C0_BASE);                          //

    下面是波形:

    我不知道0x40来自哪里、寄存器为#1。

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

    尊敬的 Doug:

     您的从器件是什么?

     我认为从  I2CMasterSlaveAddrSet (I2C0_BASE、RtcAddr、I2CRead)开始读取从器件是不正确的。 您需要首先写入从器件、以指定要读取的寄存器(0x1)。 因此、应该以类似的值(I2C0_BASE、RtcAddr、I2CWrite)开始。 在您使用 I2C_MASTER_CMD_BURST_SEND_START 写入寄存器值0x1后、I2C 总线处于保持状态、 您可以使用 I2C_MASTER_CMD_BURST_RECEIVE_FINISH 读取寄存器。

    此应用手册可用于说明如何使用 I2C。 从第4.5.1节开始。  

    https://www.ti.com/lit/pdf/spma073

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

    尊敬的 Charles:

    从站是 MAX31329实时时钟、它似乎正在正确读取数据、因为它会对无效寄存器编号进行 NAK、并确认有效值。

    我尝试了.BURST_SEND_START、然后...BURST_RECEIVE_FINISH 却没有成功。  我认为突发模式不适用于此情况、因为是在地址帧内确定事务是读取还是写入、所以要先进行写入、然后进行读取就不必先进行单次写入、然后进行单次读取?

    当我进行一个单次发送后跟一个单次接收(上面的第一个代码)时、它进行一个读取后跟一个读取!!  

    如果我先执行突发发送开始命令、然后执行突发接收完成命令、则会对同一行数据执行2次写入。


    如果我执行"突发发送开始"后跟单次接收、则执行"接收"后跟"接收"。 (哇!)

    这里发生了一些有趣的事情。  谢谢、Doug

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

    读取 SLVA704 "了解 I2C 总线"的第3.2节表明、要想读取寄存器、必须满足以下条件:

    我该怎么做?

    谢谢

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

    Doug

     您可以尝试以下代码序列吗? 它有什么不同? 注意我没有包括  I2CMasterBusy()和! I2CMasterBusy()如第一答复所述。 您仍然需要它们。  

      I2CMasterSlaveAddrSet (I2C0_BASE、RtcAddr、I2CWrite);     
       I2CMasterDataPut (I2C0_BASE、寄存器);              
       I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);   
       I2CMasterSlaveAddrSet (I2C0_BASE、rtcAddr、I2CRead);   
       I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_RECEIVE_FINISH);   
      return (I2CMasterDataGet (I2C0_BASE);

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

    啊、需要设置读取位。  此代码不起作用、但当我执行.BURST_SEND_START 后跟.single_receive 时工作正常!  突发启动会生成所需的重复启动帧、单个接收会再次发送地址帧、而 BURST_RECEIVE_FINISH 不会发送该地址帧。

    谢谢 Charles!

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

    我认为突发模式适用于具有"自动寄存器递增"功能的 I2C 从器件。

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

    尊敬的 Doug:

     很高兴您的问题得到解决。 您是否可以发布您的代码片段、以便社区中的人员在使用  MAX31329 器件时受益。  

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

    另请注意,我需要返回并实现对 I2CMasterErr ()的调用。

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

    尊敬的 Doug:

     感谢您的分享。 我会将此帖子作为书签以供将来参考。