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.
您好!
以下资源的模块12用于 I2C 通信。
http://www.ti.com/lit/zip/ssqc019
我知道在发送地址 SCD 后会轮询。 因为当内部数据计数器(I2CCNT 中的值)计数到0时、SCD 将被置位。
此外、如果 STT 未被置位、则会轮询 ARDY 以指示计数器已减至0。
但是、为什么我们最初无法设置 NACK 位、然后轮询 NACK 位(I2CSTR.1)? 因此、如果它变为0、则表示接收器已发送确认。
根据 I2C 手册:
"当 I2C 模块是发送器时、NACK 适用(主器件或
从器件)。 NACK 指示 I2C 模块是否检测到
中的确认位(ACK)或无确认位(NACK)
接收器。 CPU 可以轮询 NACK 或使用 NACK 中断
请求。"
但 NACK 从未轮询。 是轮询 SCD/ARDY。 为什么会这样呢?
此外、仅当我们轮询 NACK 位时、我们才能实际知道接收器是否已发送确认、然后继续发送下一个数据。 但是、轮询 SCD/ARDY 如何指示接收器是否发送 ACK 以及是否可以发送下一个数据? SCD/ARDY 只能指示 I2CCNT 中设置的字节数是否已传输。 如果没有轮询 NACK、我们如何知道从器件是否已接收到数据?
提前感谢!
尊敬的 Anu:
[引用 user="Anu B">但为什么我们最初无法设置 NACK 位、然后轮询 NACK 位(I2CSTR.1)? 因此、如果它变为0、则表示接收器已发送确认。
向 I2CSTR.NACK 位写入1将手动将其清零、因此这将不起作用。 NACK 位用于检测 NACK、而不是 ACK。
[引用 USER="Anu B">SCD/ARDY 只能指示 I2CCNT 中设置的字节数是否已传输。 如果没有轮询 NACK、我们如何知道从器件是否已接收到数据?
您可以利用中断在收到 Nacks 时进行处理。 或者在轮询时使用如下所示的内容。 请注意、这适用于非 FIFO 模式。
//发送寄存器字节 对于(i=0;i< REG_SIZE;i++) { while (!I2caRegs.I2CSTR.bit.XRDY){}//确保数据正确无误 //准备好写入 I2caRegs.I2CDXR = REG[i]; //在此处添加延迟以使 TX 完成.... #if nack_check //检查是否接收到 NACK if (I2caRegs.I2CSTR.bit.nack = 1) { I2caRegs.I2CMDR.bit.STP= 1; I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit; 状态= I2C_ERROR; 返回状态; } #endif }
最棒的
Kevin
谢谢!
但是、为什么示例代码只轮询 ARDY、而从不检查接收器是否确实确认了它?
这就是我们要做的事情:
I2caRegs.I2CCNT = 1;// 1字节消息
I2caRegs.I2CDXR = POINTER_TEMPORATURE;
I2caRegs.I2CMDR.ALL = 0x6620;//主接收器、START、STOP
while (I2caRegs.I2CSTR.bit.ARDY = 0);//轮询 ARDY - 等待停止条件
之后、下一个传输开始。
因此、在不检查 ACK 位的情况下、下一个传输开始。 为什么是这样?
在任何地方、它都被告知、如果从器件不确认传输、那么下一个数据/传输就不能被启动。 但示例代码不会这样做。 那么、这不是应该的错误、因为我们永远不会知道接收器是否实际接收到了它?
Anu、
请给我们的 TI 员工几天时间、以便在将来开设新主题之前与您联系。
讨论继续在 :https://e2e.ti.com/support/microcontrollers/c2000/f/171/p/901529/3333635#3333635上进行
最棒的
Kevin