气压测试实验(用IIC)

 I2C:

如果没有I2c这类总线,连接方法可能会如下图:

        单片机所有的通讯协议,无非是建立在引脚(高低电平的变换+高低电平持续的时间)这二者的组合上,i2c 多了一个clock线,负责为数据传输打节拍。

(i2c 传输数据的格式--读数据)

BMP180:

        BMP180是一款由德国博世(Bosch Sensortec)公司开发的高精度数字气压和温度传感器。它采用微电子机械系统(MEMS)技术,能够准确测量大气压力和温度,并具有低功耗、小尺寸、高稳定性的特点。BMP180通过I2C接口与微控制器或单片机通信,提供的气压和温度数据可用于气象观测、气候研究、天气预报、高度测量等多个领域。此外,BMP180还具有温度补偿功能,能减少温度对气压测量的影响,确保测量数据的准确性。

 (接线图)

 arduion 中:我们用如下这个lib:

 example code:

#include <Adafruit_BMP085.h>

/*************************************************** 
  This is an example for the BMP085 Barometric Pressure & Temp Sensor

  Designed specifically to work with the Adafruit BMP085 Breakout 
  ----> https://www.adafruit.com/products/391

  These pressure and temperature sensors use I2C to communicate, 2 pins
  are required to interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here

Adafruit_BMP085 bmp;
  
void setup() {
  Serial.begin(9600);
  if (!bmp.begin()) {
	Serial.println("Could not find a valid BMP085 sensor, check wiring!");
	while (1) {}
  }
}
  
void loop() {
    Serial.print("Temperature = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Pressure = ");
    Serial.print(bmp.readPressure());
    Serial.println(" Pa");
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" meters");

    Serial.print("Pressure at sealevel (calculated) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.println(" Pa");

  // you can get a more precise measurement of altitude
  // if you know the current sea level pressure which will
  // vary with weather and such. If it is 1015 millibars
  // that is equal to 101500 Pascals.
    Serial.print("Real altitude = ");
    Serial.print(bmp.readAltitude(101500));
    Serial.println(" meters");
    
    Serial.println();
    delay(500);
}

代码说明: 

        这段代码是使用Arduino平台编写的,旨在与Adafruit的BMP085气压和温度传感器进行交互,以读取温度、压力、以及基于这些值计算出的海拔。不过,请注意,虽然代码示例中使用了Adafruit_BMP085 bmp;来声明对象,但BMP085和BMP180在功能上是相似的,只是不同型号,且BMP085是较旧的型号。Adafruit的库通常能够很好地处理这两种传感器,但具体使用哪个型号取决于你连接的实际传感器。

下面是代码的详细解释:

初始化

  • Serial.begin(9600);:初始化串口通信,设置波特率为9600。

  • if (!bmp.begin()) {...}:尝试与BMP085传感器建立通信。如果bmp.begin()返回false(即!bmp.begin()true),则表示无法找到有效的BMP085传感器,可能是接线错误或传感器未正确连接。此时,程序会打印一条错误消息并进入无限循环。

循环

loop()函数中,程序会不断循环执行以下操作:

  1. 读取温度:使用bmp.readTemperature()函数读取当前温度(以摄氏度为单位),并通过串口输出。

  2. 读取压力:使用bmp.readPressure()函数读取当前大气压力(以帕斯卡为单位),并通过串口输出。

  3. 计算海拔

    • 首先,使用bmp.readAltitude()函数计算基于当前气压和标准海平面气压(默认为101325 Pa)的海拔。注意,这个计算假设了海平面气压是一个固定值,但在实际中,它可能会因天气等因素而变化。

    • 然后,通过bmp.readAltitude(101500)函数,可以提供一个更准确的海拔值,这要求你知道当前的海平面气压(在这个例子中为101500 Pa,即1015毫巴)。

  4. 计算海平面压力(基于当前气压和海拔):虽然这个功能在代码中直接调用bmp.readSealevelPressure()似乎是为了展示或计算某个值,但实际上,这个函数的使用场景可能是在你已经有了某个地点的海拔和当前气压,想要推算出该地点在海平面的气压值。不过,在这个循环的上下文中,它可能并不是特别有用,因为我们已经有了当前的气压值。

  5. 延时delay(500);使得每次循环之间有500毫秒的延时,以减少串口输出的速度,使数据更易于阅读。

注意事项

  • 确保你的Arduino与BMP085(或BMP180)传感器正确连接,包括电源线、地线以及I2C通信线(SCL和SDA)。

  • 如果你使用的是BMP180而不是BMP085,但Adafruit库支持两者,那么代码应该能够正常工作,无需修改。

  • 海拔的计算是基于气压的,而气压会受到天气、海拔等多种因素的影响,因此计算出的海拔值可能只是一个近似值。

stm32 单片机上,IIC 编程:

STM32使用I2C通讯的步骤可以归纳如下,这些步骤主要基于STM32CubeIDE或STM32CubeMX等工具进行配置,并结合HAL库函数实现通信。

1. 硬件连接

  • 确保STM32的I2C引脚(通常为SCL和SDA)正确连接到目标外设的相应引脚。

  • 在I2C总线上添加适当的上拉电阻(通常为4.7kΩ),以确保总线在空闲时保持高电平状态。

2. 配置STM32CubeIDE或STM32CubeMX

  • 创建新项目:打开STM32CubeIDE或STM32CubeMX,创建一个新的项目,并选择合适的STM32微控制器型号。

  • 配置I2C外设

    • 在“Pinout & Configuration”选项卡中,找到并选择I2C外设,为其分配正确的引脚(如PB6作为SCL,PB7作为SDA)。

    • 在“Configuration”选项卡中,设置I2C的时钟源、时钟速率、工作模式等参数。通常,时钟速率可以根据需要设置为100kHz或400kHz。

3. 初始化I2C外设

  • 在STM32CubeIDE中,通过STM32CubeMX生成的初始化代码,使用HAL_I2C_Init()函数初始化I2C外设。

  • 配置I2C_HandleTypeDef结构体,包括I2C实例、时钟参数、本地地址等。

4. 编写通信代码

  • 发送数据:使用HAL_I2C_Master_Transmit()HAL_I2C_Mem_Write()函数向从设备发送数据。需要指定从设备地址、寄存器地址(如果需要的话)和数据。

  • 接收数据:使用HAL_I2C_Master_Receive()HAL_I2C_Mem_Read()函数从从设备接收数据。同样需要指定从设备地址、寄存器地址(如果需要的话)和数据缓冲区。

5. 错误处理

  • 在通信过程中,可能会遇到各种错误,如总线忙、应答失败等。使用HAL_I2C_GetError()函数检查错误状态,并根据需要进行处理。

示例代码

以下是一个简化的示例,展示了如何在STM32中初始化I2C外设并发送数据:

#include "stm32f4xx_hal.h"  
  
I2C_HandleTypeDef hi2c1;  
  
void I2C1_Init(void) {  
    hi2c1.Instance = I2C1;  
    hi2c1.Init.ClockSpeed = 400000; // 400kHz  
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;  
    hi2c1.Init.OwnAddress1 = 0;  
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;  
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;  
    hi2c1.Init.OwnAddress2 = 0;  
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;  
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;  
    HAL_I2C_Init(&hi2c1);  
}  
  
void I2C_SendData(uint8_t slaveAddr, uint8_t regAddr, uint8_t data) {  
    HAL_I2C_Mem_Write(&hi2c1, slaveAddr << 1, regAddr, I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY);  
}  
  
int main(void) {  
    HAL_Init();  
    I2C1_Init();  
  
    uint8_t slaveAddr = 0x50; // 假设的从设备地址  
    uint8_t regAddr = 0x00; // 寄存器地址  
    uint8_t data = 0xAA; // 要发送的数据  
  
    I2C_SendData(slaveAddr, regAddr, data);  
  
    // 其他代码...  
}

注意:上述代码是一个简化的示例,用于说明如何初始化I2C外设并发送数据。在实际应用中,您可能需要根据具体的硬件和需求进行调整。特别是从设备地址、寄存器地址和数据长度等参数,需要根据您连接的外设来确定。

此外,HAL_I2C_Mem_Write()函数中的从设备地址需要左移一位(并可选地添加读写位),因为I2C协议中的地址是7位或10位的,但在发送时通常会左移一位以在最低位添加读写位(0为写,1为读)。然而,在大多数情况下,当使用HAL_I2C_Mem_Write()HAL_I2C_Mem_Read()函数时,库函数已经处理了这一位的添加,因此您只需提供7位或10位的从设备地址即可(但通常需要左移一位以确保与库的期望相匹配)。如果库函数要求您提供8位地址,并且您的设备是7位地址,那么您应该手动将7位地址左移一位。如果库函数已经处理了这一点,那么您就不需要再次左移。在上述示例中,我假设了HAL_I2C_Mem_Write()函数需要8位地址,并且已经通过左移一位来添加了读写位(尽管在这个写操作的上下文中,读写位是0)。但是,请注意,这取决于您使用的具体HAL库版本和您的STM32微控制器型号。

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

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

相关文章

如何删除git提交记录

今天在提交github时&#xff0c;不小心提交了敏感信息&#xff0c; 不要问我提交了啥&#xff0c;问就是不知道 查了下资料&#xff0c;终于找到简单粗暴的方式来删除提交记录。方法如下 git reset --soft HEAD~i i代表要恢复到多少次提交前的状态&#xff0c;如指定i 2&…

一文读懂:如何将广告融入大型语言模型(LLM)输出

本文是我翻译过来的&#xff0c;讨论了在线广告行业的现状以及如何将大型语言模型&#xff08;LLM&#xff09;应用于在线广告。 原文请参见”阅读原文“。 在2024年&#xff0c;预计全球媒体广告支出的69%将流向数字广告市场。这个数字预计到2029年将增长到79%。在Meta的2024…

微服务——网关路由(Spring Cloud Gateway)

网关路由 1.什么是网关 网关又称网间连接器、协议转换器&#xff0c;是在网络层以上实现网络互连的复杂设备&#xff0c;主要用于两个高层协议不同的网络之间的互连。网关就是网络的关口。数据在网络间传输&#xff0c;从一个网络传输到另一网络时就需要经过网关来做数据的路由…

Kafka 基础与架构理解

目录 前言 Kafka 基础概念 消息队列简介&#xff1a;Kafka 与传统消息队列&#xff08;如 RabbitMQ、ActiveMQ&#xff09;的对比 Kafka 的组件 Kafka 的工作原理&#xff1a;消息的生产、分发、消费流程 Kafka 系统架构 Kafka 的分布式架构设计 Leader-Follower 机制与…

安卓玩机工具-----无需root权限 卸载 禁用 删除当前机型app应用 ADB玩机工具

ADB玩机工具 ADB AppControl是很实用的安卓手机应用管理工具&#xff0c;无需root权限&#xff0c;通过usb连接电脑后&#xff0c;可以很方便的进行应用程序安装与卸载&#xff0c;还支持提取手机应用apk文件到电脑上&#xff0c;此外还有手机系统垃圾清理、上传文件等…

VMware Workstation Player虚拟机Ubuntu启用Windows共享目录

1、新建共享目录 2、安装并启用vmtools、fuse sudo apt update sudo apt install open-vm-tools open-vm-tools-desktop sudo apt install fuse sudo systemctl start open-vm-tools sudo systemctl enable open-vm-tools 3、命令挂载 sudo vmhgfs-fuse .host:/SharedFold…

初学Linux(学习笔记)

初学Linux&#xff08;学习笔记&#xff09; 前言 本文跳过了Linux前期的环境准备&#xff0c;直接从知识点和指令开始。 知识点&#xff1a; 1.目录文件夹&#xff08;Windows&#xff09; 2.文件内容属性 3.在Windows当中区分文件类型是通过后缀&#xff0c;而Linux是通过…

leaflet【十】实时增加轨迹点轨迹回放效果实现

实时轨迹回放 在前面有用leaflet-trackplayer实现了一个轨迹回放的效果&#xff0c;单击前往&#xff1a;轨迹回放效果&控制台控制轨迹运动效果 这篇文章主要是实现一下实时增加轨迹点&#xff0c;不改变原来运行轨迹和速度。这里是简易做了一个demo效果&#xff0c;大概…

vue3透传、注入

属性透传 传递给子组件时&#xff0c;没有被子组件消费的属性或事件&#xff0c;常见的如id、class 注意1 1.class、style是合并的&#xff0c;style中如果出现重复的样式&#xff0c;以透传属性为准2.id属性是以透传属性为准&#xff0c;其他情况透传属性名相同&#xff0c…

【AI视频】复刻抖音爆款AI数字人作品初体验

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI视频 | AI数字人 文章目录 &#x1f4af;前言&#x1f4af;抖音上的爆火AI数字人视频&#x1f4af;注册HeyGen账号&#x1f4af;复刻抖音爆款AI数字人&#x1f4af;最终生成效果&#x1f4af;小结 对比原视频效果&#xff1a;…

【算法篇】哈希类(笔记)

目录 一、常见的三种哈希结构 二、LeetCode 练习 1. 有效的字母异位词 2. 两个数组的交集 3. 快乐数 4. 两数之和 5. 四数相加II 6. 赎金信 7. 三数之和 8. 四数之和 一、常见的三种哈希结构 当想使用哈希法来解决问题的时候&#xff0c;一般会选择如下三种数据…

Java--String类

前言&#xff1a; 在之前的学习中&#xff0c;学习了和了解了一些类的基本使用&#xff0c;例如object类等等&#xff0c;但是我们用String这个引用或者说这个类其实我们已经用了好久&#xff0c;只不过没有具体分析过&#xff01; 对于String类&#xff0c;它可以引用一个字符…

JavaScript web API part3

web API DOM 日期对象 > 得到当前系统的时间 new这个操作就是实例化 语法 const date new Date() or const date new Date(2004-11-3 08:00:00) 可以指定时间 > 可应用于通过系统时间和指定时间实现倒计时的操作 //得到当前时间const date new Date()console.lo…

【Python小知识 - 2】:在VSCode中切换Python解释器版本

文章目录 在VSCode中切换Python解释器版本 在VSCode中切换Python解释器版本 在VSCode中按下快捷键CtrlShiftP&#xff0c;出现命令框。 输入以下命令&#xff1a; Python: Select Interpreter输入命令回车后即出现不同的Python解释器选项&#xff0c;选择想要切换的Python解释器…

【题解】—— LeetCode一周小结37

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结36 9.合并零之间的节点 题目链接&#xff1a;2181. 合并零之间…

【最新综述】基于深度学习的超声自动无损检测(下)

4.Levels of automation 5.Basic axioms for DL-based ultrasonic NDE 在回顾了最新技术和每个自动化级别的贡献之后&#xff0c;我们不难发现&#xff0c;目前的数字语言方法论在不同论文之间存在着很大的差异。例如&#xff0c;有些作者提出了同时处理不同步骤的模型[121]&…

感知器神经网络

1、原理 感知器是一种前馈人工神经网络&#xff0c;是人工神经网络中的一种典型结构。感知器具有分层结构&#xff0c;信息从输入层进入网络&#xff0c;逐层向前传递至输出层。根据感知器神经元变换函数、隐层数以及权值调整规则的不同&#xff0c;可以形成具有各种功能特点的…

Java并发常见面试题(上)

Java并发常见面试题(上) 什么是线程和进程? 一个 Java 程序的运行是 main 线程和多个其他线程同时运行 进程:程序的一次执行过程&#xff0c;系统运行一个程序就是一个进程从创建&#xff0c;运行到消亡的过程。在Java中启动main函数就是开启一个进程&#xff0c;main函数所…

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统 在产品将要上线之前&#xff0c;需要制作不同类型格式的根文件系统 在产品研发阶段&#xff0c;我们还是需要使用nfs的方式挂载根文件系统 优点&#xff1a;可以直接在上位机中修改文件系统内容&#xff0c;延长EMMC的寿命 【1】重启上位机nfs服…

WPF利用Path自定义画头部导航条(TOP)样式

1;新建两个多值转换器&#xff0c;都有用处&#xff0c;用来动态确定PATH的X,Y州坐标的。 EndPointConverter 该转换器主要用来动态确定X轴&#xff0c;和Y轴。用于画线条的。 internal class EndPointConverter : IMultiValueConverter {public object Convert(object[] val…