主要用到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 &hi2c1typedef 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;}
}

STM32 HAL 硬件I2C HTU21D相关推荐

  1. STM32的硬件I2C与AT24C16

    刚学STM32的时候就听闻STM32的硬件I2C存在重大bug,会导致运行卡死在等待ACK的过程中,所以一直以来对其避而远之,转而以模拟I2C取代之.最近这段时间一直在用STM32 CubeMX,图形 ...

  2. STM32单片机硬件I2C读取AHT10温湿度传感器数据

    STM32使用硬件IIC读取AHT10温湿度传感器的数据并显示在0.96寸OLED屏上. 我用的单片机是STM32F103C8T6,程序用的是ST标准库写的. STM32使用硬件I2C读取SHTC3温 ...

  3. STM32 HAL 驱动I2C总线0.91寸OLED模块(基于SSD1306显示驱动芯片)

    STM32 HAL 驱动I2C总线0.91寸OLED模块(基于SSD1306显示驱动芯片) 基于SSD1306驱动芯片的OLED模块有多种型号,有0.91英寸,0.96英寸等等.OLED采用单色显示方 ...

  4. STM32 HAL 硬件IIC+DMA+简单图形库控制OLED

    目录 前言 一.建立工程 二.编写和移植 前期准备 驱动部分修改 三.使用和验证 结论 (2022年1月22日重制)本文主要是移植带简单图形库的程序,如果只是实现DMA控制,建议看[0.96寸 OLE ...

  5. STM32通信硬件 I2C

    20.1关于 I2C STM32F103系列的I²C控制器,可作为通信主机或从机,因此有四种工作模式可选择:主机发送模式.主机接收模式.从机发送模式.从机接收模式. 传输速度上,支持标准模式(Stan ...

  6. STM32单片机硬件I2C驱动程序(查询方式)

    本文章原始地址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与接收. 本例程中采用I2C ...

  7. 关于 STM32 的硬件I2C

    首先转两个帖子 http://blog.csdn.net/mcu_hong/article/details/8149311 http://bbs.21ic.com/icview-184741-1-1. ...

  8. STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech

    感谢原作者:FeoTech   原文网址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与 ...

  9. 关于STM32使用硬件i2c读写AT24C256实验遇到的问题

    硬件环境:XNUCLEO开发板(STM32F411RCT6芯片).MiniSTM32 V3.41开发板(STM32F103RCT6芯片) 软件环境:IAR for ARM 8.30.1.Keil5 现 ...

最新文章

  1. Zend Studio添加ThinkPHP代码提示方法
  2. Mybatis错误:Parameter 'XXX' not found. Available parameters are [1, 0, param1, param2]
  3. 单臂路由与三层交换机—Vecloud微云
  4. matlab在一个坐标系画不同三维图,怎么用多个色标
  5. jenkins 指定 之前某版本 构建
  6. Linux第一条指令地址,arm-linux 启动代码分析——stage1 (1)
  7. c语言双向链表的作用,C语言实现双向链表
  8. Android Lolipop 屏蔽隐式Intent检查引发的错误
  9. cvResize() 图像放缩
  10. OpenCore引导配置说明第十四版-基于OpenCore-0.6.7
  11. RoboWare 下载地址
  12. Bypass disable_function
  13. 假如古人用上了区块链技术
  14. OneStep 移植
  15. 人与自然超越彩虹-下
  16. 最清晰易懂的Elasticsearch操作手册|收藏夹必备
  17. 阿里云服务器如何进行快照备份
  18. 软件工程概念总结-期末重点-(简单中文+英文关键词)-第一部分软件过程(第1-6章)-罗杰S普莱斯曼
  19. 聚合支付:将支付宝、微信、qq钱包三码收款码合而为一
  20. mysql mmm 官方_mysql mmm

热门文章

  1. JAVA攻城狮学习路线
  2. 金刚kk-1024说明书_金刚-恐龙追逐场景
  3. Matlab中的dyna,基于Matlab与Ls-dyna的气缸冲击仿真解析
  4. C++中模板类的静态成员
  5. SpringBoot 配置多数据源 dynamic-datasource(多库)
  6. 控制bing搜索爬取的方法
  7. CSS------伪类(:first)和伪元素(::after)汇总以及区别分析
  8. Shell脚本一键安装软件
  9. Filter 过滤器拦截路径配置
  10. NYOJ 1239 引水工程 【MST 变形】