MS5611气压计 I2C驱动代码 STM32

前言

这篇博客将介绍使用stm32的IIC库函数开发MS5611气压计,获取气压数据和温度数据,并对数据进行补偿。过程将结合芯片手册与代码。
手册下载地址:https://wws.lanzous.com/iZDAvf6joyd
代码仓库地址:https://gitee.com/killerp/MS5611

通信接口:IIC

使用IIC接口进行数据读取。
当PS脚接高电平时,7和8引脚复用为IIC模式,否则为SPI模式;
在这里插入图片描述由上图,CSB接地,则CSB非就是1了。所以MS5611的地址就是0xEE;
在这里插入图片描述

一,MS5611的5种命令

MS5611仅有5种基础命令:

RESET : 重启芯片

在读取PROM数据之前必须REST芯片,也就是在初始化的时候reset一下:
reset命令固定是0x1E;

/*
 * 重启ms5611
 */
void MS5611_Rest()
{
	I2C_WriteByte(I2C1,MS5611_SLAVE_ADDR,MS5611_CMD_REST);
	delay_ms(4);
	
}

READ PROM:

读取PROM内存的数据,PROM存放8个16位数据,第一个16位数据包含工厂数据,第二到第七个数据用于补偿气压和温度。2-7的具体含义见图:
在这里插入图片描述最后一个数据是CRC校验数据

D1,D2 CONVERSION

因为传感器获得的气压数据,温度数据是模拟量,需要进行模数转换。D1,D2分别对应气压和温度的模数转换精度。支持从256到4096的转换精度,精度越大,转换时间越长,具体对应关系见图:
在这里插入图片描述

READ ADC RESULT:

读取气压和温度模数转换后的数据,就是我们需要的数据。每次读取必须先进行模数转换后,延时一个转换时间后再发送此命令。

二,实现代码

1 初始化 :

需要重启芯片,然后读取保存PROM内8个数据,等会补偿数据时会用到

/*
*  读取prom的内容
*/
int MS5611_init()
{
	ms5611_init();
	Ms5611_Rest();
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_0,2,(unsigned char *)(ms5611_handle->reserve),MSB);
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_1,2,(unsigned char *)(ms5611_handle->C),MSB);
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_2,2,(unsigned char *)((ms5611_handle->C)+1),MSB);
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_3,2,(unsigned char *)((ms5611_handle->C)+2),MSB);
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_4,2,(unsigned char *)((ms5611_handle->C)+3),MSB);
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_5,2,(unsigned char *)((ms5611_handle->C)+4),MSB);
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_6,2,(unsigned char *)((ms5611_handle->C)+5),MSB);
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS5611_PROM_READ_7,2,(unsigned char *)(ms5611_handle->CRC),MSB);
}

2,读取数据

以读取温度数据为例,先发送转换命令,等待转换时间,再去读取3个字节的温度数据

/*
 * 读取温度 转换精度4096
*/
int MS5611_read_temp()
{
	I2C_WriteByte(I2C1,MS5611_SLAVE_ADDR,MS5611_CMD_CONVERT_D2_4096);//发送转换命令
	delay_ms(9);//等待转换完成
	I2C_ReadBytes(I2C1,MS5611_SLAVE_ADDR,MS6511_ADC_READ,3,(unsigned char *)((ms5611_handle->D)+1),MSB);//读取三个字节的温度
}

3,补偿温度数据

计算公式来自手册,主要是为了求出P(温度补偿压力):
在这里插入图片描述
当温度过低时,计算过程就多了T2,OFF2等步骤:
在这里插入图片描述
代码上基本跟着手册的公式来,这里不考虑温度低于-15°的情况

/*
 * 修正气压和温度
*/
int MS5611_calculate()
{
	signed long long dT = 0,TEMP = 0,T2 = 0,OFF = 0,OFF2 = 0,SENS2 = 0,SENS = 0;
	
	dT = ms5611_handle->D[1] - ((signed long long) (ms5611_handle->C[4])<<8);
	TEMP = 2000 + ((signed long long) (dT*(ms5611_handle->C[5]))>>23);
	//低于20°时:
	if(TEMP < 2000 && TEMP > -1500)
	{
		T2 = ( dT*dT )>>31;
		OFF2 = 5 * (TEMP - 2000) * (TEMP - 2000) / 2;
		SENS2 = 5 * (TEMP - 2000) * (TEMP - 2000) / 4;
	}
	OFF = (((int64_t)(ms5611_handle->C[1])) << 16) + (((ms5611_handle->C[3]) * dT) >> 7);
	SENS = (((int64_t)(ms5611_handle->C[0])) << 15) + (((ms5611_handle->C[2]) * dT) >> 8);
	
	ms5611_handle->dT = dT;
	ms5611_handle->OFF -= OFF2;
	ms5611_handle->TEMP -= T2;
	ms5611_handle->SENS -= SENS2;
	ms5611_handle->P = ((((ms5611_handle->D[0]) * (ms5611_handle->SENS))>>21) - (ms5611_handle->OFF))>>15;
	
}

猜你喜欢

转载自blog.csdn.net/weixin_44821644/article/details/107723941