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:TM4C123G Launchpad 上的 I2C 中断

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/592412/tm4c123gh6pm-i2c-interrupts-on-tm4c123g-launchpad

器件型号:TM4C123GH6PM
主题中讨论的其他器件:TM4C123

我的代码已成功使用 I2C 的轮询方法、与 MCP23017总线扩展器连接。  但是、由于一些时序问题、我要转到中断驱动的 I2C 通信来释放一些 CPU 时间。  我的代码基于为 SPMA073提供的源文件、此源文件可在 TI 网站上找到。  我意识到它是为 Tm4C129x 编写的、但我希望它适应 TM4C123。  

我注意到的第一件事是、示例代码似乎使用的是16位寄存器地址、其中我只需要一个8位寄存器地址、因此我更正了该地址。  我可以在中断处理程序中设置断点、并查看是否发送寄存器地址和两个数据字节(寄存器地址0x00、数据为0x00和0x00、以将总线扩展器端口设置为输出。)  

我还看到它从发送最后一个字节   

 I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);

 然后、它会在下面代码的 while 循环中挂起。  它永远不会转换到 I2C_OP_STOP 状态。  请参阅底部的中断句柄中的片段。  有什么想法吗?  


G_ui8MasterTxData[0]= 0x00;
G_ui8MasterTxData[1]= 0x00;
G_ui8MasterTxData[2]= 0x00;
G_ui8MasterBytesLength = 2;

//
//在中设置发送标志并设置页地址
//将外部从器件连接到0x0000
//
G_bI2CDirection = false;
G_registerAddress = 0x00;
G_ui16SlaveWordAddress = 0x0;
G_ui8MasterBytes = 0;

IntTrigger (INT_I2C0);
while (g_ui8MasterCurrent 状态!= I2C_OP_STOP);
G_ui8MasterCurrent 状态= I2C_OP_IDLE;

中断处理程序片段

I2C_OP_TXDATA 案例:
//
//将当前状态移动到上一状态
//否则继续传输直到最后一个字节
//
G_ui8MasterPrevState = g_ui8MasterCurrent 状态;

//
//如果地址或数据已经 NAK'ed,则转至停止状态
//如果由于获得的字节数而出现停止条件
//完成,然后移动到停止状态
//
if (ui32I2CMasterInterruptStatus & I2C_MASTER_INT_NACK)

G_ui8MasterCurrent 状态= I2C_OP_STOP;

否则、IF (ui32I2CMasterInterruptStatus 和 I2C_MASTER_INT_STOP)

G_ui8MasterCurrent 状态= I2C_OP_STOP;

其他

I2CMasterDataPut (I2C0_BASE、g_ui8MasterTxData[g_ui8MasterBytes++]);
if (g_ui8MasterBytes == g_ui8MasterBytesLength)

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);

其他

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);

中断;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    顺便说一下、这是我使用的中断屏蔽。。

    //启用中断
    I2CMasterIntEnableEx (I2C0_BASE、(I2C_MASTER_INT_ARB_Lost | I2C_MASTER_INT_STOP | I2C_MASTER_INT_NACK |
    I2C_MASTER_INT_TIMEOUT | I2C_MASTER_INT_DATA);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Brian Savage"]

    IntTrigger (INT_I2C0);
    while (g_ui8MasterCurrent 状态!= I2C_OP_STOP);

    “IntTrigger ()”吸引了我的眼球-这是不是 API 中的一个官方函数?    (我们的组使用(仅限) StellarisWare -我已选中- IntTrigger ()不包括在其中。)

    如果怀疑是正确的(你"发明了"一个函数)并且你在 while 循环之后(立即)成为"被"进入"-这样的点(很多)指向 IntTrigger()的失败。

    您会说、"一些时序问题"、但不详细-我们使用了精确的 I/O 扩展器-在轮询时没有发现这样的"时序问题"。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Brian、
    我想您从应用手册中获取了示例代码、对吧?

    您说过它完成了 I2C_MASTER_CMD_BURST_SEND_FINISH。 您是否看到主器件发送停止位? 如果您看到停止位、您是否看到 I2CMMIS 寄存器中的 STOPMIS 位被置位?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    IntTrigger(),第359页,TivaWare 驱动程序库用户指南。  时序问题不是总线扩展器。  我在多种设计中使用这些器件。  问题是我对 它们的 I2C 接口的实现。  以400Hz 的频率向两个器件写入16位会导致4kHz 闭环控制系统过度运行。

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

    Charles - 是的、我确实看到了停止位、但似乎从未生成停止中断?  我更改了中断处理程序中的代码、以强制更改发送的最后一个字节的状态。 (请参阅下面的红色文本。  我在中断处理程序中粘贴了单个案例。

      I2C_OP_TXDATA 案例:

        //

        //将当前状态移动到上一状态

        //否则继续传输直到最后一个字节

        //

        G_ui8MasterPrevState = g_ui8MasterCurrent 状态;

        //

        //如果地址或数据已经 NAK'ed,则转至停止状态

        //如果由于获得的字节数而出现停止条件

        //完成,然后移动到停止状态

        //

        if (ui32I2CMasterInterruptStatus & I2C_MASTER_INT_NACK)

        {

          G_ui8MasterCurrent 状态= I2C_OP_STOP;

        }

        否则、IF (ui32I2CMasterInterruptStatus 和 I2C_MASTER_INT_STOP)

        {

          G_ui8MasterCurrent 状态= I2C_OP_STOP;

        }

        其他

        {

          I2CMasterDataPut (I2C0_BASE、g_ui8MasterTxData[g_ui8MasterBytes++]);

          if (g_ui8MasterBytes == g_ui8MasterBytesLength)

          {

            I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);

            //尝试此操作?

            G_ui8MasterCurrent 状态= I2C_OP_STOP;

          }

          其他

          {

            I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);

          }

        }

        中断;

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

    您好 Brian、

     我认为您不能像现在一样使用 TM4C123的示例代码、因为示例代码是为 TM4C129编写的。 如果您看到下面的中断状态寄存器、它们会有很大不同。

    TM4C129:

    TM4C123:

    我倾向于认为、在完成 传输结束的 I2C_MASTER_CMD_BURST_SEND_FINISH 之后。 TM4C123不会单独生成另一个停止中断。  I2C_OP_STOP 只是一个软件执行的状态。 在您进行修改后、它应该起作用、对吧?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、我已经将它破解了。 现在、我将对其进行重新计算并进行清理。 谢谢