大家好、我 已经观察到我的 I2C 总线悬挂在第二个字节的第7位上
我看到了 USCI30勘误表、因此我尝试实施了权变措施
case 8u: // Vector 8: STPIFG
if (UCB1IFG & UCRXIFG)
{
if ((ucb1_i2c.rx_curr_len < ucb1_i2c.slave_rx->dat_len) &&
(ucb1_i2c.slave_rx != NULL))
{
*ucb1_i2c.slave_rx->data++ = UCB1RXBUF; // Get RX'd byte into buffer
ucb1_i2c.rx_curr_len++;
}
else
{
ucb1_i2c.rx_succeed = 0u;
uint8_t dummyClear = UCB1RXBUF;
}
}
if (ucb1_i2c.rx_succeed && (NULL != ucb1_i2c.stp_cb))
{
(*ucb1_i2c.stp_cb)();
// vTaskNotifyGiveFromISR(decode_i2c_handler, pdFALSE);
}
ucb1_i2c.rx_succeed = 1u;
ucb1_i2c.rx_curr_len = 0;
break;
case 10u: // Vector 10: RXIFG
{
if ((UCB1STAT & UCSCLLOW) != 0)
{
__delay_cycles(200);
}
else
{
UCB1IFG |= UCRXIFG;
break;
}
if (ucb1_i2c.rx_mode == SLAVE_RECEIVE)
{
if ((ucb1_i2c.rx_curr_len < ucb1_i2c.slave_rx->dat_len)
&& (ucb1_i2c.slave_rx != NULL))
{
*ucb1_i2c.slave_rx->data++ = UCB1RXBUF; // Get RX'd byte into buffer
ucb1_i2c.rx_curr_len++;
}
else
{
ucb1_i2c.rx_succeed = 0u;
uint8_t dummyClear = UCB1RXBUF;
}
}
上面是我的 I2C ISR 的一个片段(STPIFG 和 RXIFG 部分的从器件接收)
因此、在勘误表中、权变措施是检查 UCSCLLOW 已被设定至少3个 USCI 位时钟周期。
我使用的是12.8MHz SMCLK 和400kHz I2C 时钟频率。
因此、在我的 RX ISR 处理中、我正在检查 UCSCLLOW 是否被置位、我将延迟200个周期。
我认为这应该足够长、因为12.8MHz 时钟的200个周期大约为15.625us、我只需要7.5us 来覆盖3个 USCI 位时钟周期
如果 UCSCLLOW 未被置位、我只会中断并让它重新进入 ISR 以进行再次检查。
对于接收到的最后一个字节、我希望 UCSCLLOW 不被置位。 因此、我将等待 STPIFG 被触发并读取其中的最后一个字节。
执行此操作后、我在示波器上获得 SCL 线路的该图像 
我观察到、即使在实现 I2C 后、我仍然面临同样的问题、I2C 偶尔悬挂在第二个字节的第7位上。
我是否可以询问我是否对该勘误表/权变措施有误解、并检查我的权变措施实施是否正确?
