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.

[参考译文] MSP430FR2433:MSP430 I2C 从器件需要时钟扩展来实现地址 ACK?

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/679701/msp430fr2433-msp430-i2c-slave-requires-clock-stretching-for-address-ack

器件型号:MSP430FR2433
主题中讨论的其他器件: USB2ANY

我的设置由一个以16MHz 运行的 MSP430FR2433 I2C 从设备组成。 I2C 主设备通信使用 TI USB2ANY 器件完成。 我注意到 MSP430需要定期拉伸 I2C 时钟以跟上主设备的步伐。 在所连接的捕获中、需要时钟拉伸来应答地址。 我意识到这完全符合 I2C 规范、但我对它无法跟上100kHz I2C 总线有点惊讶?

这是我的 ISR:

#pragma vector=USCI_B0_vector
__interrupt void USCIB0_ISR (void)
{
switch (_even_in_range (UCB0IV、0x1E))
{
案例0x00:break;//向量00:无中断
案例0x02:break;//向量02:UCALIFG
案例0x04:break;//向量
0x06 UCNIFG 案例0x04:CnIFG:CnIFG: //向量06:UCSTTIFG 启动
rxBuffIndex = 0;
中断;
情况0x08: //向量08:UCSTPIFG 停止
stopSet = true;
break;
case 0x0A:break;// Vector 0A:UCRXIFG3
case 0x0C:break;// Vector 0C:UCTXIFG3
case 0x0E:break;// Vector 0E:UCRXIFG2
case 0x10:break;// Vector 10:UCTXIFG2
case 0x12:break;// Vector 12:UCRXIFG1
:UCRXIFG1:0x14:UCRXIFG1:case 0x14;/ Vector 0x14:break
//向量16:UCRXIFG0
if (rxBuffIndex >= slave_I2C_buff_size)
{
//生成 NAK
UCB0CTLW0 |= UCTXNACK;
返回;
}
rxBuff[rxBuffIndex++]= UCB0RXBUF;

IF (stopSet)
{
stopSet = false;
if (dataRxCallback!= NULL)
{
dataRxCallback (&rxBuff[0]、rxBuffIndex);
}
}
中断;
情况0x18: //向量18:UCTXIFG0
if (txBuff.dataIndex >= txBuff.maxNumBytes)
{
//生成 NAK
UCB0CTLW0 |= UCTXNACK;
返回;
}
UCB0TXBUF = txBuff.dataPtR[txBuff.dataIndex++];
break;
case 0x1A:break;// Vector 1A:UCBCNTIFG
case 0x1C:break;// Vector 1C:UCCLTOIFG
case 0x1E:break;// Vector 1E:UCBIT9IFG
default:break;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    时钟扩展量取决于 CPU 对 TXIFG 的响应速度[另请参阅 SLAU45G 图23-9]。

    60us 对于这种数量的代码(16MHz 时)似乎有点长、但您似乎也在通过 UCSTTIFG 的 ISR 单独执行、因此这是2次调用。

    也许(?) 优化器可以提供一些帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Rob、您好!
    我需要稍微更正上一个帖子。
    正确的数字是用户指南 slau445g 中的图23-10。
    ISR 中的代码行、用于触发 ACK 并应释放 SCL
    rxBuff[rxBuffIndex++]= UCB0RXBUF;
    您可以插入一个触发器、例如切换 GPIO 以监控 CPU 对 RX 缓冲区的读取访问、从而确定接收是否按预期工作、而不会停止 CPU。

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

    感谢您的回复!

    根据用户指南、如果 I2C 地址 ACK 与 UCB0I2COA0匹配、则由外设完成、这让我感到困惑、因为 I2C 时钟被扩展以应答地址。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我必须服从 USCI 设计人员("我只知道我在状态图中读出的内容")。

    也许规范中有一些禁止拉伸 Tx 字节第一位上的时钟的内容(或常见用法)? (我刚刚完成了。)

    主发送器对 TXIFG 有相同的要求--它将在 TXBUF 被载入前停止总线。