主要用到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); #endifhtu21d.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; } }