MS5611是一款由瑞士公司MEAS推出的高分辨率气压传感器。它具有以下特点:
接口:支持SPI和I²C总线接口。(通过PS脚来选择)
内部结构:包括高线性度的压力传感器和超低功耗的24位累加模数转换器(工厂校准系数)。
功能:提供精确的24位数字压力值和温度值,适用于高度计、温度计等功能。
尺寸:仅有5.0毫米×3.0毫米×1.0毫米的小尺寸,适合集成在移动设备中。
这款传感器采用领先的MEMS技术,具有高稳定性和非常低的压力信号滞后。它在移动高度计、气压计系统、自行车电脑、智能手机等领域有广泛的应用
准备工作
由于芯片上支持IIC通讯,因此我们打算使用STM32的硬件IIC,我的STM32为STM32F407。
我们打开CUBEMX,选择好我们的时钟还有其他设置之后,我们打开我们的硬件IIC
并且我们打开串口来进行调试,我们选择IIC1,可以发现是PB6/PB7。
并且我们在USART.C文件中加入我们的串口重定向代码,方便我们使用printf函数
struct __FILE
{
int handle;
};
struct __FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, struct __FILE *f)
{
while((USART1- >SR&0X40)==0);//循环发送,直到发送完毕
USART1- >DR = (unsigned char) ch;
return ch;
}
利用这串代码,我们就可以把我们的串口发送函数重定向到我们的printf函数上。
之后我们测试一下,我们的串口发送。
可以看到串口重定向成功。
数据解释
我们在MS5611的官方手册中可以看到,MS5611的数据主要由C1~C6这六个校准系数以及D1,D2两个数据组成。
通过这些数据配合芯片手册计算方式我们可以计算出我们的传感器数值。
我们在向MS5611发送数据转换命令的时候,模块会把对应的信号转换好之后存入PROM寄存器中,我们需要读取PROM的数据来读取这些数据,PROM的地址从0XA0~0XAE
代码编写
#define MS5611_I2C_ADDR 0xEE //PS拉高的地址
#define CMD_ADC_READ 0x00 //ADC转换开始
#define CMD_ADC_CONV_D1 0x40 //D1读取命令
#define CMD_ADC_CONV_D2 0x50 //D2读取命令
#define CMD_PROM_RD 0xA0 //PROM基地址
typedef struct {
double temperature;//温度
double pressure;//气压
uint32_t D1;
uint32_t D2;
uint16_t C1;
uint16_t C2;
uint16_t C3;
uint16_t C4;
uint16_t C5;
uint16_t C6;
} MS5611Data;
首先我们定义模块的命令宏定义以及我们的结构体用来存放我们的数据。
extern I2C_HandleTypeDef hi2c1;
void ReadMS5611Data(MS5611Data *ms5611Data);
其次定义我们的hi2c1句柄,由于这个句柄的实际定义是在i2c.h文件中,因此我们需要加上extern来修饰我们的变量
接着我们来定义我们的ReadMS5611Data函数,我们分步讲解。
HAL_I2C_Mem_Write(&hi2c1, MS5611_I2C_ADDR, CMD_ADC_CONV_D1, I2C_MEMADD_SIZE_8BIT, NULL, 0, 100);
HAL_Delay(10);
uint8_t buffer[3];
HAL_I2C_Mem_Read(&hi2c1, MS5611_I2C_ADDR, CMD_ADC_READ, I2C_MEMADD_SIZE_8BIT, buffer, 3, 100);
ms5611Data- >D1 = ((uint32_t)buffer[0] < < 16) | ((uint32_t)buffer[1] < < 8) | (uint32_t)buffer[2];
首先是利用HAL库的IIC写命令函数,我们向模块发送读取命令,
由于D1,D2都是24个空间,因此我们的数据分3次读取,我们定义一个uint8_t buffer[3];分别存储三次数据
之后我们利用移位运算符,把我们的数据依次拼接到我们的D1数据上。
HAL_I2C_Mem_Write(&hi2c1, MS5611_I2C_ADDR, CMD_ADC_CONV_D2, I2C_MEMADD_SIZE_8BIT, NULL, 0, 100);
HAL_Delay(10);
HAL_I2C_Mem_Read(&hi2c1, MS5611_I2C_ADDR, CMD_ADC_READ, I2C_MEMADD_SIZE_8BIT, buffer, 3, 100);
ms5611Data- >D2 = ((uint32_t)buffer[0] < < 16) | ((uint32_t)buffer[1] < < 8) | (uint32_t)buffer[2];
这部分也是同理,我们用这个方式获取D2的值。
uint8_t coef_data[2];
for (int i = 1; i <= 6; i++) {
HAL_I2C_Mem_Read(&hi2c1, MS5611_I2C_ADDR, CMD_PROM_RD + (i)*2, I2C_MEMADD_SIZE_8BIT, coef_data, 2, 100);
if (i == 1) {
ms5611Data- >C1 = (coef_data[0] < < 8) | coef_data[1];
} else if (i == 2) {
ms5611Data- >C2 = (coef_data[0] < < 8) | coef_data[1];
} else if (i == 3) {
ms5611Data- >C3 = (coef_data[0] < < 8) | coef_data[1];
} else if (i == 4) {
ms5611Data- >C4 = (coef_data[0] < < 8) | coef_data[1];
} else if (i == 5) {
ms5611Data- >C5 = (coef_data[0] < < 8) | coef_data[1];
} else if (i == 6) {
ms5611Data- >C6 = (coef_data[0] < < 8) | coef_data[1];
}
}
接着我们定义一个数据用来存储我们的校准系数,由于校准系数是存储在PORM上的
所以我们需要用MS5611_I2C_ADDR, CMD_PROM_RD + (i)*2来确定我们的地址
我们把数据按照高8位低8位存储到校准系数中
int32_t dt = ms5611Data- >D2 - ((int32_t)ms5611Data- >C5 *256);
double temp = 2000+((double)dt/ 8388608)*ms5611Data- >C6;
接着我们按照手册中的方法计算我们的数据,需要注意的是,temp的类型最好选择是double型,否则dt/8388608(1<<23)可能会数据丢失。
同样的我们再用这种办法计算我们的气压值(手册上面都有)
int64_t off = ((int64_t)ms5611Data- >C2 * 65536) + ((int64_t)ms5611Data- >C4 * dt) / 128;
int64_t sens = ((int64_t)ms5611Data- >C1 < < 15) + (((int64_t)ms5611Data- >C3 * dt) / (1 < < 8));
double pressure = ((double)ms5611Data- >D1 * sens/2097152 - off) / (1 < < 15);
效果展示
可以看到我们的气压数据打印出来是符合常理的。
我们的温度数据也是正常显示的
-
传感器
+关注
关注
2499文章
45804浏览量
733035 -
mems
+关注
关注
126文章
3532浏览量
187422 -
STM32
+关注
关注
2214文章
10274浏览量
345462 -
气压传感器
+关注
关注
4文章
115浏览量
20775
发布评论请先 登录
相关推荐
【经验交流】使用MS5611高精度气压计之后的感想
完全替换精量(Intersema) MS5611的气压传感器 -- FBM320(沛喆
GPS轨迹和气压传感器等多路数据同步采集与存储实现方案
STM32F10X + MS5611 + JLink 测气压温度例程详解
STM32+MS5611测气压温度例程详解

气压传感器MS5611使用SPI接口的程序

气压传感器bmp280与ms5611哪个好
一文看懂ms5611性能参数及典型应用
STM32 BMP280模块获取气压温度高度传感器数据 TFT显示

评论