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.

[参考译文] TMS570LC4357:通用中断驱动 I2C 读取功能

Guru**** 2399305 points
Other Parts Discussed in Thread: HALCOGEN

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1326322/tms570lc4357-generic-interrupt-driven-i2c-read-function

器件型号:TMS570LC4357
主题中讨论的其他器件:HALCOGEN

我想创建一个通用中断驱动的 I2C 读取函数、并且已经完成以下操作:

我调用 i2cInit (),它为 I2C_2采用以下 HALCoGen 设置:

  • 启用 I2C2驱动器
  • I2C2:
    • 启用主模式
    • TX/TX Rx:发送器
    • 添加模式:7_bit_AMODE
    • 位计数:8_bit
    • 启用 ICRRDY
    • 启用 ICXRDY
    • I2C 引脚模式:I2C 功能
  • 引脚多路复用:
    • 检查 I2C2 (SDA @ G17且 SCL @ G16)

我的读取函数会进行以下调用:

UINT8通道;

i2cSetSlaveAdd ( i2cREG2、SLAVE_ADDR);
i2cSetDirection ( i2cREG2, I2C_TRANSMIT );
i2cSetCount ( i2cREG2, 2 );
i2cSetMode ( i2cREG2, I2C_MASTER );
i2cSetStop(  i2cREG2 );
i2cSetStart(  i2cREG2 );
i2cSend ( i2cREG2、1U、REGISTER_ADDR );
while ( i2cIsBusy (  i2cREG2 )== true );
while ( i2cIsStopDetected ( i2cREG2  )== true );
i2cClearSCD(  i2cREG2 );

i2cSetSlaveAdd (i2cREG2、SLAVE_ADDR);
i2cSetDirection ( i2cREG2, I2C_receiver );
i2cSetCount ( i2cREG2, 2u );
i2cSetMode ( i2cREG2, I2C_MASTER );
i2cSetStart(  i2cREG2 );
i2cReceive(i2cREG2, 1u,&ch );
i2cClearSCD(  i2cREG2 );

我的 i2cNotification 函数如下:

void i2cNotification (i2cbase_t *i2c,uint32标志)
{


UINT8通道;

if ( FLAG & I2C_RX_INT )

{

i2cReceive(i2cREG2, 1,&ch );


在 HDK 上运行上述代码后、中断服务例程(ic2Notification)会从 BME280传感器接收到4个字节(错误地为零)、我请求其 ID 为一个字节!

有人能评论一下我上面的函数调用序列中的错误吗?
i2cSetCount 值应该是多少?  它是否需要考虑从器件地址?

谢谢你。

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

    您好、Jerry。

    只需确保您的操作正确无误、

    1.您是否正确选择了 i2c 接口、方法是将 CSB 引脚连接到 VDDIO

    2.您是否正确设置了从地址? 如果 SDO 接地、则从器件地址将为0x76。 如果 SDO 连接到 VDDIO、则从器件地址将为0x77。 和 SDO 不应悬空。

    3、我怀疑的主要问题是,在我们发送注册地址后,我们不应该发送停止条件。

    如上图所示、在发送一个寄存器地址并从从器件收到 ACK 后、我们只是再次发送 START、而不是 STOP 条件正确吗? 这不过是一个重复的启动条件。

    但是、如果我验证了您的代码、您是在发送寄存器地址后提供停止条件?

    只需按如下方式进行修改即可查看结果:

    i2cSetSlaveAdd ( i2cREG2、SLAVE_ADDR);
    i2cSetDirection (  i2cREG2, I2C_TRANSMIT );
    i2cSetCount (  i2cREG2, 1 );
    i2cSetMode (  i2cREG2, I2C_MASTER );
    i2cSetStart(  i2cREG2  );
    i2cSend (  i2cREG2、1U、REGISTER_ADDR );
    while ( i2cIsBusy (  i2cREG2  )== true );

    i2cSetSlaveAdd ( i2cREG2、SLAVE_ADDR);
    i2cSetDirection (  i2cREG2, I2C_receiver );
    i2cSetCount (  i2cREG2, 1U );
    i2cSetStop(  i2cREG2 );

    i2cSetStart(  i2cREG2  );
    i2cReceive(i2cREG2, 1u, &ch );
    i2cClearSCD(  i2cREG2  );

    --
    谢谢。此致、
    Jagadish。

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

    Jagadish、您好!

    感谢您的回复。

    是的、我在 BME280上具有 CSB 和 SDO 至 VDDIO、因此启用 I2C 接口并且从地址为0x77。

    我根据您的指示修改了代码、并会进行测试、然后回复给您。

    此致、

    杰瑞

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

    Jagadish、您好!

    根据您的代码片段、我能够使用以下代码与 BME280 I2C 器件进行通信:
    __________________________________

    #define SLAVE_ADDR 0x77

    uint8_t 通道;
    uint32_t i;
    uint8_t TX_DATA[ 2 ]={0xE0、0xD0};/* 0xE0:复位 BME280、0xD0:BME280 ID 寄存器*/

    _enable_interrupt_();

    i2cInit();

    i2cSetSlaveAdd (i2cREG2、SLAVE_ADDR);
    i2cSetDirection ( i2cREG2, I2C_TRANSMIT );
    i2cSetMode ( i2cREG2, I2C_MASTER );

    i2cSetCount ( i2cREG2, 1U );
    i2cSetStart( i2cREG2 );
    i2cSend (i2cREG2、1U、&TX_DATA[ 0 ]);  /*发送 BME280重置命令*/
    // while ( i2cIsBusy ( i2cREG2 )== true );

    对于(I = 0;I < 10000;I++);

    i2cSetCount ( i2cREG2, 1U );
    i2cSetStart( i2cREG2 );
    i2cSend (i2cREG2、1U、&TX_DATA[ 1 ]);  /*发送 BME280 ID 寄存器*/
    // while ( i2cIsBusy ( i2cREG2 )== true );

    对于(I = 0;I < 10000;I++);

    i2cSetSlaveAdd (i2cREG2、SLAVE_ADDR);
    i2cSetDirection ( i2cREG2, I2C_receiver );
    i2cSetStop( i2cREG2 );

    i2cSetCount ( i2cREG2, 1U );
    i2cSetStart( i2cREG2 );
    i2cReceive(i2cREG2, 1u,&ch );

    i2cClearSCD( i2cREG2 );
    __________________________________

    离开第一个 i2cIsBusBusy 检查没有问题,但第二个导致程序无限期等待。  因此我在每个 i2cSend 后放入一个小延迟。
    哪项检查是合适的、这样程序就不会无限期等待?  或许是一个 Tx 完成?

    以下是 SDA 和 SCL 信号的快照、如果您需要检查数据的有效性。

    很好的餐厅
    杰瑞

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

    您好、Jerry。

    不要将 ID 读取命令与复位命令组合在一起。 复位命令在此处无用、因为复位传感器采用不同的步骤。

    如您所见、要对器件进行复位、我们必须随命令0xE0发送0xB6、然后我们必须发送停止条件、此过程是不同的。 因此、只需删除发送0xE0命令、同时发送 ID 读取命令、按如下所示修改代码、并更新结果。

    #define SLAVE_ADDR 0x77

    uint8_t 通道;
    uint32_t i;
    uint8_t TX_DATA[ 2 ]={0xE0、0xD0};/* 0xE0:复位 BME280、0xD0:BME280 ID 寄存器*/

    _enable_interrupt_();

    i2cInit();

    i2cSetSlaveAdd (i2cREG2、SLAVE_ADDR);
    i2cSetDirection ( i2cREG2, I2C_TRANSMIT );
    i2cSetMode ( i2cREG2, I2C_MASTER );

    i2cSetCount ( i2cREG2, 1U );
    i2cSetStart( i2cREG2 );
    i2cSend (i2cREG2、1U、&TX_DATA[ 1 ]);  /*发送 BME280 ID 寄存器*/
    while ( i2cIsBusy ( i2cREG2 )== true );

    i2cSetSlaveAdd (i2cREG2、SLAVE_ADDR);
    i2cSetDirection ( i2cREG2, I2C_receiver );
    i2cSetStop( i2cREG2 );

    i2cSetCount ( i2cREG2, 1U );
    i2cSetStart( i2cREG2 );
    i2cReceive(i2cREG2, 1u,&ch );

    i2cClearSCD( i2cREG2 );

    --
    谢谢。此致、
    Jagadish。

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

    Jagadish、您好!

    非常好的是、你注意到了复位过程和它对于通用读取的独立性。  我将测试上述情况并提出建议。

    此致、
    杰瑞

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

    Jagadish、您好!

    感谢您的帮助、以上代码解决了通信问题。

    此致、
    杰瑞