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 为 SDAGPIO_Initstructure.GPIO_Mode = GPIO_Mode_AF_OD;                             // 配置为开漏模式(I2C 外设需要)GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;                           // 设置引脚速度为 50MHzGPIO_Init(GPIOB, &GPIO_Initstructure);                                      // 初始化 GPIOB 引脚/* I2C 配置 */I2C_Initstructure.I2C_ClockSpeed = 100000;                                  // 设置 I2C 时钟频率为 100kHzI2C_Initstructure.I2C_Mode = I2C_Mode_I2C;                                  // 设置 I2C 工作模式为 I2C 模式I2C_Initstructure.I2C_DutyCycle = I2C_DutyCycle_2;                          // 设置 Tlow/Thigh 的比例为 2I2C_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 - 40finalTemperature = ((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);        
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯好数

样例输入&#xff1a; 24 输出&#xff1a;7 输入&#xff1a;2024 输出&#xff1a; 150 思路&#xff1a;本题朴素方法的时间复杂度是O(n * log10(n)) &#xff0c;不超时。主要考察能否逐位取数&#xff0c;注意细节pi&#xff0c;这样不会改变i,否则会导致循环错误。 #in…

Linux-Ansible命令

文章目录 常用命令基础命令 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Linux专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年02月21日18点49分 常用命令 ansible #主命令&#xff0c;管理员临时命令的执行工具 ansible-doc #…

AI到底能做些什么:详细产品功能对比

1. 引言 人工智能&#xff08;AI&#xff09;作为当今科技领域的热门话题&#xff0c;已经在多个行业中展现出巨大的潜力。从自然语言处理到计算机视觉&#xff0c;从语音识别到自动化机器人&#xff0c;AI的应用范围广泛且深入。本文将详细探讨AI的核心功能、在各行业的应用、…

vue 学习-vite api.js

/** 整机管理 * */ // 整机分类 列表 export const wholeMachineServersType params > ajaxGet({url: wholeMachine/serverstype/,params}) // 整机分类 新增 export const wholeMachineServersTypeAdd params > ajaxPost({url: wholeMachine/serverstype/,params}) /…

ESP32 websocket-client

本文简介 ESP-IDF WebSocket-Client 实验平台 ①ESP-IDF 版本&#xff1a;release/v5.3.2 ③硬件平台&#xff1a;esp32-s3 版权声明 ①作者&#xff1a;coLin ②声明&#xff1a;问题总结&#xff0c;有误解&#xff0c;请联系纠正。 正文 1、基于 esp-idf 如何使用 …

【Python爬虫(12)】正则表达式:Python爬虫的进阶利刃

【Python爬虫】专栏简介&#xff1a;本专栏是 Python 爬虫领域的集大成之作&#xff0c;共 100 章节。从 Python 基础语法、爬虫入门知识讲起&#xff0c;深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑&#xff0c;覆盖网页、图片、音频等各类数据爬取&#xff…

网络安全设备防护原理 网络安全防护装置

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 防火墙 简介 网络层的防护设备&#xff0c;依照特殊的规则允许或者限制传输的数据通过 是由软件和硬件设备组合而成&#xff0c;在内部网和外部网之间、专用网…

小结:策略路由(Policy-based Routing,PBR)

在华为设备上&#xff0c;策略路由&#xff08;Policy-based Routing&#xff0c;PBR&#xff09;允许你根据流量的各种特征&#xff08;如源IP、目标IP、源端口、目的端口、协议类型等&#xff09;来选择流量的转发路径。华为的策略路由配置与其他厂商相似&#xff0c;但也有其…

蓝桥杯15 填空题

1.握手问题&#xff1a; 思路&#xff1a;首先当所有人都握过手&#xff0c;由于一次握手相当于两个人都握手过&#xff0c;所以容易发现这是一个组合问题&#xff0c;为&#xff08;50*49&#xff09;/2&#xff0c;而其中有7个人没有相互握过手&#xff0c;那么减去&#xff…

HTML项目一键打包工具:HTML2EXE 最新版

HTML2EXE 工具可以一键打包生成EXE可执行文件。可以打包任意HTML项目或者是一个网址为单个EXE文件&#xff0c;直接打开即可运行。支持KRPano全景VR项目、WebGL游戏项目、视频播放、,课件打包、网址打包等。 一、功能特点 类别序号功能标题1支持程序图标自定义&#xff08;支持…

开启开源新时代:DeepSeek引领人工智能技术开放化

DeepSeek开源周&#xff1a;开启AI共享新时代 摘要 DeepSeek近日通过社交平台X宣布&#xff0c;将于下周启动为期五天的开源活动&#xff0c;每天公开一个核心代码库。这一消息迅速引发热议&#xff0c;被认为是人工智能迈向开放共享时代的关键一步。通过释放技术资源&#xff…

springboot多实例部署时,@Scheduled注释的方法重复执行

问题&#xff1a;springboot多实例部署时&#xff0c;Scheduled注释的方法重复执行 在 Spring Boot 中要实现 Redis 的SET NX EX命令&#xff0c;可以借助 Spring Data Redis 来完成。SET NX EX命令用于在键不存在时设置键值对&#xff0c;并同时设置过期时间。 <dependen…

DeepSeek赋能制造业:图表可视化从入门到精通

一、企业数据可视化之困 在数字化浪潮席卷全球的当下,商贸流通企业作为经济活动的关键枢纽,每天都在与海量数据打交道。从商品的采购、库存管理,到销售渠道的拓展、客户关系的维护,各个环节都源源不断地产生数据。这些数据犹如一座蕴含巨大价值的宝藏,然而,如何挖掘并利用…

紧随“可信数据空间”政策风潮,数造科技正式加入开放数据空间联盟

在全球数字化转型加速的背景下&#xff0c;数造科技凭借前瞻性战略眼光&#xff0c;正式加入开放数据空间联盟&#xff08;ODSA&#xff09;。这一决策&#xff0c;不仅是公司发展历程中的重要一步&#xff0c;更是我们积极响应行业发展趋势&#xff0c;致力于推动数据产业创新…

数学建模之数学模型-1:线性规划

文章目录 线性规划线性规划的基本概念线性规划的数学模型线性规划的标准模型对非标准形式标准化线性规划的典型建模&#xff1a;运输问题数学模型的建立 线性规划 线性规划的基本概念 线性规划问题可以分为两类问题&#xff1a; &#xff08;1&#xff09;如何合理地使用有限…

开源免费文档翻译工具 可支持pdf、word、excel、ppt

项目介绍 今天给大家推荐一个开源的、超实用的免费文档翻译工具&#xff08;DeeplxFile&#xff09;&#xff0c;相信很多人都有需要翻译文档的时刻&#xff0c;这款工具就能轻松解决你的需求。 它支持多种文档格式翻译&#xff0c;包括 Word、PDF、PPT、Excel &#xff0c;使…

Django Admin: 实现基于数据库实际值的动态过滤器

在 Django Admin 中,我们经常需要使用 list_filter 来为管理界面添加过滤功能。然而,有时我们希望过滤器能够动态地反映数据库中的实际值,而不是依赖于预定义的选项。本文将介绍如何实现一个基于数据库实际值的动态过滤器,以 ECR 仓库的区域过滤为例。 问题背景 在管理 E…

巧用GitHub的CICD功能免费打包部署前端项目

近年来&#xff0c;随着前端技术的发展&#xff0c;前端项目的构建和打包过程变得越来越复杂&#xff0c;占用的资源也越来越多。我有一台云服务器&#xff0c;原本打算使用Docker进行部署&#xff0c;以简化操作流程。然而&#xff0c;只要执行sudo docker-compose -f deploy/…

Python之装饰器二 带参数的装饰器

前言一、带参数的装饰器二、在装饰器里面传入参数总结 前言 暂无 一、带参数的装饰器 我们知道&#xff0c;不带参数的装饰其实就是在函数的头上添加装饰器时放一个名称&#xff0c;这种写法就默认了装饰器函数调的是被装饰函数自己&#xff0c;换句话说就是&#xff0c;大家…

Windows 主机与安卓设备网线直连配置教程

在一些特殊场景下&#xff0c;我们可能需要在 Windows 主机没有联网的情况下&#xff0c;与安卓设备通过网线直连进行通信。本文将详细介绍具体的配置步骤。 一、硬件准备 一根网线&#xff08;直通线或交叉线&#xff0c;具体取决于设备接口&#xff09;。 一台支持以太网连…