为什么“ HAL_I2C_Master_Transmit”在每个循环中写入2个字节的数据

时间:2019-01-30 10:28:30

标签: i2c master-slave hal stm32f4

我正在将HAL库用于stm32f4(V1.7.1),并试图了解HAL_I2C_Master_Transmit的工作方式。此功能在SDA线上传输“主机到从机”数据包。 发送从站地址后,在stm32f4xx_hal_i2c.c代码中,存在一个循环(while(hi2c->XferSize > 0U)),该循环将要发送的字节发送给从站。该循环一直进行到所有字节都发送完为止。但是有一个问题,“为什么函数要在每个循环中传输两个字节?”循环中有一个IF(if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U))),它检查当前是否正在传输前一个字节,然后发送下一个字节! 我不知道在下一个循环中可以传输其他字节时存在此IF的原因是什么?

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t 
DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart = 0x00U;

  /* Init tickstart for timeout management*/
  tickstart = HAL_GetTick();

  if(hi2c->State == HAL_I2C_STATE_READY)
  {
    /* Wait until BUSY flag is reset */
    if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, 
I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
    {
      return HAL_BUSY;
    }

/* Process Locked */
__HAL_LOCK(hi2c);

/* Check if the I2C is already enabled */
if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
{
  /* Enable I2C peripheral */
  __HAL_I2C_ENABLE(hi2c);
}

/* Disable Pos */
hi2c->Instance->CR1 &= ~I2C_CR1_POS;

hi2c->State     = HAL_I2C_STATE_BUSY_TX;
hi2c->Mode      = HAL_I2C_MODE_MASTER;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;

/* Prepare transfer parameters */
hi2c->pBuffPtr    = pData;
hi2c->XferCount   = Size;
hi2c->XferOptions = I2C_NO_OPTION_FRAME;
hi2c->XferSize    = hi2c->XferCount;

/* Send Slave Address */
if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK)
{
  if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
  {
    /* Process Unlocked */
    __HAL_UNLOCK(hi2c);
    return HAL_ERROR;
  }
  else
  {
    /* Process Unlocked */
    __HAL_UNLOCK(hi2c);
    return HAL_TIMEOUT;
  }
}

/* Clear ADDR flag */
__HAL_I2C_CLEAR_ADDRFLAG(hi2c);

while(hi2c->XferSize > 0U)
{
  /* Wait until TXE flag is set */
  if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
  {
    if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
    {
      /* Generate Stop */
      hi2c->Instance->CR1 |= I2C_CR1_STOP;
      return HAL_ERROR;
    }
    else
    {
      return HAL_TIMEOUT;
    }
  }

  /* Write data to DR */
  hi2c->Instance->DR = (*hi2c->pBuffPtr++);
  hi2c->XferCount--;
  hi2c->XferSize--;

  if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U))
  {
    /* Write data to DR */
    hi2c->Instance->DR = (*hi2c->pBuffPtr++);
    hi2c->XferCount--;
    hi2c->XferSize--;
  }

  /* Wait until BTF flag is set */
  if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
  {
    if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
    {
      /* Generate Stop */
      hi2c->Instance->CR1 |= I2C_CR1_STOP;
      return HAL_ERROR;
    }
    else
    {
      return HAL_TIMEOUT;
    }
  }
}

/* Generate Stop */
hi2c->Instance->CR1 |= I2C_CR1_STOP;

hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;

/* Process Unlocked */
__HAL_UNLOCK(hi2c);

return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

0 个答案:

没有答案