气压测试实验(用IIC)

news2024/9/24 21:28:52

 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微控制器型号。

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

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

相关文章

Unity3d中制作触发区域为圆形的按钮

一、常规矩形的Button制作 设置Highlighed Color为绿色。 此时当鼠标在button上方时会显示绿色&#xff1a; 二、圆形Button制作 在Button的Image中选择Source Image为Knob。 程序运行时&#xff0c;鼠标在矩形和圆形之间的区域&#xff0c;button还是会变成绿色。 所以&…

【时时三省】(C语言基础)指针进阶 例题5

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 abcdef是个常量字符串 把首地址a放在了p里面 第一个p 算的是指针变量的大小 它打印就是4或者8 第二个p1 p本来是a的地址 1就是b的地址 是地址就是打印四或者八 …

chapter14-集合——(List-LikedHashSet)——day18

目录 528-LikedHashSet介绍 529-LikedHashSet源码介绍 528-LikedHashSet课堂练习 528-LikedHashSet介绍 529-LikedHashSet源码介绍 528-LikedHashSet课堂练习

【计网】从零开始认识网络socket

优于别人&#xff0c;并不高贵&#xff0c; 真正的高贵应该是优于过去的自己。 --- 海明威 --- 从零开始认识网络socket 1 网络通信流程2 IP地址 VS MAC地址3 网络socket3.1 理解源 IP 地址和目的 IP 地址3.2 传输层的典型代表3.3 网络字节序3.4 socket编程基础 1 网络通信流…

高压直流接触器及使用注意事项

高压直流接触器及使用注意事项 1.概述2.接触器和继电器有什么区别3.节能线圈4.安装位置5.直流继电器线圈抑制6.高压继电器和接触器有哪些应用?7.线圈效率的决定因素是什么?对线圈驱动器有什么要求?8.负载极性对接触器的影响9.触点参数注意事项10.线圈供电要求1.概述 航空接…

基于单片机实现的的多点分布室内环境监测系统

基于STM32单片机为基础设计的一款室内环境监测系统程序源码 程序分为接收端和采集端两部分 接收端与采集端均以STM32单片机作为控制核心&#xff0c;两者通过ZigBee无线通信技术进行连接。接收端主要用于接收数据并将其实时显示以及报警。 采集端主要用于监测室内环境的各类数…

【Python工具】Python 装饰器实现统计函数执行时长

文章目录 1、背景2、轮子 1、背景 业务基本代码堆积完毕了&#xff0c;部分流程需要调优&#xff0c;想着在几个关键执行路径上进行时间记录&#xff0c;类似 SQL 慢日志一样的方法&#xff0c;方便进行性能问题发现。 了解了下&#xff0c;应该是采用装饰器实现是代码侵入最…

林草湿地址、导出echart为word

2.导出 // 导出exportDoc () {this.loading truelet arrRefs [this.$refs.endChart, this.$refs.processChart, this.$refs.officeEndChart]setTimeout(() > {Promise.all(arrRefs.map((canvasDom) > {return this.html2canvasHandle(canvasDom)})).then(res > {let…

如何让潜意识帮你实现你的目标

潜意识的力量是意识的3万倍以上 如果你有一个宏大的目标&#xff0c;怎么借助潜意识实现你的目标呢 比如&#xff0c;我的目标是&#xff1a;帮助100万人颠覆潜意识&#xff0c;实现人生蜕变&#xff0c;并且培养一万名潜意识开发导师 这么宏大的一个目标&#xff0c;怎么让…

B-树底层原理

一、B-树介绍 定义&#xff1a; B-树&#xff08;B-Tree&#xff09;是一种自平衡的树形数据结构&#xff0c;广泛应用于数据库和操作系统中。它的设计目标是减少搜索、顺序访问、插入和删除操作中比较次数和移动次数&#xff0c;特别适合于磁盘中数据的存储和检索。 性质&a…

运维团队日志管理策略参考

在运维工作中&#xff0c;日志管理是一项至关重要的任务。有效的日志管理不仅能够帮助运维团队实时监控系统状态、发现潜在问题&#xff0c;还能为故障排查和系统性能优化提供宝贵的数据支持。本文结合运维行业的实际需求&#xff0c;介绍了一套全面的日志管理策略&#xff0c;…

AutoDroid: LLM-powered Task Automation inAndroid论文学习

光看题目怎么和上一篇差不多&#xff1f;又是纯用LLM的&#xff1f; 当然还是有一点不一样的&#xff1a; 这里的最大特点是加上了UI领域知识&#xff0c;可以大幅增强LLM在处理UI方面的知识的能力。根据文章的说法&#xff0c;使用了这招他们的LLM可以吊打GPT4V&#xff0c;准…

node.js 完全卸载和下载配置

一、介绍 &#xff08;1&#xff09;node.js Node.js发布于2009年5月&#xff0c;由Ryan Dahl开发&#xff0c;是一个基于ChromeV8引擎的JavaScript运行环境&#xff0c;使用了一个事件驱动、非阻塞式I/O模型&#xff0c; [1]让JavaScript 运行在服务端的开发平台&#xff0c…

Linux开发工具的使用

文章目录 vim的使用基本模式介绍光标当前行操作光标快速定位&#xff08;命令行模式&#xff09;&#xff1a;插入模式的三种方式&#xff08;命令行模式&#xff09;&#xff1a;vim基本操作&#xff08;命令行模式&#xff09;底行模式的操作 Linux编译器 - gcc/g的使用Linux…

录屏软件免费版:四款热门工具全面解析!

日常生活或工作中&#xff0c;我们经常有记录屏幕的需求。今天&#xff0c;就让我们来探索几款市面上广受欢迎的免费录屏软件&#xff0c;它们不仅功能强大&#xff0c;而且完全免费&#xff0c;让屏幕录制体验更加流畅和高效。 福昕录屏大师 直达链接&#xff1a;www.foxits…

比亚迪海豹06这油耗,丈母娘都叫好

文 | AUTO芯球 作者 | 雷慢 刚一朋友问我 有没有什么好看、价格低&#xff0c; 车大、油耗还低的车&#xff0c; 开到女盆友家能第一个动筷子。 哎&#xff0c;我要给你说的这车&#xff0c; 能不能第一个动筷子 首先看你未来的丈母娘喜欢什么货色的&#xff0c; 其次你…

仿最近老火的羊了个羊 三消游戏源码,两种玩法模式,完整带后台

游戏玩儿法类似于养了个羊&#xff0c;有两种模式&#xff0c;一个是普通版。一个是王者荣耀版。 代码免费下载&#xff1a;百度网盘

广播与组播,超时检测

目录 一.超时检测 必要性 超时检测的设置方法 1. 通过函数自带的参数设置 2. 通过设置套接字属性进行设置 3. alarm函数与sigaction函数结合 二.广播与组播&#xff08;broadcast & multicast&#xff09; 1. 广播&#xff08;udp&#xff09; 理论&#xff1a…

redis底层—网络模型

1.用户空间和内核空间 2.阻塞IO 3.非阻塞IO 4.IO多路复用 select模式的三个问题&#xff1a; 能监听的FD最大不超过1024 每次select都需要把所有要监听的FD都拷贝到内核空间 每次都要遍历所有FD来判断就绪状态 poll模式的问题&#xff1a; poll利用链表解决了select中监听FD上限…

信号保存和处理

把上一篇回顾一下吧&#xff1a;共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到内核&#xff0c;进程不再通过执行进入内核的系统调用来传递彼此的数据 共享内存的数据结构&#xff1a; struct shmid_ds {…