i2c - 为什么“HAL_I2C_Master_Transmit”在每个循环中写入 2 个字节的数据
问题描述
我正在为 stm32f4 (V1.7.1) 使用 HAL 库,并试图了解 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;
}
}
解决方案
推荐阅读
- database - MongoDB如何回滚或销毁事务中新创建的集合
- php - 将普通的html表转换为数据表
- android - Webivew onNavigationStateChange 方法在本机反应中多次调用
- android - 将光标导出到 CSV 文件。CSV 文件丢失
- node.js - 如何使用 nodejs 自动检测 /dev/ttyUSBx 端口并使用该端口读取和写入数据?
- haskell - 如何使用 RSA 以这种特殊方式使用 criptonite 库解密 ByteString?
- python - 如何从 Python 列表中删除所有出现的元素?
- wordpress - WP json rest api验证码问题
- excel - 在单元格 B(x) 中查找一个值并替换 C(x) 中的值。偏移 1
- java - 如何为我的世界 1.15.2 制作可饮用物品