【STM32】HAL库HAL_I2C_Transmit详解
Diagram中,上方为硬件自动执行,下方为软件控制的事件(EVx)
STM32 Master Transmit diagram
HAL_I2C_Master_Transmit
函数流程图
REF:3.HAL_I2C_Master_Transmit 函数解析
代码解析
代码解析对照STM32开发指南的Master Transmit Diagram进行讲解,由Diagram可见,对于7-bit master transmitter,其流程如下:
- 发送Start信号;
- EV5 事件;
- 发送从机7-bit地址(加上写指令),等待从机ACK;
- EV6 事件;
- EV8_1 事件;
- 不断发送DATA;
- EV8_2事件;
- 发送Stop信号。
其中1~3在I2C_MasterRequestWrite
函数内实现:
static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart)
{
/* Declaration of temporary variable to prevent undefined behavior of volatile usage */
uint32_t CurrentXferOptions = hi2c->XferOptions;
/* Generate Start condition if first transfer */
if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME))
{
/* Generate Start */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
}
else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
{
/* Generate ReStart */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
}
else
{
/* Do nothing */
}
/* Wait until SB flag is set */
if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) //EV5
{
if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
{
hi2c->ErrorCode = HAL_I2C_WRONG_START;
}
return HAL_TIMEOUT;
}
if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) // Send slave address
{
/* Send slave address */
hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); // 数据在DR寄存器会自动发送
}
else
{
/* Send header of slave address */
hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress);
/* Wait until ADD10 flag is set */
if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK)
{
return HAL_ERROR;
}
/* Send slave address */
hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress);
}
/* Wait until ADDR flag is set */
if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) // EV6
{
return HAL_ERROR;
}
return HAL_OK;
}
I2C_SR1→Bit0 SB
位置1。当I2C Master发送START信号后,Bit0 SB
会硬件置1,对应为EV5 事件。I2C_SR1→Bit1 ADDR
位置1。当7-bit从机地址和从机匹配上,Bit0 ADDR
会硬件置1,对应为EV6 事件。
I2C_SR1→Bit1 AF
的状态,判断是哪种错误5对应为通过I2C_WaitOnTXEFlagUntilTimeout
判断I2C_SR1→Bit1 TXE
是否为1
I2C_SR1→Bit1 TXE
为1,此时Data Register,即I2C_DR
为空,此时可向I2C_DR
内写数据,I2C_DR
内的数据会自动发送。7对应为通过__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET
判断I2C_SR1→Bit1 BTF
是否为1
I2C_SR1→Bit1 BTF
为1,此时对应为In transmission when a new byte should be sent and DR has not been written yet (TxE=1),主机后续发送Stop,结束此次的I2C通信。作者:康