I2C实践开发 ---【STM32-I2C-HDC1080温湿度采集系统】

I2C实践开发 — STM32-I2C-HDC1080温湿度采集系统

目录

  • I2C实践开发 --- STM32-I2C-HDC1080温湿度采集系统
    • 1. 引言
    • 2. 系统架构
      • 2.1 硬件架构
      • 2.2 软件架构
    • 3. 代码分析
      • 3.1 I2C驱动文件 (i2c.h 和 i2c.c)
      • 3.2 HDC1080传感器驱动文件 (hdc1080.h 和 hdc1080.c)
    • 4. 功能总结
    • 【HDC1080传感器寄存器地址概览】
    • 5、源码分享
      • i2c.h
      • i2c.c
      • hdc1080.h
      • hdc1080.c

1. 引言

本项目旨在通过STM32F1系列微控制器实现对HDC1080温湿度传感器的控制与数据采集。HDC1080是一种高精度、低功耗的温湿度传感器,支持I2C接口通信。通过本系统,用户能够实时读取环境的温湿度数据,适用于多种场景,如工业自动化、智能家居等。

2. 系统架构

2.1 硬件架构

• 主控芯片 :STM32F1系列微控制器(如STM32F103C8T6)
• 传感器模块 :HDC1080温湿度传感器
• 通信接口 :I2C总线(主设备)

2.2 软件架构

• I2C驱动层 :负责I2C总线的初始化和数据传输。
• 传感器驱动层 :实现对HDC1080传感器的控制与数据读取。
• 上层应用 :根据需求调用传感器驱动层接口,获取温湿度数据并处理。

3. 代码分析

3.1 I2C驱动文件 (i2c.h 和 i2c.c)

目标 :配置STM32F1系列微控制器的I2C外设,实现I2C通信功能。
主要功能 :

  • IIC_Init函数 :
    • 使能I2C1和相关GPIO外设时钟。
    • 配置GPIOB的Pin6(SCL)和Pin7(SDA)为开漏输出模式。
    • 初始化I2C1外设,配置时钟频率为100kHz,采用7位地址模式。
  • I2C1_ReadData函数 :
    • 生成I2C启动信号,开始通信。
    • 发送器件地址和寄存器地址。
    • 读取指定长度的数据并存储到缓冲区中。
    • 在通信结束时发送停止信号。

特点 :

  • 严格按照I2C协议流程进行数据传输。
  • 加入适当延时,确保数据传输可靠性。

3.2 HDC1080传感器驱动文件 (hdc1080.h 和 hdc1080.c)

目标 :通过I2C接口读取HDC1080传感器的温湿度数据。
主要功能 :

  • HDC1080_ReadTemperature函数 :
    • 初始化I2C总线。
    • 读取温度数据寄存器(地址:0x00)。
    • 将读取到的16位数据转换为摄氏度。
  • HDC1080_ReadHumidity函数 :
    • 初始化I2C总线。
    • 读取湿度数据寄存器(地址:0x01)。
    • 将读取到的16位数据转换为百分比表示的湿度值。
  • HDC1080_ReadDeviceID函数 :
    • 初始化I2C总线。
    • 读取制造商ID(地址:0xFE)和设备ID(地址:0xFF)。
    特点 :
    • 严格按照HDC1080数据手册进行数据格式转换。
    • 提供温度和湿度的精确测量。

4. 功能总结

本系统通过I2C协议实现了对HDC1080温湿度传感器的控制与数据采集,具备以下功能:

  1. 初始化I2C总线,配置STM32F1系列微控制器。
  2. 读取传感器的温度和湿度数据,并进行必要的计算,转换为实际的物理量。
    读取传感器的制造商ID和设备ID,用于设备验证。

【HDC1080传感器寄存器地址概览】

HDC1080详细信息

5、源码分享

i2c.h

//i2c.h

#ifndef __IIC_H
#define __IIC_H
#include "sys.h"

// IO方向设置
#define SDA_IN()  {GPIOB->CRH &= 0XFFFF0FFF; GPIOB->CRH |= 8 << 12;}   // PB7 输入
#define SDA_OUT() {GPIOB->CRH &= 0XFFFF0FFF; GPIOB->CRH |= 3 << 12;}   // PB7 输出

// IO操作定义
#define IIC_SCL    PBout(6)   // SCL
#define IIC_SDA    PBout(7)   // SDA
#define READ_SDA   PBin(7)    // 读取 SDA

/* IIC 初始化函数 */
void    IIC_Init(void);  

/* IIC 读取器件内部数据函数 */
uint8_t I2C1_ReadData(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t length);

#endif

i2c.c

// i2c.c

#include "i2c.h"
#include "../delay/delay.h"
#include "stm32f10x_i2c.h"

/*********************************************************************************
  * @ 函数名  :IIC_Init
  * @ 功能说明:IIC初始化函数
  * @ 参数    :无         
  * @ 返回值  :无
  ********************************************************************************/
void IIC_Init(void) {
    /* 定义结构体变量 */
    GPIO_InitTypeDef GPIO_Initstructure;
    I2C_InitTypeDef I2C_Initstructure;
    
    /* 使能 I2C1 外设时钟 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);                        // 开启 I2C1 外设时钟
    /* 使能 GPIOB 和 GPIOA 外设时钟 */                                            
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                       // 开启 GPIOB 外设时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                       // 开启 GPIOA 外设时钟

    /* GPIO 配置(用于 I2C 的 SCL 和 SDA 引脚)*/
    GPIO_Initstructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;                      // 设置 Pin6 和 Pin7,Pin6 为 SCL,Pin7 为 SDA
    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AF_OD;                             // 配置为开漏模式(I2C 外设需要)
    GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;                           // 设置引脚速度为 50MHz
    GPIO_Init(GPIOB, &GPIO_Initstructure);                                      // 初始化 GPIOB 引脚

    /* I2C 配置 */
    I2C_Initstructure.I2C_ClockSpeed = 100000;                                  // 设置 I2C 时钟频率为 100kHz
    I2C_Initstructure.I2C_Mode = I2C_Mode_I2C;                                  // 设置 I2C 工作模式为 I2C 模式
    I2C_Initstructure.I2C_DutyCycle = I2C_DutyCycle_2;                          // 设置 Tlow/Thigh 的比例为 2
    I2C_Initstructure.I2C_OwnAddress1 = 0x00;                                   // 设置 I2C 主设备地址(此处为默认值 0x00)
    I2C_Initstructure.I2C_Ack = I2C_Ack_Enable;                                 // 使能 ACK 响应
    I2C_Initstructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   // 设置 7 位地址模式
    // I2C_DeInit(I2C1);                                                        // 可选:先进行 I2C 外设复位
    I2C_Init(I2C1, &I2C_Initstructure);                                         // 初始化 I2C 外设
    I2C_Cmd(I2C1, ENABLE);                                                      // 启用 I2C 外设
}


/*********************************************************************************
  * @ 函数名  :I2C1_ReadData
  * @ 功能说明:使用IIC读取器件寄存器地址中的数据(本工程中读取HDC中的数据)
  * @ 参数    :
	*			        DeviceAddr:设备器件的地址
	*			        RegAddr   :要读取的数据所在寄存器地址
  *             pBuffer   :缓冲区
  *             length    :长度
  * @ 返回值  :无
  ********************************************************************************/
uint8_t I2C1_ReadData(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t length) {
    uint16_t i;
    uint8_t Address;

    I2C_GenerateSTART(I2C1, ENABLE);                                            // 生成启动信号,开始 I2C 通信
	
	/* 等待直到 I2C 外设准备好 */
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));                

    /* 配置 7 位设备地址,并选择接收方向 */
    Address = DeviceAddr << 1;                                                  // 设备地址左移 1 位,准备设置为 7 位地址
    Address |= 0x00;                                                            // 选择发送方向(0表示写,1表示读)
	
	/* 发送设备地址(发送器模式)*/
    I2C_Send7bitAddress(I2C1, Address, I2C_Direction_Transmitter);              
    delay_ms(10);                                                                // 延时确保数据传输
	
	/* 等待 I2C 进入传输模式 */
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  
	
	/* 发送寄存器地址 */
    I2C_SendData(I2C1, RegAddr);                                                
    delay_ms(10);                                                                // 延时确保数据传输

    /* 等待寄存器地址发送完成 */
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* 重新生成启动信号,准备读取数据 */
    I2C_GenerateSTART(I2C1, ENABLE);
    delay_ms(100);                                                                // 延时确保启动信号有效

    /* 等待 I2C 外设进入接收模式 */
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    /* 发送设备地址并选择接收方向 */
    Address = (DeviceAddr << 1) | 0x01;                                         // 设备地址右移 1 位,并选择接收模式
    I2C_Send7bitAddress(I2C1, Address, I2C_Direction_Receiver);
    delay_ms(10);                                                                // 延时确保数据传输

    /* 等待 I2C 进入接收模式 */
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    /* 读取数据 */
    for (i = 0; i < length; i++) {
        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));          // 等待字节接收
        pBuffer[i] = I2C_ReceiveData(I2C1);                                     // 读取接收到的数据
        delay_ms(1);                                                            // 延时确保数据读取
    }

    /* 关闭 ACK 响应,结束数据接收 */
    I2C_AcknowledgeConfig(I2C1, DISABLE);
    I2C_GenerateSTOP(I2C1, ENABLE);                                             // 生成停止信号,结束传输

    return 0;                                                                   // 返回 0 表示成功
}

hdc1080.h

// hdc1080.h

#ifndef __HDC1080_H
#define __HDC1080_H
#include "sys.h"
#include "i2c.h"

/* HDC1080 传感器的 I2C 地址和寄存器地址定义 */
#define HDC1080_I2C_ADDR       0x40     // HDC1080 传感器的 I2C 地址(7 位地址),值为 0x40。这个地址是 7 位的,最右边的位(1)用于选择读取(读)或写操作(写)。
                                        
#define Temperature            0x00     // 温度寄存器地址,0x00 是 HDC1080 用于存储温度数据的寄存器地址。
                                        
#define Humidity               0x01     // 湿度寄存器地址,0x01 是 HDC1080 用于存储湿度数据的寄存器地址。
                                        
#define Manufacturer_ID        0xFE     // 制造商 ID 寄存器地址,0xFE 是用于读取 HDC1080 制造商 ID 的寄存器地址,返回值通常是 0x5449。
                                        
#define Device_ID              0xFF     // 设备 ID 寄存器地址,0xFF 是用于读取 HDC1080 设备 ID 的寄存器地址,返回值通常是 0x1050。

/* 配置值和状态定义 */
#define Manufacturer_ID_value  0x5449   // HDC1080 的制造商 ID 值,值为 0x5449,通常表示该传感器的制造商标识。

#define Device_ID_value        0x1050   // HDC1080 的设备 ID 值,值为 0x1050,表示该设备的唯一标识符。

#define Config_heateroff       0x1000   // 配置寄存器设置为关闭加热器,值为 0x1000,表示关闭加热器。
                                        // 当加热器关闭时,传感器工作在低功耗模式下,适用于温度和湿度的常规测量。

#define Config_heateron        0x3000   // 配置寄存器设置为打开加热器,值为 0x3000,表示打开加热器。
                                        // 打开加热器时,传感器的温度和湿度测量范围会增大,但会增加功耗。
	
/* 读取HDC1080器件中的温度 */	
float HDC1080_ReadTemperature(void);

/* 读取HDC1080器件中的湿度 */	
uint16_t HDC1080_ReadHumidity(void);

/* 读取HDC1080器件中的ID */	
void HDC1080_ReadDeviceID(uint8_t *pDeviceID);																				

#endif

hdc1080.c

// hdc1080.c

#include "hdc1080.h"
#include "../../SYSTEM/I2C/i2c.h"
#include "usart.h"
#include "delay.h"
#include "math.h"

/*********************************************************************************
  * @ 函数名  :HDC1080_ReadTemperature
  * @ 功能说明:读取HDC1080器件中的温度
  * @ 参数    :无         
  * @ 返回值  :无
  ********************************************************************************/
float HDC1080_ReadTemperature(void) {
	  IIC_Init();                                                         // 防止IIC状态不对,先初始化下IIC状态
		delay_ms(50);
    uint8_t tempData[2];                                                // 存储从传感器读取的温度数据,2字节
    uint16_t temperature = 0;                                           // 读取到的原始温度数据
    float finalTemperature = 0;                                         // 转换后的最终温度值
    
    /* 通过 I2C 读取温度数据(HDC1080_I2C_ADDR 为设备地址,Temperature 为温度寄存器地址)*/
    I2C1_ReadData(HDC1080_I2C_ADDR, Temperature, tempData, 2);
    
    temperature = (tempData[0] << 8) | tempData[1];                     // 合并读取的两个字节为一个 16 位的温度值
    
    finalTemperature = (temperature / 65536.0f) * 165.0f - 40.0f;       // 根据 HDC1080 的数据手册,将原始值转换为实际的温度(单位:摄氏度)
	                                                                      // 温度公式: (temperature / 65536) * 165 - 40
    
    finalTemperature = ((int)(finalTemperature * 100000)) / 100000.0f;  // 保证温度结果精度到小数点后五位
    
    return finalTemperature;                                            // 返回最终的温度值
}


/*********************************************************************************
  * @ 函数名  :HDC1080_ReadHumidity
  * @ 功能说明:读取HDC1080器件中的湿度
  * @ 参数    :无         
  * @ 返回值  :无
  ********************************************************************************/
uint16_t HDC1080_ReadHumidity(void) {
	  IIC_Init();                                                 // 防止IIC状态不对,先初始化下IIC状态
		delay_ms(50); 
    uint8_t humiData[2];                                        // 存储从传感器读取的湿度数据,2字节
    uint16_t humidity;                                          // 转换后的湿度值
    
    /* 通过 I2C 读取湿度数据(HDC1080_I2C_ADDR 为设备地址,Humidity 为湿度寄存器地址)*/
    I2C1_ReadData(HDC1080_I2C_ADDR, Humidity, humiData, 2);  
    humidity = (humiData[0] << 8) | humiData[1];                // 合并读取的两个字节为一个 16 位的湿度值                                                                                                                          
    humidity = (humidity * 100 / 65536);                        // 根据 HDC1080 的数据手册,将原始值转换为实际的湿度值(百分比) 
	
    return humidity;                                            // 返回最终的湿度值
}

/*********************************************************************************
  * @ 函数名  :HDC1080_ReadDeviceID
  * @ 功能说明:读取HDC1080器件中的ID
  * @ 参数    :无         
  * @ 返回值  :无
  ********************************************************************************/
void HDC1080_ReadDeviceID(uint8_t *pDeviceID) {
	  IIC_Init();                                                  // 防止IIC状态不对,先初始化下IIC状态
	  delay_ms(50);
		/* 通过 I2C 读取 HDC1080 设备的 ID(寄存器地址为 0xFE)*/
    I2C1_ReadData(HDC1080_I2C_ADDR, 0xFE, pDeviceID, 2);        
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/973845.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java毕业设计之医院门诊挂号系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的医院门诊挂号系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 医院门诊挂号系统的主要使用者…

[笔记.AI]大模型的蒸馏、剪枝、量化 | 模型压缩 | 作用与意义

上周简单整理了《deepseek-r1的不同版本&#xff08;满血版、蒸馏版、量化&#xff09;》&#xff0c;这次继续完善对其的认知——补充“剪枝”&#xff0c;并进一步整理蒸馏、剪枝、量化的作用与意义。 以下摘自与DeepSeek-R1在线联网版的对话 蒸馏、剪枝、量化是当前主流的三…

VMware按照的MacOS升级后无法联网

背景 3年前公司使用Flutter开发了一款app&#xff0c;现在app有微小改动需要重新发布到AppStore 问题 问题是原来的Vmware搭建的开发环境发布App失败了 提示&#xff1a;App需要使用xcode15IOS 17 SDK重新构建&#xff0c;这样的话MacOS至少需要升级到13.5 Xcode - 支持 - Ap…

量子计算的基本运算:Hadamard 门、CNOT 门、Pauli 门详解

量子计算是现代计算科学的前沿领域,它与经典计算机在处理信息的方式上有着本质的区别。量子计算机利用量子比特(qubit)的叠加态和量子纠缠等特性来进行计算,从而在某些特定任务上超越传统计算机。量子计算的核心运算单元是量子门,它们通过作用于量子比特来操控量子状态。本…

go http Client net/http

框架推荐 net/http go的内置http工具&#xff0c;可以构建client和server。 Slf4j Controller RequestMapping("/rest") public class RestTestController {GetMapping("/get")ResponseBodypublic String get(RequestBody SSHConnectParam param) throws…

Pycharm中断点使用技巧

1. 打开项目并准备代码 首先&#xff0c;打开 PyCharm 并加载你的 Python 项目&#xff0c;确保你已经有想要调试的 Python 代码文件。如&#xff1a; def add_numbers(a, b):result a breturn resultnum1 5 num2 3 sum_result add_numbers(num1, num2) print(f"Th…

【数据库系统概论】第第12章 并发控制

12.1 并发控制概述 并发控制是指数据库管理系统&#xff08;DBMS&#xff09;通过控制多个事务同时执行&#xff0c;保证数据的一致性和隔离性&#xff0c;避免事务间的相互干扰。 事务串行执行不能充分利用系统资源 并发执行的优点&#xff1a;能够减少处理机的空闲 时间&a…

阿里云通过docker安装skywalking及elasticsearch操作流程

系统 本文使用系统为 Alibaba Cloud Linux 3.2104 LTS 64位 配置为 4核8G PS&#xff1a;最低配置应为2核4G&#xff0c;配置过低无法启动 安装docker 1.卸载旧版本docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-…

【分治法】循环赛日程表问题 C\C++(附代码、实例)

问题描述 设计一个满足以下要求的比赛日程表&#xff1a; 每位选手必须与其他n-1个选手各赛一次每位选手一天只能赛一次循环赛一个进行n-1天选手人数 n 2 k n2^k n2k 问题分析 下图是一种日程表的安排方式 观察上图&#xff0c;我们发现日程表左上角的四行四列和右下角的四…

【第一节】C++设计模式(创建型模式)-工厂模式

目录 前言 一、面向对象的两类对象创建问题 二、解决问题 三、工厂模式代码示例 四、工厂模式的核心功能 五、工厂模式的应用场景 六、工厂模式的实现与结构 七、工厂模式的优缺点 八、工厂模式的扩展与优化 九、总结 前言 在面向对象系统设计中&#xff0c;开发者常…

基于windows的docker-desktop安装kubenetes以及dashboard

我们需要k8s环境做各种小实验可以本地安装一个&#xff0c;这里介绍win11如何通过docker-desktop安装k8s以及通过helm安装dashboard。 下载docker-desktop地址https://www.docker.com/get-started/打开【控制面板】->打开【启用和关闭windows功能】->分别勾选【hyper-v】…

vmware虚拟机Ubuntu Desktop系统怎么和我的电脑相互复制文件、内容

1、先安装vmware workstation 17 player&#xff0c;然后再安装Ubuntu Desktop虚拟机&#xff0c;然后再安装vmware tools&#xff0c;具体可以参考如下视频&#xff1a; VMware虚拟机与主机实现文件共享&#xff0c;其实一点也不难_哔哩哔哩_bilibili 2、本人亲自试过了&…

AIGC视频扩散模型新星:SVD——稳定扩散的Video模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍慕尼黑大学携手 NVIDIA 等共同推出视频生成模型 Video LDMs。NVIDIA 在 AI 领域的卓越成就家喻户晓&#xff0c;而慕尼黑大学同样不容小觑&#xff0c;…

llama-factory部署微调方法(wsl-Ubuntu Windows)

llama-factory项目GitHub地址&#xff1a;GitHub - hiyouga/LLaMA-Factory: Unified Efficient Fine-Tuning of 100 LLMs & VLMs (ACL 2024) wsl-Ubuntu&#xff1a; 1.获取项目 git clone https://github.com/hiyouga/LLaMA-Factory.gitcd LLaMA-Factory/ 2.安装环境…

数据结构之【顺序表简介】

1.顺序表的概念 顺序表 是 用一段物理地址连续的存储单元 依次 存储数据元素的线性结构 一般情况下采用数组存储 2.顺序表的结构 既然顺序表可以用来存储数据元素&#xff0c; 那就少不了 增删查改 的操作 此时&#xff0c;单一地只创建数组满足不了上述操作 创建相应的结构…

基于Spring Boot的农产品智慧物流系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

具有整合各亚专科医学领域知识能力的AI智能体开发纲要(2025版)

整合各亚专科医学领域知识能力的AI代理的开发与研究 一、引言 1.1 研究背景 在科技飞速发展的当下,人工智能(AI)已成为推动各行业变革的关键力量,医疗领域也不例外。近年来,AI 在医疗行业的应用取得了显著进展,从医学影像诊断到疾病预测,从药物研发到个性化医疗,AI 技…

【Redis】在Java中以及Spring环境下操作Redis

Java环境下&#xff1a; 1.创建maven 项目 2.导入依赖 <!-- redis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.2</version></dependency> 此处使用的是Jedis&…

功能说明并准备静态结构

功能说明并准备静态结构 <template><div class"card-container"><!-- 搜索区域 --><div class"search-container"><span class"search-label">车牌号码&#xff1a;</span><el-input clearable placeho…

【华三】STP的角色选举(一文讲透)

【华三】STP的角色选举 一、引言二、STP基础概念扫盲三、根桥选举过程详解四、根端口选举过程详解五、指定端口选举过程详解六、阻塞端口七、总结与配置建议七、附录**1. BPDU字段结构图&#xff08;文字描述&#xff09;****2. 华三STP常用命令速查表** 文章总结 一、引言 在…