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.

[参考译文] RM46L852:I2C TXRDY 中断不会触发(当 RXRDY 正常运行时)

Guru**** 1810550 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/1346307/rm46l852-i2c-txrdy-interrupts-never-fire-while-the-rxrdy-works-fine

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

e2e 主题的更多信息。

 I2C TXRDY 中断永不触发(当 RX 正常运行时)

正如我提到过的、在我的 另一个 e2e 线程中、我的 i2c 总线运行正常。 我可以在总线上成功接收和发送数据。
也就是说、虽然 RX 中断正常工作、但我从不会接收到 TX 中断。 它们在 halcodegen 中启用。

请注意、 用户5967417已经提出了这个问题

 这个线程中、看起来即使对于经修改的代码、它们也无法接收 TX ISR。

实际上、我尝试了您的权变措施、但不起作用、因为当长度= 1时、微控制器不会调用 i2cInterrupt 函数。 当我更改长度= 2时、一切都顺利。
>所以我认为问题可能与硬件相关。 您是否尝试过解决方案? 此权变措施是否在您的设置中起作用?

由于 i2c 传输在我的工作台上运行良好、因此请不要认为它是上拉电阻或总线问题。
我没有 验证从器件的 ACK、但由于我正确地从从从器件接收到多个字节、我似乎不太可能不会接收 NACK。

您确定不可能是另外一个 HalCoGen 错误吗?  

此致、
加布里埃尔


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

    尊敬的 Gabriel:

    我们在印度度假、因此我的最新资讯可能会延迟。

    --
    谢谢。此致、
    Jagadish。

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

    感谢您提供的信息。

    愉快的假期!  

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

    尊敬的 Gabriel:

    我了解了行为的根本原因。

     实际上、我尝试了您的权变措施、但不能为我效、因为当长度为1时微控制器不调用 i2cInterrupt 函数。 当我更改长度=2时,一切都很好。

    是的、您的要求是对的、即使在我们按照 QJ 提到的那样更改了代码之后、中断也不起作用。

    据我所知、这是因为向 CNT 寄存器写入1。

    在这里、我们要将 CNT 寄存器设置为1、因为要在发送单字节之后发送停止条件、对吧?根据我的理解、这是会产生问题、我的意思是在发送字节之后、在创建中断之前、它会发送停止条件并且总线变为空闲状态、因此不会生成更多的中断。

    因此、为了确保我刚才这么做、我添加了写入 CNT 寄存器的注释、如上文 pic 中突出显示的那样。 但现在我们如何生成停止条件呢? 那么、我在我的处理程序中执行该操作。

    我只启用重复模式、然后发送停止条件。 这是因为只有在重复模式下、停止条件才会立即发送、而不取决于 CNT 寄存器。

    之后、如果需要发送更多数据、我们可以关闭重复模式。

    在进行这种修改后、似乎效果很好。

    我随附代码供您参考、请对代码进行一次性测试、并告知我您的评论。

    e2e.ti.com/.../2318.I2C_5F00_Master_5F00_RM46L852.zip

    --

    谢谢。此致、
    Jagadish。

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

    Jagadish、您好!

    我希望你有一个美好的假期!

    感谢您的回答。 我今天将介绍它。  

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

    您好,Jagadish

    感谢您提供源文件。

    您需要回答的一些问题:

    1.为什么会忽略 NACK 模式?

    2.  在中断中而不是在 main 中检查 i2cIsStopDetected ()有什么作用?
    我不希望在 ISR 中使用 while 循环。

    3.是否有理由在发送 STOP 后不重置 MDR 寄存器?   

    4.我们可以在 ISR 中清除停止条件吗?

    此致、

    加布里埃尔   

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

    尊敬的 Gabriel:

    1. 为什么您忽略 NACK 模式?

    这不是有意为之、实际上我在数据库中使用了一个旧代码并进行了修改以测试中断。 您可以使用任一模式。

    2.   在中断中而不是在 main 中检查 i2cIsStopDetected ()有什么作用?
    我不希望在 ISR 中使用 while 循环。

    您也可以检查主循环。 由于我们已在数据传输后设置了一个标志、因此在主循环中使用相同的标志、并检查主循环中的停止条件。

    3. 为什么在发送 STOP 后不复位 MDR 寄存器?   [/报价]

    没有理由、我们必须重置到 MDR 以传输更多数据。 我的意思是我们必须关闭重复模式。

    4. 我们可以在 ISR 中清除停止条件吗?

    是的、可以。 但它应始终在"等待、直到检测到 STOP "之后。

    --
    谢谢。此致、
    Jagadish。

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

    Jagadish、您好!

    感谢您的回答。

    我做了更多的测试,我发现我们的策略有问题: 忽略 i2cSetCount 只适用于第一次传输。
    一旦我们传输另一个字节、我们就会卡住。

    使用您发送给我的项目、我将 i2c 例程封装到了一个函数中、因此我可以调用两次。

    这是 sys_main.c (未触及其他文件)   

    uint8_t TX_Data_Master[DATA_COUNT] = {0xAA};
    uint8_t FLAG_STATUS = 0x00;
    
    void transmit_test(void)
    {
        FLAG_STATUS = 0;
    
        /*Ignore NACK Mode*/
        i2cREG1->EMDR |=    0x2;
    
        /* Configure address of Slave to talk to */
        i2cSetSlaveAdd(i2cREG1, DAC7574_ADDRESS);
    
        /* Set direction to Transmitter */
        i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    
        /* Set mode as Master */
        i2cSetMode(i2cREG1, I2C_MASTER);
    
        /* Set Stop after programmed Count */
        i2cSetStop(i2cREG1);
    
        /* Transmit Start Condition */
        i2cSetStart(i2cREG1);
    
        /* Tranmit DATA_COUNT number of data in Polling mode */
        i2cSend(i2cREG1, DATA_COUNT, TX_Data_Master);
    
        while(FLAG_STATUS == 0x00);
    
        /* Clear the Stop condition */
        i2cClearSCD(i2cREG1);
    }
    
    
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
        i2cInit();
    
        _enable_IRQ();
    
        transmit_test();
        transmit_test();
    
        while(1);
    /* USER CODE END */
    
        return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    void i2cNotification(i2cBASE_t *i2c, uint32 flags)
    {
    /*  enter user code between the USER CODE BEGIN and USER CODE END. */
        if(i2c == i2cREG1 && (flags & I2C_TX_INT))
        {
            i2cREG1->MDR |= (uint32)((uint32)1U << 7U);
            i2cSetStop(i2cREG1);
            while(i2cIsBusBusy(i2cREG1) == true);
            while(i2cIsStopDetected(i2cREG1) == 0);
            FLAG_STATUS = 0xFF;
        }
    }


    在这里可以看到、ISR 绝不会再次触发、

      
     

    您能否在最终重现问题?

    此致、
    加布里埃尔

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

    尊敬的 Gabriel:

    我对您的代码做了一些小改动:

    uint8_t TX_Data_Master[DATA_COUNT] = {0xAA};
    uint8_t FLAG_STATUS = 0x00;
    
    void transmit_test(void)
    {
        FLAG_STATUS = 0;
    
        /*Ignore NACK Mode*/
        i2cREG1->EMDR |=    0x2;
    
        /* Configure address of Slave to talk to */
        i2cSetSlaveAdd(i2cREG1, DAC7574_ADDRESS);
    
        /* Set direction to Transmitter */
        i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    
        /* Set mode as Master */
        i2cSetMode(i2cREG1, I2C_MASTER);
    
        /* Set Stop after programmed Count */
        //i2cSetStop(i2cREG1);
    
        /* Transmit Start Condition */
        i2cSetStart(i2cREG1);
    
        /* Tranmit DATA_COUNT number of data in Polling mode */
        i2cSend(i2cREG1, DATA_COUNT, TX_Data_Master);
    
        while(FLAG_STATUS == 0x00);
    
        /* Clear the Stop condition */
        i2cClearSCD(i2cREG1);
    }
    
    
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
        i2cInit();
    
        _enable_IRQ();
    
        transmit_test();
        transmit_test();
    
        while(1);
    /* USER CODE END */
    
        return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    void i2cNotification(i2cBASE_t *i2c, uint32 flags)
    {
    /*  enter user code between the USER CODE BEGIN and USER CODE END. */
        if(i2c == i2cREG1 && (flags & I2C_TX_INT))
        {
            i2cREG1->MDR |= (uint32)((uint32)1U << 7U);
            i2cSetStop(i2cREG1);
            while(i2cIsBusBusy(i2cREG1) == true);
            while(i2cIsStopDetected(i2cREG1) == 0);
            i2cREG1->MDR &= (uint32)(~((uint32)1U << 7U));
            FLAG_STATUS = 0xFF;
        }
    }

    您能用上面的代码测试一下吗、让我知道结果。

    --
    谢谢。此致、
    Jagadish。

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

    Jagadish、您好!

    感谢您的支持。  
    我对我的答复延迟表示歉意。


    我在  第二次传输时仍滞留在 while (flag_status == 0x00)行。

    如果您想在您的机器上进行测试、这里是附加文件中的项目。

    e2e.ti.com/.../modified_5F00_2318.I2C_5F00_Master_5F00_RM46L852.zip

    此致、
    加布里埃尔

     

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

    尊敬的 Gabriel:

    我对我的答复出现拖延表示诚挚的歉意。

    实际上、我们在 TI 印度度过了几个假期。 我也遇到了其他几个问题。

    您是否仍然坚持这个问题、如果是、那么我将需要设置并在我结束时进行测试。

    --

    谢谢。此致、
    Jagadish。

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

     Jagadish、您好!

    我希望您度过了愉快的假期。

     

    是的、我仍然坚持这个问题。
    我不敢相信使用这个外设有多难!

    如果您希望我进行其他测试、请告诉我。

    此致、   

    加布里埃尔

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

    尊敬的 Gabriel:

    我诚挚的歉意。

    我没有机会再次测试这一点。

    我将尝试在明天之前对其进行测试、这样您就可以在明天结束时期待我的回应。

    --
    谢谢。此致、
    Jagadish。

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

    尊敬的 Gabriel:

    我了解了问题的根本原因、  

    原因是您没有按照 QJ 建议修改 Tx 中断处理程序代码。

    QJ 建议的代码:

    (+) TMS570LS1115:I2C 中断不工作-基于 Arm 的微控制器论坛-基于 Arm 的微控制器- TI E2E 支持论坛

    您的当前代码:

    我们应该考虑此修改以及我之前告诉您的建议。

    以下是经过修改和测试的项目:

    e2e.ti.com/.../7220.I2C_5F00_Master_5F00_RM46L852.zip

    在上面的代码中、我还进行了另外两处更改:

    我每次执行新的传输时都会将 FLAG_STATUS 设置为零。

    发送停止条件后清除重复模式。

    --
    谢谢。此致、
    Jagadish。

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

    Jagadish、您好!  

    很抱歉、我在其他地方一直很忙、我会在本周初查看您的解决方案。

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

    Jagadish、您好!  

    很抱歉耽误你的时间。 项目仍在进行中。 我应该有时间快速对此进行测试。

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

    尊敬的 Gabriel:

    抱歉耽误时间。 项目仍在进行中。 我应该很快有时间对此进行测试。

    没问题、花点时间测试一下。 在您对其进行测试后、让我知道结果。