你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

I2C从机接收代码的疑惑

[复制链接]
希望在转角 提问时间:2019-9-18 17:44 /
    在网上看到一个基于STM32L011的IAP代码。其中Bootloader的I2C从机部分有点疑惑。    代码如下。这段代码表示的是检测到STOPF之后,判断是从机接收STOP还是从机发送STOP。
    其中我用红色线条框出来的部分,这部分的目的到底是啥?


    I2C.jpg

收藏 评论6 发布时间:2019-9-18 17:44

举报

6个回答
废鱼 回答时间:2019-9-19 10:57:23
我理解是发送一个NACK表示数据传输结束。
希望在转角 回答时间:2019-9-19 14:06:02
安 发表于 2019-9-19 10:57
我理解是发送一个NACK表示数据传输结束。

   但是按照协议,NACK应该由主机来发送,表示不需要从机再发数据了啊
废鱼 回答时间:2019-9-19 16:06:49
要分情况的。再写入数据时,ACK由从机控制。再读取数据时由主机控制。
希望在转角 回答时间: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 I2C  entor transmit mode*/
      
    }
    else   /*Write operation, slave receive status*/
    {
      I2C1->CR1 |= I2C_CR1_RXIE; /* Set receive IT /status*/
      i2c_event=EVENT_OPCOD_BUSY_RECEIVE; /* Set I2C  entor 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[I2C_Receive_Counter++]= 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,告知主机接收完毕。

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版