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.
e2e 主题的更多信息。
I2C TXRDY 中断永不触发(当 RX 正常运行时)
正如我提到过的、在我的 另一个 e2e 线程中、我的 i2c 总线运行正常。 我可以在总线上成功接收和发送数据。
也就是说、虽然 RX 中断正常工作、但我从不会接收到 TX 中断。 它们在 halcodegen 中启用。
请注意、 用户5967417已经提出了这个问题:
在 这个线程中、看起来即使对于经修改的代码、它们也无法接收 TX ISR。
> 实际上、我尝试了您的权变措施、但不起作用、因为当长度= 1时、微控制器不会调用 i2cInterrupt 函数。 当我更改长度= 2时、一切都顺利。
>所以我认为问题可能与硬件相关。 您是否尝试过解决方案? 此权变措施是否在您的设置中起作用?
由于 i2c 传输在我的工作台上运行良好、因此请不要认为它是上拉电阻或总线问题。
我没有 验证从器件的 ACK、但由于我正确地从从从器件接收到多个字节、我似乎不太可能不会接收 NACK。
您确定不可能是另外一个 HalCoGen 错误吗?
此致、
加布里埃尔
尊敬的 Gabriel:
我了解了行为的根本原因。
实际上、我尝试了您的权变措施、但不能为我效、因为当长度为1时微控制器不调用 i2cInterrupt 函数。 当我更改长度=2时,一切都很好。
是的、您的要求是对的、即使在我们按照 QJ 提到的那样更改了代码之后、中断也不起作用。
据我所知、这是因为向 CNT 寄存器写入1。
在这里、我们要将 CNT 寄存器设置为1、因为要在发送单字节之后发送停止条件、对吧?根据我的理解、这是会产生问题、我的意思是在发送字节之后、在创建中断之前、它会发送停止条件并且总线变为空闲状态、因此不会生成更多的中断。
因此、为了确保我刚才这么做、我添加了写入 CNT 寄存器的注释、如上文 pic 中突出显示的那样。 但现在我们如何生成停止条件呢? 那么、我在我的处理程序中执行该操作。
我只启用重复模式、然后发送停止条件。 这是因为只有在重复模式下、停止条件才会立即发送、而不取决于 CNT 寄存器。
之后、如果需要发送更多数据、我们可以关闭重复模式。
在进行这种修改后、似乎效果很好。
我随附代码供您参考、请对代码进行一次性测试、并告知我您的评论。
e2e.ti.com/.../2318.I2C_5F00_Master_5F00_RM46L852.zip
--
谢谢。此致、
Jagadish。
Jagadish、您好!
我希望你有一个美好的假期!
感谢您的回答。 我今天将介绍它。
尊敬的 Gabriel:
1. 为什么您忽略 NACK 模式?
这不是有意为之、实际上我在数据库中使用了一个旧代码并进行了修改以测试中断。 您可以使用任一模式。
2. 在中断中而不是在 main 中检查 i2cIsStopDetected ()有什么作用?
我不希望在 ISR 中使用 while 循环。
您也可以检查主循环。 由于我们已在数据传输后设置了一个标志、因此在主循环中使用相同的标志、并检查主循环中的停止条件。
3. 为什么在发送 STOP 后不复位 MDR 寄存器? [/报价]没有理由、我们必须重置到 MDR 以传输更多数据。 我的意思是我们必须关闭重复模式。
4. 我们可以在 ISR 中清除停止条件吗?是的、可以。 但它应始终在"等待、直到检测到 STOP "之后。
--
[/quote]
谢谢。此致、
Jagadish。
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。
尊敬的 Gabriel:
抱歉耽误时间。 项目仍在进行中。 我应该很快有时间对此进行测试。
没问题、花点时间测试一下。 在您对其进行测试后、让我知道结果。