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.

[参考译文] TM4C1294NCPDT:如何从 I2C 寄存器读取多个字节?

Guru**** 2581905 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/755565/tm4c1294ncpdt-how-to-read-multiple-bytes-from-i2c-register

器件型号:TM4C1294NCPDT

从 I2C 器件上的寄存器读取单个字节不会遇到任何问题、但在读取2个字节时、我的以下问题显然存在一些错误。 有人可以给我一个指针吗? 谢谢!

int I2CReceive (uint32_t SLAVE_CHN、uint8_t reg、uint8_t num_of _args)

内部 ITEMP;

//指定我们正在向 从器件写入(寄存器地址)
I2CMasterSlaveAddrSet (I2C2_base、slave_address_base_slave_chn、false);

//指定要读取的寄存器
I2CMasterDataPut (I2C2_base、reg);

//将控制字节和寄存器地址字节发送到从器件
I2CMasterControl (I2C2_base、I2C_MASTER_CMD_SINGLE_SEND);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C2_base));

//SysCtlDelay (6000);
//指定我们将从从从器件读取
I2CMasterSlaveAddrSet (I2C2_base、slave_address_base_slave_chn、true);

if (num_of_args=1){

//This section works!
//发送控制字节并从我们的寄存器中读取
//specified
I2CMasterControl (I2C2_base、I2C_MASTER_CMD_SINGLE_Receive);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C2_base));

//返回从指定寄存器提取的数据
return (short) I2CMasterDataGet (I2C2_base);



否则{

//num_of_args==2、这将不起作用
I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_start);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C2_base));

//返回从指定寄存器提取的数据
ITEMP= I2CMasterDataGet (I2C2_base);

I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_finish);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C2_base));

//返回从指定寄存器提取的数据
ITEMP= ITEMP| I2CMasterDataGet (I2C2_base)<<8;

返回 ITEMP;


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我看不到您对"I2CMasterBurstLengthSet (I2C2_base、2);"的调用。 您需要在进行突发传输之前设置突发长度。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我采纳了你的建议、但仍然有问题

    在逻辑分析仪中、我希望总线上的一个组中有4个字节、但通常主器件会拒绝 ACK、因此我看到2个或3个字节的组

    _________________

    int I2CReceiveWord (uint32_t SLAVE_CHN、uint8_t reg)

    内部 ITEMP;

    //指定我们正在向 从器件写入(寄存器地址)
    I2CMasterSlaveAddrSet (I2C2_base、slave_address_base_slave_chn、false);

    //指定要读取的寄存器
    I2CMasterDataPut (I2C2_base、reg);

    //将控制字节和寄存器地址字节发送到从器件
    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_SINGLE_SEND);

    //等待 MCU 完成事务
    while (I2CMasterBusy (I2C2_base));

    //指定我们将从从从器件读取
    I2CMasterSlaveAddrSet (I2C2_base、slave_address_base_slave_chn、true);

    I2CMasterBurstLengthSet (I2C2_base、2);
    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_start);

    //等待 MCU 完成事务
    while (I2CMasterBusy (I2C2_base));

    //返回从指定寄存器提取的数据
    ITEMP= I2CMasterDataGet (I2C2_base);

    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_finish);

    //等待 MCU 完成事务
    while (I2CMasterBusy (I2C2_base));

    //返回从指定寄存器提取的数据
    ITEMP= ITEMP| I2CMasterDataGet (I2C2_base)<<8;


    返回 ITEMP;

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

    I2C 对我来说是新手、我们是否需要使用突发模式? 我只需要从寄存器中读取两个字节(我需要从 Microchip 的 MCP9600读取温度、请参阅下面的时序)

     I2C 对我来说是新手、我们是否需要使用突发模式? 我只需要从寄存器中读取两个字节(我需要从 Microchip 的 MCP9600读取温度)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在我看来、MCP9600需要突发模式来读取温度寄存器的所有16位。 您能否将逻辑分析仪上的结果与 Microchip 数据表的图4-3进行比较? 它有何不同?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    附件是一个屏幕截图、您可以看到主器件(TM1294)拒绝 ACK 从器件读取的第一个字节、X 标记了主器件此时应 ACK 的位置

    BTW、我将读取例程分开、以使读取更简单:

    //读取从器件上的指定寄存器
    int I2CReceiveWord (uint32_t SLAVE_CHN、uint8_t reg)

    内部 ITEMP;

    //指定我们将从从从器件读取

    I2CMasterSlaveAddrSet (I2C2_base、slave_address_base_slave_chn、true);

    I2CMasterBurstLengthSet (I2C2_base、2);
    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_start);

    //等待 MCU 完成事务
    while (I2CMasterBusy (I2C2_base));

    //返回从指定寄存器提取的数据
    ITEMP= I2CMasterDataGet (I2C2_base);

    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_finish);

    //等待 MCU 完成事务
    while (I2CMasterBusy (I2C2_base));

    //返回从指定寄存器提取的数据
    ITEMP= ITEMP| I2CMasterDataGet (I2C2_base)<<8;


    返回 ITEMP;


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们似乎需要使用 I2C_MASTER_CMD_BURST_Receive_CONTC 来获取第二个字节。 我将进行详细介绍
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在我使用 I2C_MASTER_CMD_BURST_Receive_contt (请参阅附加的代码)后、至少主器件将 ACK 第二个字节。

    但出现了新问题

    对于上述捕获、我们可以看到第二个字节为0x01、第三个字节为0x89、这与 MCP9600的读数相匹配

    当我检查  I2CReceiveWord 的读数时、我发现第一个字节是0x88、第二个字节是0x1、我不知道它们是什么

    即使 通过首先调用 I2CMasterDataGet 八次来刷新 FIFO 的尝试也不会起作用、数据也是不可预测的(但 MCP9600的输出看起来非常好)。 有指针吗?

    int I2CReceiveWord (uint32_t SLAVE_CHN、uint8_t reg)

    内部 ITEMP;
    int i、i1、i2、i3;

    //指定我们要向写入(寄存器地址)
    //从器件
    //I2CMasterSlaveAddrSet (I2C2_base、slave_address_BASH+slave_CHN、false);

    //指定要读取的寄存器
    //I2CMasterDataPut (I2C2_base、reg);

    //将控制字节和寄存器地址字节发送到从器件
    //I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_SEND_START);

    //等待 MCU 完成事务
    //while ((I2CMasterBusy (I2C2_base)));

    //对于(i=0;i<8;i++) I2CMasterDataGet (I2C2_base);//我们是否需要清空 FIFO?

    //SysCtlDelay (6000);
    //指定我们将从从从器件读取
    I2CMasterSlaveAddrSet (I2C2_base、slave_address_base_slave_chn、true);

    I2CMasterBurstLengthSet (I2C2_base、2);
    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_start);

    //等待 MCU 完成事务
    while (I2CMasterBusy (I2C2_base));

    //返回从指定寄存器提取的数据
    I1= I2CMasterDataGet (I2C2_base);
    ITEMP=(i1&0xff)<<8;

    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_contt);

    //等待 MCU 完成事务
    while (I2CMasterBusy (I2C2_base));

    //返回从指定寄存器提取的数据
    I2=I2CMasterDataGet (I2C2_base);
    ITEMP= ITEMP|(i2&0xff);

    while (I2CMasterBusy (I2C2_base));


    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_Receive_finish);

    if (ITEMP=257){
    ITEMP=1;

    返回 ITEMP;


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    根据 Amit Ashara 的建议、 www.ti.com/.../spma073.pdf 帮助我重新开始