主要用到stm32自带的库函数,因为库函数没有等待时间,所以不兼容,把程序拷贝出来重写,“I2C_RequestMemoryRead”函数的
“/* Generate Restart */”前面添加一个80ms左右的延时即可。
htu21d.h:
#ifndef _HTU21D_H
#define _HTU21D_H
#include "stm32f4xx_hal.h"
//非主机模式
#define HTU_TEMP 0xf3
#define HTU_HUMI 0Xf5
#define HTU21D_I2C &hi2c1
typedef struct
{
float HTU21D_Temp;
float HTU21D_Humi;
uint8_t Read_Flag;
} HTU21D;
extern HTU21D htu21d;
void HTU21D_Get_Data(void);
#endif
htu21d.c:
#include "HTU21D.h"
#include "delay.h"
#include "main.h"
#include "i2c.h"
HTU21D htu21d;/**< htu21d结构体,包含温度和湿度数据 */
static HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);/**< 读取函数,因为库函数不兼容,因此在这重写一个函数 */
void HTU21D_Get_Data(void)
{
uint8_t rx_buf[2];
float temp_float;
if(HAL_I2C_Mem_Read(HTU21D_I2C, 0x80, HTU_TEMP, I2C_MEMADD_SIZE_8BIT, rx_buf, 2, 100) == HAL_OK)//读取温度
{
rx_buf[1] &= 0xfc;
temp_float = rx_buf[0];
temp_float *= 256.0f; //wendu <<=8;
temp_float += rx_buf[1];
temp_float = -46.85f + (175.72f * (temp_float*1.0f / 65536.0f));
htu21d.HTU21D_Temp = temp_float;
}
if(HAL_I2C_Mem_Read(HTU21D_I2C, 0x80, HTU_HUMI, I2C_MEMADD_SIZE_8BIT, rx_buf, 2, 100) == HAL_OK) //读取湿度
{
rx_buf[1] &= 0xfc;
temp_float = rx_buf[0];
temp_float *= 256.0f; //湿度 <<=8;
temp_float += rx_buf[1];
temp_float = -6.0f + (125.0f * (temp_float*1.0f / 65536.0f));
htu21d.HTU21D_Humi = temp_float;
}
}
static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
{
/* Wait until flag is set */
while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
{
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
hi2c->PreviousState = ((uint32_t)(HAL_I2C_MODE_NONE));
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
}
}
return HAL_OK;
}
static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart)
{
while (__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET)
{
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
{
/* Generate Stop */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
/* Clear AF Flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
hi2c->PreviousState = ((uint32_t)(HAL_I2C_MODE_NONE));
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
hi2c->PreviousState = ((uint32_t)(HAL_I2C_MODE_NONE));
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
}
}
return HAL_OK;
}
static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c)
{
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
{
/* Clear NACKF Flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
hi2c->PreviousState = ((uint32_t)(HAL_I2C_MODE_NONE));
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
return HAL_OK;
}
static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
{
while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET)
{
/* Check if a NACK is detected */
if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK)
{
return HAL_ERROR;
}
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
hi2c->PreviousState = ((uint32_t)(HAL_I2C_MODE_NONE));
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
}
}
return HAL_OK;
}
static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
{
/* Enable Acknowledge */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
/* Generate Start */
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 (hi2c->Instance->CR1 & I2C_CR1_START)
{
hi2c->ErrorCode = HAL_I2C_WRONG_START;
}
return HAL_TIMEOUT;
}
/* Send slave address */
hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(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;
}
/* If Memory address size is 8Bit */
if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
{
/* Send Memory Address */
hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
}
/* If Memory address size is 16Bit */
else
{
/* Send MSB of Memory Address */
hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress);
/* 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 LSB of Memory Address */
hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
}
/* 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;
}
delay_ms(50);
/* 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 (hi2c->Instance->CR1 & I2C_CR1_START)
{
hi2c->ErrorCode = HAL_I2C_WRONG_START;
}
return HAL_TIMEOUT;
}
/* Send slave address */
hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
/* Wait until ADDR flag is set */
if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
{
return HAL_ERROR;
}
return HAL_OK;
}
static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
{
while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET)
{
/* Check if a STOPF is detected */
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
{
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
hi2c->PreviousState = ((uint32_t)(HAL_I2C_MODE_NONE));
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
hi2c->ErrorCode |= HAL_I2C_ERROR_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
/* Check for the Timeout */
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
hi2c->PreviousState = ((uint32_t)(HAL_I2C_MODE_NONE));
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
}
return HAL_OK;
}
static HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
/* Init tickstart for timeout management*/
uint32_t tickstart = HAL_GetTick();
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
if (hi2c->State == HAL_I2C_STATE_READY)
{
/* Wait until BUSY flag is reset */
if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, 25U, 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_MEM;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferSize = hi2c->XferCount;
hi2c->XferOptions = 0xFFFF0000U;
/* Send Slave Address and Memory Address */
if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, 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);
/* Clear ADDR flag */
__HAL_I2C_CLEAR_ADDRFLAG(hi2c);
/* Generate Stop */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
}
else if (hi2c->XferSize == 2U)
{
/* Disable Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
/* Enable Pos */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
/* Clear ADDR flag */
__HAL_I2C_CLEAR_ADDRFLAG(hi2c);
}
else
{
/* 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;
}
/* 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--;
/* 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);
/* 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 */
if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_ERROR;
}
/* 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--;
/* 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)
{
/* 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;
}
}