STM32外设-HAL库I2C的改动并使用

说明:

        以STM32为主机,原始hal库发送和接收的模式为只有两个参数,参数一(地址)和参数二(数据(读或写))。

        然并卵,上述模式并不适合三参数的情况,参数一(从设备地址),参数二(寄存器地址),参数三(数据(读或写))的模式。

        所以需要改良,改良内容如下3、4、5、6点。

        1、2点为配置方式。

1、GPIO配置:

/**
* @brief I2C MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hi2c->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    */
    __HAL_AFIO_REMAP_I2C1_DISABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }

}

2、外设I2C配置:

void I2C_Init(void)
{
    /* USER CODE BEGIN I2C1_Init 0 */

    /* USER CODE END I2C1_Init 0 */

    /* USER CODE BEGIN I2C1_Init 1 */

    /* USER CODE END I2C1_Init 1 */
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 400000;
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    hi2c1.Devaddress = KXTJ3_ADDR;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
        Error_Handler();
    }
    /* USER CODE BEGIN I2C1_Init 2 */

    /* USER CODE END I2C1_Init 2 */
}

3、重写(另写不改原本库内容)函数I2C_MasterRequestWrite 

/**
 * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
 *         the configuration information for I2C module
 * @param  DevAddress Target device address: The device 7 bits address value
 *         in datasheet must be shifted to the left before calling the interface
 * @param  Timeout Timeout duration
 * @param  Tickstart Tick start value
 * @retval HAL status
 */
static HAL_StatusTypeDef I2C_MasterRequestWrite_Rewrite(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;
//ACK自动产生低应答信号
    /* Disable Acknowledge */
    SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
//产生Start信号
    /* 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 */
    }
//等待Start信号完成
    /* Wait until SB flag is set */
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
    {
        if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
        {
            hi2c->ErrorCode = HAL_I2C_WRONG_START;
        }
        return HAL_TIMEOUT;
    }
//修改了从机地址由传参DevAddress改为hi2c->Devaddress
    if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
    {
        /* Send slave address */
        hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
    }
    else
    {
        /* Send header of slave address */
        hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->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(hi2c->Devaddress);
    }
    
//等待发送完成
    /* Wait until ADDR flag is set */
    if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
    {
        return HAL_ERROR;
    }
//以下为添加部分,添加的是发送从机寄存器地址
    /* Clear ADDR flag */
    __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
//等待发送为空
    /* Wait until TXE flag is set */
    if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
    {
        if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
        {
            /* Generate Stop */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
        }
        return HAL_ERROR;
    }
//发送寄存器地址
    /* Send slave registers address */
    hi2c->Instance->DR = DevAddress;
//等待ACK信号
    /* Wait until BTF flag is set */
    if (I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
    {
        if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
        {
            /* Generate Stop */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
        }
        return HAL_ERROR;
    }

    return HAL_OK;
}

 4、I2C写函数

//传参说明
//I2C_HandleTypeDef *hi2c:I2C结构体,包含从机地址信息
//uint16_t DevAddress:寄存器地址
//uint8_t *pData:需要发送的内容
//uint16_t Size需要写的数据大小
//uint32_t Timeout:最大等待时间,避免死程序

HAL_StatusTypeDef MyI2C_write_multi(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
    uint32_t 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 */
        CLEAR_BIT(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->XferSize = hi2c->XferCount;
        hi2c->XferOptions = I2C_NO_OPTION_FRAME;
//功能:发送从机地址,发送寄存器地址,只改了I2C_MasterRequestWrite_Rewrite这一行
        /* Send Slave Address */
        if (I2C_MasterRequestWrite_Rewrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK)
        {
            return HAL_ERROR;
        }
//发送数据内容
        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 */
                    SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
                }
                return HAL_ERROR;
            }

            /* Write data to DR */
            hi2c->Instance->DR = *hi2c->pBuffPtr;

            /* Increment Buffer pointer */
            hi2c->pBuffPtr++;

            /* Update counter */
            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;

                /* Increment Buffer pointer */
                hi2c->pBuffPtr++;

                /* Update counter */
                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 */
                    SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
                }
                return HAL_ERROR;
            }
        }

        /* Generate Stop */
        SET_BIT(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;
    }
}

5、 重写(另写不改原本库内容)函数I2C_MasterRequestRead

/**
 * @brief  Master sends target device address for read request.
 * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
 *         the configuration information for I2C module
 * @param  DevAddress Target device address: The device 7 bits address value
 *         in datasheet must be shifted to the left before calling the interface
 * @param  Timeout Timeout duration
 * @param  Tickstart Tick start value
 * @retval HAL status
 */
static HAL_StatusTypeDef I2C_MasterRequestRead_Rewrite(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;
//ACK自动产生低信号应答
    /* Enable Acknowledge */
    SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
//产生Start信号
    /* 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_TX)
    {
        /* 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)
    {
        if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
        {
            hi2c->ErrorCode = HAL_I2C_WRONG_START;
        }
        return HAL_TIMEOUT;
    }
//发送从设备地址由原来的传参DevAddress改为hi2c->Devaddress
    if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
    {
        /* Send slave address */
        hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
    }
    else
    {
        /* Send header of slave address */
        hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->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(hi2c->Devaddress);

        /* Wait until ADDR flag is set */
        if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
        {
            return HAL_ERROR;
        }

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

        /* Generate Restart */
        SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);

        /* Wait until SB flag is set */
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
        {
            if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
            {
                hi2c->ErrorCode = HAL_I2C_WRONG_START;
            }
            return HAL_TIMEOUT;
        }

        /* Send header of slave address */
        hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress);
    }
//以下为添加内容,发出
    /* Wait until ADDR flag is set */
    if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
    {
        return HAL_ERROR;
    }

    /* Clear ADDR flag */
    __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
//等待发送完毕
    /* Wait until TXE flag is set */
    if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
    {
        if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
        {
            /* Generate Stop */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
        }
        return HAL_ERROR;
    }
//发送寄存器地址
    /* Send slave registers address */
    hi2c->Instance->DR = DevAddress;

    /* Wait until BTF flag is set */
    if (I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
    {
        if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
        {
            /* Generate Stop */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
        }
        return HAL_ERROR;
    }
//发出Rstart信号
    /* Generate Restart */
    SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);

    /* Wait until SB flag is set */
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
    {
        if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
        {
            hi2c->ErrorCode = HAL_I2C_WRONG_START;
        }
        return HAL_TIMEOUT;
    }


    return HAL_OK;
}

6、I2C读函数

HAL_StatusTypeDef MyI2C_read_multi(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
    __IO uint32_t count = 0U;

    /* Init tickstart for timeout management*/
    uint32_t 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 */
        CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);

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

        /* Prepare transfer parameters */
        
        
        hi2c->XferCount = Size;
        hi2c->XferSize = hi2c->XferCount;
        hi2c->XferOptions = I2C_NO_OPTION_FRAME;
        hi2c->pBuffPtr = pData;
        /* Send Slave Address */
//把读重写的函数改到这里来,改动一下内容
        if (I2C_MasterRequestRead_Rewrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK)
        {
            return HAL_ERROR;
        }
//最后判断读的数据是否只有一个,一个数据数据最后自动应答NACK(高电平),如果不是则自动应答ACK(低电平)
        /* Disable Acknowledge */
        if(hi2c->XferSize <= 1){
            CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
        }

        /* Send slave address */
        hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);

        /* Wait until ADDR flag is set */
        if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, tickstart) != HAL_OK)
        {
            return HAL_ERROR;
        }
//改动以上内容
        if (hi2c->XferSize == 0U)
        {
            /* Clear ADDR flag */
            __HAL_I2C_CLEAR_ADDRFLAG(hi2c);

            /* Generate Stop */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
        }
        else if (hi2c->XferSize == 1U)
        {
            /* Disable Acknowledge */
            CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);

            /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
            software sequence must complete before the current byte end of transfer */
            __disable_irq();
    
            /* Clear ADDR flag */
            __HAL_I2C_CLEAR_ADDRFLAG(hi2c);

            /* Generate Stop */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);

            /* Re-enable IRQs */
            __enable_irq();
        }
        else if (hi2c->XferSize == 2U)
        {
            /* Enable Pos */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);

            /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
            software sequence must complete before the current byte end of transfer */
            __disable_irq();

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

            /* Disable Acknowledge */
            CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);

            /* Re-enable IRQs */
            __enable_irq();
        }
        else
        {
            /* Enable Acknowledge */
            SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);

            /* Clear ADDR flag */
            __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
        }
        
        
        while (hi2c->XferSize > 0U)
        {
            if (hi2c->XferSize <= 3U)
            {
                /* One byte */
                if (hi2c->XferSize == 1U)
                {
                    /* Wait until RXNE flag is set */
                    if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
                    {
                        return HAL_ERROR;
                    }

                    /* Read data from DR */
                    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                    /* Increment Buffer pointer */
                    hi2c->pBuffPtr++;

                    /* Update counter */
                    hi2c->XferSize--;
                    hi2c->XferCount--;
                }
                /* Two bytes */
                else if (hi2c->XferSize == 2U)
                {
                    /* Wait until BTF flag is set */
                    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
                    {
                        return HAL_ERROR;
                    }

                    /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
                       software sequence must complete before the current byte end of transfer */
                    __disable_irq();

                    /* Generate Stop */
                    SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);

                    /* Read data from DR */
                    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                    /* Increment Buffer pointer */
                    hi2c->pBuffPtr++;

                    /* Update counter */
                    hi2c->XferSize--;
                    hi2c->XferCount--;

                    /* Re-enable IRQs */
                    __enable_irq();

                    /* Read data from DR */
                    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                    /* Increment Buffer pointer */
                    hi2c->pBuffPtr++;

                    /* Update counter */
                    hi2c->XferSize--;
                    hi2c->XferCount--;
                }
                /* 3 Last bytes */
                else
                {
                    /* Wait until BTF flag is set */
                    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
                    {
                        return HAL_ERROR;
                    }

                    /* Disable Acknowledge */
                    CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);

                    /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
                       software sequence must complete before the current byte end of transfer */
                    __disable_irq();

                    /* Read data from DR */
                    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                    /* Increment Buffer pointer */
                    hi2c->pBuffPtr++;

                    /* Update counter */
                    hi2c->XferSize--;
                    hi2c->XferCount--;

                    /* Wait until BTF flag is set */
                    count = I2C_TIMEOUT_FLAG * (SystemCoreClock / 25U / 1000U);
                    do
                    {
                        count--;
                        if (count == 0U)
                        {
                            hi2c->PreviousState = I2C_STATE_NONE;
                            hi2c->State = HAL_I2C_STATE_READY;
                            hi2c->Mode = HAL_I2C_MODE_NONE;
                            hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;

                            /* Re-enable IRQs */
                            __enable_irq();

                            /* Process Unlocked */
                            __HAL_UNLOCK(hi2c);

                            return HAL_ERROR;
                        }
                    } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET);

                    /* Generate Stop */
                    SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);

                    /* Read data from DR */
                    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                    /* Increment Buffer pointer */
                    hi2c->pBuffPtr++;

                    /* Update counter */
                    hi2c->XferSize--;
                    hi2c->XferCount--;

                    /* Re-enable IRQs */
                    __enable_irq();

                    /* Read data from DR */
                    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                    /* Increment Buffer pointer */
                    hi2c->pBuffPtr++;

                    /* Update counter */
                    hi2c->XferSize--;
                    hi2c->XferCount--;
                }
            }
            else
            {
                /* Wait until RXNE flag is set */
                if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
                {
                    return HAL_ERROR;
                }

                /* Read data from DR */
                *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                /* Increment Buffer pointer */
                hi2c->pBuffPtr++;

                /* Update counter */
                hi2c->XferSize--;
                hi2c->XferCount--;

                if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET)
                {

                    if (hi2c->XferSize == 3U)
                    {
                        /* Disable Acknowledge */
                        CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
                    }

                    /* Read data from DR */
                    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;

                    /* Increment Buffer pointer */
                    hi2c->pBuffPtr++;

                    /* Update counter */
                    hi2c->XferSize--;
                    hi2c->XferCount--;
                }
            }
        }

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

        /* Process Unlocked */
        __HAL_UNLOCK(hi2c);

        return HAL_OK;
    }
    else
    {
        return HAL_BUSY;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值