macompengluo 发表于 2019-9-18 17:44:36

I2C从机接收代码的疑惑

    在网上看到一个基于STM32L011的IAP代码。其中Bootloader的I2C从机部分有点疑惑。    代码如下。这段代码表示的是检测到STOPF之后,判断是从机接收STOP还是从机发送STOP。
    其中我用红色线条框出来的部分,这部分的目的到底是啥?


   

发表于 2019-9-19 10:57:23

我理解是发送一个NACK表示数据传输结束。

macompengluo 发表于 2019-9-19 14:06:02

安 发表于 2019-9-19 10:57
我理解是发送一个NACK表示数据传输结束。
   但是按照协议,NACK应该由主机来发送,表示不需要从机再发数据了啊

发表于 2019-9-19 16:06:49

要分情况的。再写入数据时,ACK由从机控制。再读取数据时由主机控制。

macompengluo 发表于 2019-9-19 16:19:05

安 发表于 2019-9-19 16:06
要分情况的。再写入数据时,ACK由从机控制。再读取数据时由主机控制。

   这个我清楚的。可能我没描述清楚,我把完整的I2C中断代码贴出来
   void I2C1_IRQHandler(void)
{
uint32_t I2C_InterruptStatus = I2C1->ISR; /* Get interrupt status */

if((I2C_InterruptStatus & I2C_ISR_ADDR) == I2C_ISR_ADDR) /* Check address match */
{
    I2C1->ICR |= I2C_ICR_ADDRCF;                        /* Clear address match flag*/
   
    if((I2C1->ISR & I2C_ISR_DIR) == I2C_ISR_DIR) /* Check if transfer direction is read (slave transmitter) */
    {
      I2C1->CR1 |= I2C_CR1_TXIE;      /* Set transmit IT /status*/
      i2c_event=EVENT_OPCOD_SEND;            /* Set I2Centor transmit mode*/
      
    }
    else   /*Write operation, slave receive status*/
    {
      I2C1->CR1 |= I2C_CR1_RXIE; /* Set receive IT /status*/
      i2c_event=EVENT_OPCOD_BUSY_RECEIVE; /* Set I2Centor receive mode*/
    }
   
   I2C1->CR1 |=I2C_CR1_STOPIE;//Enable STOP interrupt
   
}
else if((I2C_InterruptStatus & I2C_ISR_TXIS) == I2C_ISR_TXIS)
{
    //add some application code in this place   
}
      /*check RXDR is not empty*/
else if((I2C_InterruptStatus & I2C_ISR_RXNE) == I2C_ISR_RXNE)
{
    //I2C_ISR_RXNE add you code in this place Tomas Li add
    Receive_Buffer= I2C1->RXDR;
    i2c_event=EVENT_OPCOD_BUSY_RECEIVE;//slave is busy for receive data

}
else if((I2C_InterruptStatus & I2C_ISR_NACKF) == I2C_ISR_NACKF)
{



}
/*check Stop event happen */
if((I2C_InterruptStatus & I2C_ISR_STOPF) == I2C_ISR_STOPF)
{
   
      I2C1->ICR |=I2C_ICR_STOPCF;//clear the STOP interrupt Flag
      
#if 1
    switch(i2c_event){
    case EVENT_OPCOD_BUSY_RECEIVE://slave receive status Stop flag
      I2C_Receive_Counter=0;
      i2c_event = EVENT_OPCOD_NOTYET_READ;
      
      I2C1->CR1 &= ~(I2C_CR1_STOPIE); //Disable all interrupt.except Error interrupt
      I2C1->CR2 |= I2C_CR2_NACK;//set feedback Nack in next event
      I2C1->CR1 |= I2C_CR1_ADDRIE;      
      break;
    case EVENT_OPCOD_SEND: //slave send stop
      I2C1->ICR |=I2C_ICR_STOPCF | I2C_ICR_NACKCF |I2C_ICR_BERRCF;//clear the STOP interrupt Flag
      I2C1->CR1 |=I2C_CR1_ADDRIE;
      i2c_event = NOEVENT;
      
      break;
    default:
      
      break;
   
    }
#endif
   
}
else
{
    error = ERROR_I2C; /* Report an error */
   
}
}

发表于 2019-9-19 17:26:05

从代码上分析,当I2C总线忙时的处理机制。I2C再下个事件时产生一个NACK,用于结束处理。这里我理解时对I2C总线忙时,需要告诉主机,停止访问。

yygkqzh 发表于 2019-9-19 23:15:43

从机接收结束数据后, 产生一个NACK,告知主机接收完毕。
页: [1]
查看完整版本: I2C从机接收代码的疑惑