MS5611气压计数据采集(模拟IIC)/温度采集/相对高度求解
MS5611气压计数据采集(模拟IIC)/温度采集/相对高度求解
1、 MS5611气压计属性
1.1 基础属性
MS5611使用24位ADC,可以采集温度和气压,并且温度可以用来补偿气压,MS5611在出厂时进行了校准,校准的6个系数存储在PROM寄存器中, PROM寄存器起始地址0XA0, 从0xA0到0XAE, 一共16字节, 一共16*8 = 128位,其中每两个字节为一个系数:
第一个系数: 制造商定的,我们不用在意
第二到第七个系数:我们需要读取,后面用于气压计算
第八个系数:CRC
1.2 5个命令(COMMANDS)
分别是:
1、复位
2、读取PROM
3、D1转换, 其实就是设置读取气压的一些参数,然后MS5611会返回24字节(下文会说明)
4、D2转换,其实就是设置读取温度的一些参数
5、读取ADC中的数据
1.3 SPI和IIC接口
IIC模式:PS拉高
SPI模式:PS拉低
本实验用的是模拟IIC读取数据
IIC模式中CSB拉低时, IIC从设备地址为0111 0111, CSB拉高时,IIC设备地址为0111 0110
2、 温度气压读取
IIC开始、结束、等待ack、读取发送函数等(参考匿名)
#define MS5611_ADDR 0x77 //0xee //
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC OSR=256
#define CMD_ADC_512 0x02 // ADC OSR=512
#define CMD_ADC_1024 0x04 // ADC OSR=1024
#define CMD_ADC_2048 0x06 // ADC OSR=2048
#define CMD_ADC_4096 0x08 // ADC OSR=4096
#define CMD_PROM_RD 0xA0 // Prom read command
#define PROM_NB 8
#define MS5611_OSR 0x08 //CMD_ADC_4096//开始信号
int I2c_Soft_Start()
{MS5611_IIC_SDA = 1;MS5611_IIC_SCL = 1;delay_us(4);if(!MS5611_READ_SDA)return 0; //SDA线为低电平则总线忙,退出MS5611_IIC_SDA = 0;delay_us(4);if(MS5611_READ_SDA) return 0; //SDA线为高电平则总线出错,退出MS5611_IIC_SDA = 0;delay_us(4);return 1; }
//结束信号
void I2c_Soft_Stop()
{MS5611_IIC_SCL = 0;delay_us(4);MS5611_IIC_SDA = 0;delay_us(4);MS5611_IIC_SCL = 1;delay_us(4);MS5611_IIC_SDA = 1;delay_us(4);
}
//应答
void I2c_Soft_Ask()
{MS5611_IIC_SCL = 0;delay_us(4);MS5611_IIC_SDA = 0;delay_us(4);MS5611_IIC_SCL = 1;delay_us(4);MS5611_IIC_SCL = 0;delay_us(4);
}
//非应答
void I2c_Soft_NoAsk()
{MS5611_IIC_SCL = 0;delay_us(4);MS5611_IIC_SDA = 1;delay_us(4);MS5611_IIC_SCL = 1;delay_us(4);MS5611_IIC_SCL = 0;delay_us(4);
}
// 等待回复
int I2c_Soft_WaitAsk(void) //返回为:=1无ASK,=0有ASK
{u8 ErrTime = 0;MS5611_IIC_SCL = 0;delay_us(4);MS5611_IIC_SDA = 1; delay_us(4);MS5611_IIC_SCL = 1;delay_us(4);while(MS5611_READ_SDA){ErrTime++;if(ErrTime>50){I2c_Soft_Stop();return 1;}}MS5611_IIC_SCL = 0;delay_us(4);return 0;
}// IIC发送一个字节
void I2c_Soft_SendByte(u8 SendByte) //数据从高位到低位//
{u8 i=8;while(i--){MS5611_IIC_SCL = 0;delay_us(4);if(SendByte&0x80)MS5611_IIC_SDA = 1; else MS5611_IIC_SDA = 0; SendByte<<=1;delay_us(4);MS5611_IIC_SCL = 1;delay_us(4);}MS5611_IIC_SCL = 0;
} //读1个字节,ack=1时,发送ACK,ack=0,发送NACK
u8 I2c_Soft_ReadByte(u8 ask) //数据从高位到低位//
{ u8 i=8;u8 ReceiveByte=0;MS5611_IIC_SDA = 1; while(i--){ReceiveByte<<=1; MS5611_IIC_SCL = 0;delay_us(4);MS5611_IIC_SCL = 1;delay_us(4); if(MS5611_READ_SDA){ReceiveByte|=0x01;}}MS5611_IIC_SCL = 0;if (ask)I2c_Soft_Ask();elseI2c_Soft_NoAsk(); return ReceiveByte;
} // IIC写一个字节数据
u8 IIC_Write_1Byte(u8 SlaveAddress,u8 REG_Address,u8 REG_data)
{I2c_Soft_Start();I2c_Soft_SendByte(SlaveAddress<<1); if(I2c_Soft_WaitAsk()){I2c_Soft_Stop();return 1;}I2c_Soft_SendByte(REG_Address); I2c_Soft_WaitAsk(); I2c_Soft_SendByte(REG_data);I2c_Soft_WaitAsk(); I2c_Soft_Stop(); return 0;
}// IIC读1字节数据
u8 IIC_Read_1Byte(u8 SlaveAddress,u8 REG_Address,u8 *REG_data)
{ I2c_Soft_Start();I2c_Soft_SendByte(SlaveAddress<<1); if(I2c_Soft_WaitAsk()){I2c_Soft_Stop();return 1;}I2c_Soft_SendByte(REG_Address); I2c_Soft_WaitAsk();I2c_Soft_Start();I2c_Soft_SendByte(SlaveAddress<<1 | 0x01);I2c_Soft_WaitAsk();*REG_data= I2c_Soft_ReadByte(0);I2c_Soft_Stop();return 0;
}
2.1 第一步:初始化MS5611
初始化包括:
1、复位
2、读取PROM中的6个关键系数
// 复位
void MS5611_Reset(void)
{// MS5611_ADDR:0x77 CMD_RESET:0x1EIIC_Write_1Byte(MS5611_ADDR, CMD_RESET, 1);
}
u8 MS5611_Read_Prom(void)
{uint8_t rxbuf[2] = { 0, 0 };u8 check = 0;u8 i;for (i = 0; i < PROM_NB; i++){check += IIC_Read_nByte(MS5611_ADDR, CMD_PROM_RD + i * 2, 2, rxbuf); // send PROM READ commandms5611_prom[i] = rxbuf[0] << 8 | rxbuf[1];}if(check == PROM_NB)return 1;elsereturn 0;
}
2.2 第二步:获取温度数据
首先发送Convert D1命令,进行相应的配置,再发送ADC Read命令,然后MS5611会返回24位的温度数据, 这时候再去读取这些温度数据。
// 写入数据
void MS5611_Start_T(void)
{//CMD_ADC_CONV + CMD_ADC_D2 + MS5611_OSR = 0x48IIC_Write_1Byte(MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D2 + MS5611_OSR, 1); // D2 (temperature) conversion start!
}
// 读取24位温度数据
void MS5611_Read_Adc_T(void)
{IIC_Read_nByte( MS5611_ADDR, CMD_ADC_READ, 3, t_rxbuf ); // read ADC
}
2.3 第三步:获取气压数据
首先发送Convert D2命令,进行相应的配置,然后再发送ADC Read命令, 然后MS5611会返回24位的气压数据, 这时候再去读取这些气压数据。
// 写入数据
void MS5611_Start_P(void)
{CMD_ADC_CONV + CMD_ADC_D1 + MS5611_OSR = 0x58IIC_Write_1Byte(MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D1 + MS5611_OSR, 1); // D1 (pressure) conversion start!
}
// 读取24位气压数据
void MS5611_Read_Adc_P(void)
{IIC_Read_nByte(MS5611_ADDR, CMD_ADC_READ, 3, p_rxbuf); // read ADC
}
3、温度补偿气压
绝对高度(海拔)的求解公式:
H= 44300*(1- (P/P0)^(1/5.256) )
H为高度
P0为标准大气压(≈101Kpa)
P为读取的气压 (注意单位得和P0相同)
相对高度(例如飞机起飞前和飞行中的高度差)的求解
这里提供一个思路:
MS5611开机上电一段时间后,读取静止100组数据并转换成海拔,取个平均,这个海拔高度就相当于基准海拔,如果你把MS5611拿高或者拿低, 此时的海拔与基准海拔相见就是相对高度。
ps:求相对高度的时候,可以对此时的海拔高度数据进行一个滑动窗滤波,这样求出的相对高度比较平滑。
void MS5611_BaroAltCalculate(void)
{float height = 0;int64_t off2 = 0, sens2 = 0, delt = 0, f = 0, f2 = 0;int32_t temperature = 0, pressure = 0, T2 = 0;int32_t dT = 0;int64_t off =0, sens =0;static int num = 0;static int cnt = 0;double ms5611SumDat = 0.0;ms5611_ut = (t_rxbuf[0] << 16) | (t_rxbuf[1] << 8) | t_rxbuf[2]; // 读取的原始温度值ms5611_up = (p_rxbuf[0] << 16) | (p_rxbuf[1] << 8) | p_rxbuf[2]; // 读取的原始气压值dT = ms5611_ut - ((uint32_t)ms5611_prom[5] << 8);off = ((uint64_t)ms5611_prom[2] << 16) + (((int64_t)dT * ms5611_prom[4]) >> 7);sens = ((uint64_t)ms5611_prom[1] << 15) + (((int64_t)dT * ms5611_prom[3]) >> 8);// 实际温度: 2007:20.07 ℃temperature = 2000 + (((int64_t)dT * ms5611_prom[6]) >> 23); if (temperature < 2000) { T2 = (dT*dT)>>31;delt = temperature - 2000;delt = delt * delt;off2 = (5 * delt) >> 1;sens2 = (5 * delt) >> 2;if (temperature < -1500) { delt = temperature + 1500;delt = delt * delt;off2 += 7 * delt;sens2 += (11 * delt) >> 1;}}temperature -= T2;off -= off2; sens -= sens2;ms5611Data.temperature = (double)temperature / 100.0; // ℃// 温度补偿后的气压 100009 = 1000.09 mbar = 100009 Papressure = (((ms5611_up * sens ) >> 21) - off) >> 15; // mbarms5611Data.pressure = (double)pressure / 100.0;height = (double)((1.0f - pow((double)pressure / 101325.0f, 0.190295f)) * 44330.0f); // meterms5611Data.height = height;// 求相对高度// 上电100个数据后if(num > 100) {if(cnt < MS5611_WIN_FILTER){alt[cnt] = ms5611Data.height;cnt++;}else{ms5611SumDat = 0.0;for(int i=0; i<MS5611_WIN_FILTER-1; i++){alt[i] = alt[i+1];ms5611SumDat += alt[i];}alt[cnt-1] = ms5611Data.height;ms5611SumDat += alt[cnt-1];ms5611CurAlt = ms5611SumDat/MS5611_WIN_FILTER; // 当前100组数据的高度平均if(baroCalOk == true){ms5611CurAlt -= ms5611StartAlt; // 当前相对高度}}num = 100;}num++;
}
4、总结
MS5611主要是用于计算高度,比如可以用于四旋翼的定高等。
MS5611求海拔高度的时候,由于受温度,气流等各种因素的影响,最终的结果并不理想,
例如下面是我静止采集的30分钟左右的数据,可以明显看到高度是飘的。
最后30分钟左右是我把ms5611拿上拿下来测试的, 所以出现了上图中的波动。
MS5611气压计数据采集(模拟IIC)/温度采集/相对高度求解相关推荐
- STM32F407单片机移植MS5611气压计(基于IIC)---同时解决温度低于20度时计算得到的大气压错误的问题
最近一个工程项目需要使用MS5611气压计,就花时间研究了一下,发现网上很多都是基于STM32F103单片机的MS5611气压计源程序,当移植到STM32F407时发现采集的大气压力和温度值不对,同时 ...
- STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出
文章目录 前言 一.I2C总线通信协议 1.I2C总线 2.工作原理 3.I2C特点 4.I2C模式选择 5.软件I2C和硬件I2C 二.串口输出温湿度传感器的数据 1.核心代码分析 2.硬件实操连接 ...
- STM32基于软件模拟IIC进行AHT21B温湿度采集
STM32基于软件模拟IIC进行AHT21B温湿度采集 一. IIC简介 1.1 IIC简介 1.2 实现方式 1.3 实现方式对比 二. AHT21B简介 2.1 简介 2.2 产品特点 2.3 外 ...
- MS5611气压计IIC源程序
前段工程项目需要测量大气压力,网上搜集了MS5611气压计这方面的资料,并完全参考了相关网友的程序. 1.MYIIC.h #ifndef __MYIIC_H #define __MYIIC_H #in ...
- 基于正点原子STM32F103精英板IIC实验的MS5611气压计的使用
MS5611是一款气压计,能够提供高精度的气压值与温度值,这次做项目正好需要用到这款传感器,包括之前也没好好学习用过IIC,所以写下博客记录一下. 如果有需要使用的朋友可以去https://downl ...
- labview串口数据采集并显示_一种NB-IoT冶金节点温度采集与远程监测系统的设计...
大型高炉出铁量大,冶金生产环境恶劣,导致铁水沟侵蚀日益严重,需人工定期对冶金沟道部分进行温测,其准确度不高,生产成本高,安全保障低[1].为了能够对高炉冶金沟道进行全方位测温,掌握铁水沟道的温度和腐蚀 ...
- 包含几通道数据_温度采集,无处不测!「数据采集」
Measurement Computing (MCC) 提供多种温度数据采集产品.低成本数据采集方案,例如USB-TEMP单模块即可提供热电偶.RTD和热敏电阻输入通道.独立式无线数据采集设备和数据记 ...
- Proteus 8086模拟温度采集 使用LM35温度传感器
一.思路 使用LM35温度传感器进行温度采集,将采集到的电压值(模拟量)经过ADC0808芯片转换成数字信号经数据总线传入8086的寄存器中. 二.8086接线方式 8086的接线方式如上图所示.74 ...
- 多路温度采集计算机网络监测设计,多路温度信号测量与监测,数据采集 温度采集模块...
原标题:多路温度信号测量与监测,数据采集 温度采集模块 5路热电阻温度信号转RS-485/232,温度采集转换模块 WJ25 产品特点: ● 5路温度信号采集,隔离转换 RS-485/232输出 ● ...
- MS5611气压计 I2C驱动代码 STM32
文章目录 前言 通信接口:IIC 一,MS5611的5种命令 RESET : 重启芯片 READ PROM: D1,D2 CONVERSION READ ADC RESULT: 二,实现代码 1 初始 ...
最新文章
- 2022-2028年中国消防报警行业市场前瞻与投资战略规划分析报告
- 学习 Spring Boot:(二十九)Spring Boot Junit 单元测试
- opensource项目_推出“什么是开放式教育?” Opensource.com上的资源
- python 百分比输出_获取Linux系统负荷百分比的python脚本
- git 修改commit_结合IDEA与命令行,解决常用git操作与特殊情况的最佳实践
- Java解析中文数字字符串
- 很多的Adobe Dreamweaver CS5序列号
- Servlet常用依赖
- 前复权 后复权和不复权是什么意思
- 写给大学男同胞几条择偶建议
- 大学想选择计算机专业,零基础如何快速学习编程?都是经验之谈
- delphi 调用浏览器内核_深入理解浏览器原理
- Android 学习网站
- 智能制造系统解决方案和智能工厂发展趋势
- java技术栈 高清视频
- im2col函数实现超级详细解释
- 葫芦娃手游服务器未响应,葫芦娃充值没反应 充值元宝未到账解决办法
- atcoder AtCoder Beginner Contest 210 D - National Railway(dp)
- CAD专用卸载工具,完美彻底卸载清除干净cad各种残留注册表和文件。
- vulnhub Monitoring: 1