MS5611气压传感器的使用
——中北大学:马政贵
图1 MS5611的电路图
MS5611气压传感器支持SPI和IIC总线接口,为降低通讯时间,选择使用SPI通讯,设计的电路图如图1所示。根据电路原理图,程序使用SPI总线接口的模式0方式(时钟空闲时为低,数据捕获于第1个时钟沿)。MS5611内含低功耗的24位ADC,高度分辨率可达10cm。
4.1 MS5611的初始化:
根据数据手册,MS5611在上电之后应发送一次复位指令,用来将出厂校准数据载入相应的寄存器中。复位完成后,再读取这些出厂校准数据,后续用于气压和温度的计算。
/*******************************************************************************
功能:对MS5611进行初始化 参数:无 返回值:无
*******************************************************************************/ void MS5611_Init(void) {
static unsigned char temp_rest; SPI_MS5611_CS_L; delay_us(10);
SPI2_ReadWriteByte(CMD_MS5611_RESET); //发送复位指令
delay_ms(20); //复位需要2.8ms,这里取长一点时间,确保复位 SPI_MS5611_CS_H; delay_us(10);
/*--------------复位后读取PROM内容------------------*/ C1 = SPI_MS5611_Read(CMD_MS5611_PROM_C1); C2 = SPI_MS5611_Read(CMD_MS5611_PROM_C2); C3 = SPI_MS5611_Read(CMD_MS5611_PROM_C3); C4 = SPI_MS5611_Read(CMD_MS5611_PROM_C4); C5 = SPI_MS5611_Read(CMD_MS5611_PROM_C5); C6 = SPI_MS5611_Read(CMD_MS5611_PROM_C6); }
备注:u16 SPI_MS5611_Read(u8 ReadAddr)为寄存器读取函数,参数ReadAddr为要读取的寄存器地址,函数返回相应寄存器的值。在MS5611.h头文件中根据芯片手册对相应寄存器地址进行了宏定义:
/*MS5611模块传感器地址定义*/ #define MS5611_ADC #define CMD_MS5611_RESET #define CMD_MS5611_PROM_Setup #define CMD_MS5611_PROM_C1 #define CMD_MS5611_PROM_C2 #define CMD_MS5611_PROM_C3 #define CMD_MS5611_PROM_C4 #define CMD_MS5611_PROM_C5 #define CMD_MS5611_PROM_C6 #define CMD_MS5611_PROM_CRC
0x00 0x1E 0xA0 0xA2 0xA4 0xA6 0xA8 0xAA 0xAC 0xAE 0x48 0x58
#define CMD_CONVERT_D1_OSR4096 #define CMD_CONVERT_D2_OSR4096
4.2 MS5611数据读取及转换:
对MS5611进行数据读取时,要先发送相应的转换指令。MS5611可以进行气压和温度的测量,因此,有两条相应的转换指令,根据精度的不同,每条转换指令又分为5条具体指令。程序中,我们均按最高精度来进行转换,转换时间约9ms。由于我们的任务调度基于时间片调度模式,为避免造成程序堵塞,数据读取采用switch语句,从而避免在数据转换时的等待,可以去运行其他任务。
气压和温度的计算过程根据芯片手册进行,具体如下:
图2 气压和温度的计算
末尾还进行了相应的二阶温度补偿,具体过程为:
图3 二阶温度补偿
由当前气压和温度值,可计算得到当前高度,公式为:
P((0)5.257?1)*(T?273.15)h?P0.0065
其中,
1P0为海平面气压值;P为当前大气压值;T为当前温度值,单位℃。
/*******************************************************************************
功能:读取MS5611数据,并求取温度、高度值 参数:无 返回值:无
说明:得到的温度为温度值*100(即实际温度放大100倍)
*******************************************************************************/ void MS5611_get_Data(void) {
static unsigned char data[3]; static unsigned char temp;
static unsigned char MS5611_Count=0,MS5611_Num=0; static unsigned int D1,D2;
//D1为气压,D2为温度
static long long dT,T2,Temperature,Pressure;
static double OFF,OFF2,SENS,SENS2; static double tmp_float,Altitude[3];
MS5611_Count++; MS5611_Num++; switch(MS5611_Count) {
case 1:
SPI_MS5611_CS_L; delay_us(10);
SPI2_ReadWriteByte(CMD_CONVERT_D2_OSR4096); //温度转换指令 break; case 2: delay_us(10); SPI_MS5611_CS_L; delay_us(10);
if(0xfe == SPI2_ReadWriteByte(0x00)) {
data[2] = SPI2_ReadWriteByte(0x00); data[1] = SPI2_ReadWriteByte(0x00); data[0] = SPI2_ReadWriteByte(0x00); }
delay_us(10); SPI_MS5611_CS_H;
D2 = ((unsigned int)data[2]<<16) | ((unsigned int)data[1]<<8) | data[0]; dT = D2 - (unsigned int)C5*256; Temperature = 2000 + dT*C6/8388608;
break; case 3:
SPI_MS5611_CS_L; delay_us(10);
SPI2_ReadWriteByte(CMD_CONVERT_D1_OSR4096); //气压转换指令 break; case 4:
//读取气压值
SPI_MS5611_CS_H; delay_us(10); SPI_MS5611_CS_L; delay_us(10);
if(0xfe == SPI2_ReadWriteByte(0x00)) {
data[2] = SPI2_ReadWriteByte(0x00);
//判断读取是否正确
//判断读取是否正确
//读取温度值
SPI_MS5611_CS_H;