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温湿度传感器的控制与数据采集,具备以下功能:
- 初始化I2C总线,配置STM32F1系列微控制器。
- 读取传感器的温度和湿度数据,并进行必要的计算,转换为实际的物理量。
读取传感器的制造商ID和设备ID,用于设备验证。
【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);
}
相关文章:

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…...

【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调【完整教程】
文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.3.1 zero-1微调2.2.3.2 zero-2微调2.2.3.3 zero-3微调2.2.3.4 单卡Lora微调 2.2.4 实验2.2.4.1 实验1:多GPU微调-zero12.2.4.2 实验2:…...

浏览器报错:无法访问此网站 无法找到xxx.xxx.net的DNS地址。正在诊断该问题。尝试运行Windows网络诊断。DNS_PROBE_STARTED
🤟致敬读者 🟩感谢阅读🟦希望我的文章能帮到您🟪如有兴趣可点关注了解更多内容 📘博主信息 点击标题👆有惊喜 📃文章前言 🔷文章均为学习和工作中整理的笔记,分享记录…...

【设计模式】 代理模式(静态代理、动态代理{JDK动态代理、JDK动态代理与CGLIB动态代理的区别})
代理模式 代理模式是一种结构型设计模式,它提供了一种替代访问的方法,即通过代理对象来间接访问目标对象。代理模式可以在不改变原始类代码的情况下,增加额外的功能,如权限控制、日志记录等。 静态代理 静态代理是指创建的或特…...
网络安全-攻击流程-用户层
用户层攻击主要针对操作系统中的用户空间应用程序及用户权限,利用软件漏洞、配置错误或用户行为弱点进行攻击。以下是常见的用户层攻击类型及其流程,以及防御措施: 1. 缓冲区溢出攻击 攻击流程: 目标识别:确定存在漏…...

网络安全等级保护测评(等保测评):全面指南与准备要点
等保测评,全称为“网络安全等级保护测评”,是根据《网络安全法》及《网络安全等级保护条例》等法律法规,对信息系统进行安全等级划分,并依据不同等级的安全保护要求,采用科学方法和技术手段,全面评估信息系…...

具身导航赋能智能物流!OpenBench:智能物流最后一公里语义导航新基准
作者:Junhui Wang, Dongjie Huo, Zehui Xu, Yongliang Shi, Yimin Yan, Yuanxin Wang, Chao Gao, Yan Qiao, Guyue Zhou 单位:澳门科技大学系统工程与协作实验室、智能科学与系统联合实验室,清华大学人工智能产业研究院(AIR&…...

详解 本机安装多个MySQL服务【为后续大数据量分库分表奠定基础,以mysql8.0为例,附有图文】
本机安装多个mysql 在电脑上新建mysql8文件夹,然后在mysql8文件下新建mysql3391文件夹。然后找到自己原本mysql的安装目录,我的是E:\software\mysql\one,如图所示: 将次目录下的所有文件全选复制粘贴在mysql3391文件夹下。 然后…...

2025年新趋势:如何利用AI技术优化你的在线帮助中心
在2025年的今天,人工智能(AI)技术正以惊人的速度改变着我们的世界。从自动驾驶汽车到智能家居,从医疗诊断到金融分析,AI的身影无处不在。而在客户服务领域,AI同样正在发挥着越来越重要的作用。特别是在线帮…...

同花顺Java开发面试题及参考答案 (上)
int 类型占用几个字节?float 类型的数字如何与 0 进行比较? 在 Java 中,int 类型是一种基本数据类型,它占用 4 个字节。一个字节有 8 位,所以 int 类型总共是 32 位。这 32 位可以用来表示不同的整数值,其取…...

CommonLang3-使用介绍
摘自:https://www.cnblogs.com/haicheng92/p/18721636 学习要带着目的,参照现实问题 本次目标: 了解 CommonsLang3 API 文档,找对路后以后开发直接查询 API 文档,摈弃盲目的百度掌握基础的字符串、日期、数值等工具…...
Java常用设计模式及其应用场景
1. 什么是设计模式? 设计模式是一个经过多次验证的、针对常见问题的可复用解决方案。设计模式并不是具体的代码实现,而是给出了如何解决问题的思路和结构。在实际开发过程中,设计模式有助于开发者快速找到合适的解决方案,从而减少…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pnalloc函数
ngx_pnalloc 声明在 src\core\ngx_palloc.h void *ngx_pnalloc(ngx_pool_t *pool, size_t size); 定义在 src\core\ngx_palloc.c void * ngx_pnalloc(ngx_pool_t *pool, size_t size) { #if !(NGX_DEBUG_PALLOC)if (size < pool->max) {return ngx_palloc_small(pool, …...
【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析①】
ISO 14229-1:2023 UDS诊断【会话控制0x10服务】_TestCase01 作者:车端域控测试工程师 更新日期:2025年02月14日 关键词:UDS诊断、0x10服务、诊断会话控制、ECU测试、ISO 14229-1:2023 TC10-001测试用例 用例ID测试场景验证要点参考条款预期…...

A与B组件自动对齐与组装,无映射直接补偿。
网上针对组装的从视觉到控制动作,要不就是收费,要不就是简单介绍。这么详细的比较难找~ 手下留情,不喜勿喷! Show time~ 分步解决方案: 标定阶段(Calibration) 9点张氏标定(每个位置A1、A2、B1、B2): 使用机械手在相机视野内沿Z字形路径移动,覆盖9个点(XY方…...

QT 读写锁
一、概述 1、读写锁是一种线程同步机制,用于解决多线程环境下的读写竞争问题。 2、读写锁允许多个线程同时获取读锁(共享访问),但只允许一个线程获取写锁(独占访问)。 3、这种机制可以提高并发性能&…...
C++ 的时间库之二:Ratio
从现在开始,我们开始介绍 C 风格的时间处理,在这之前,首先要介绍std::ratio。因为 C 的 chrono库中的时间段(duration)定义离不开std::ratio,不了解std::ratio,就很难理解duration的定义。 1 st…...

使用小雅xiaoya/Emby正确的观看电影电视剧的姿势
最近有很多小伙伴来咨询关于小雅Emby全家桶的使用问题,最常见的就是在Emby上搜索出来资源之后,点击播放会提示【播放错误】,当前没有兼容的流。 这可把很多小伙伴给急坏了……于是找到小白咨询。 嗯……怎么说呢?小白并不喜欢看电…...
Java状态机
目录 1. 概念 2. 定义状态机 3. 生成一个状态机 4. 使用 1. 概念 在Java的应用开发里面,应该会有不少的人接触到一个业务场景下,一个数据的状态会发生多种变化,最经典的例子例如订单,当然还有像用户的状态变化(冻结…...
【Pandas】pandas Series isin
Pandas2.2 Series Computations descriptive stats 方法描述Series.align(other[, join, axis, level, …])用于将两个 Series 对齐,使其具有相同的索引Series.case_when(caselist)用于根据条件列表对 Series 中的元素进行条件判断并返回相应的值Series.drop([lab…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...