小马哥四轴robofly气压计定高解读(1)-气压计获取数据

下面是我对气压计获取数据的解读,水平有限,可以通过这篇文章来理清楚获取高度数据的思路
单片机数字滤波器的文档
FBM320的数据手册
小马哥robofly四轴开源项目GitHub上

FBMTYPE FBM; //首先定义一个结构体用来结合FBM返回的数据计算高度
uint8_t ALTIUDE_OK = 0,ALT_Updated = 0;
float RPFilter;

FBM320数据结构

下面是一些函数
**uint8_t FBM320_WriteByte(uint8_t reg,uint8_t data):写一个字节到
FBM320寄存器

uint8_t FBM320_WriteMultBytes(uint8_t reg,uint8_t len,uint8_t *buf):从指定寄存器写入指定长度数据

uint8_t FBM320_ReadMultBytes(uint8_t reg,uint8_t len,uint8_t *buf):从指定寄存器读取指定长度数据

uint8_t FBM320_getDeviceID(void):读取 FBM320 WHO_AM_I 标识将返回 0x42

uint8_t FBM320_testConnection(void) :检测FBM320 是否已经连接,可以检查FBM320是否能和主机通信

void FBM320_Check(void):检测IIC总线上的FBM320是否存在
void FBM320_Init(void):初始化FBM320并获取FBM320校准数据
void FBM320_GetCoeff(void):获取存储在FBM320片内的校准数据**

void FBM320_GetCoeff(void)
{
	uint8_t data[20],i = 0;
	uint16_t R[10];
	FBM320_ReadMultBytes(FBM_COEFF1,18,data); //从这个地址FBM_COEFF1:0xAA(187)-0xBB(170)开始拿18个数据放到data里
	FBM320_ReadByte(FBM_COEFF3,&data[18]);   //将从FBM_COEFF3获取到的数据放到data[18]
	FBM320_ReadByte(FBM_COEFF4,&data[19]);  //将从FBM_COEFF4获取到的数据放到data[19],刚好就20个
	for(i=0;i<10;i++)
	{
		R[i] = (uint16_t)(data[2*i]<<8)|data[2*i+1];   //数据获取后的常见操作,16bit类型的数据=8bit高位 接上 8bit地位,这里的接上就是进行或运算,但是要先将8bit的高位转换为16位比如:11000011->11000011 00000000  | 11111110 = 
		11000011 11111110
	}
		/* Use R0~R9 calculate C0~C12 of FBM320-02	*/  //这个就直接参考例程,通过传感器获取的data,然后转换为R[],然后在通过下面的方法获取计算气压和温度的C0---C12
	FBM.C0 = R[0] >> 4;
	FBM.C1 = ((R[1] & 0xFF00) >> 5) | (R[2] & 7);
	FBM.C2 = ((R[1] & 0xFF) << 1) | (R[4] & 1);
	FBM.C3 = R[2] >> 3;
	FBM.C4 = ((uint32_t)R[3] << 2) | (R[0] & 3);
	FBM.C5 = R[4] >> 1;
	FBM.C6 = R[5] >> 3;
	FBM.C7 = ((uint32_t)R[6] << 3) | (R[5] & 7);
	FBM.C8 = R[7] >> 3;
	FBM.C9 = R[8] >> 2;
	FBM.C10 = ((R[9] & 0xFF00) >> 6) | (R[8] & 3);
	FBM.C11 = R[9] & 0xFF;
	FBM.C12 = ((R[0] & 0x0C) << 1) | (R[7] & 7);
	}

FBM320寄存器
FBM320寄存器
FBM320头文件
void FBM320_Calculate(int32_t UP, int32_t UT) :将FBM320获取到AD值转换成物理量,通过测量得到的温度值和气压值求出
这里获取FBM结构体中的RT和RP值,RP值在气压计初始化求初始高度和求出实际高度时用到,具体怎么实现的我们也不用管

void FBM320_Calculate(int32_t UP, int32_t UT)										
{
    int32_t DT, DT2, X01, X02, X03, X11, X12, X13, X21, X22, X23, X24, X25, X26, X31, X32, CF, PP1, PP2, PP3, PP4;

    DT	=	((UT - 8388608) >> 4) + (FBM.C0 << 4);
    X01	=	(FBM.C1 + 4459) * DT >> 1;
    X02	=	((((FBM.C2 - 256) * DT) >> 14) * DT) >> 4;
    X03	=	(((((FBM.C3 * DT) >> 18) * DT) >> 18) * DT);
    FBM.RT	=	((2500 << 15) - X01 - X02 - X03) >> 15;

    DT2	=	(X01 + X02 + X03) >> 12;

    X11	=	((FBM.C5 - 4443) * DT2);
    X12	=	(((FBM.C6 * DT2) >> 16) * DT2) >> 2;
    X13	=	((X11 + X12) >> 10) + ((FBM.C4 + 120586) << 4);

    X21	=	((FBM.C8 + 7180) * DT2) >> 10;
    X22	=	(((FBM.C9 * DT2) >> 17) * DT2) >> 12;
    X23 = (X22 >= X21) ? (X22 - X21) : (X21 - X22);

    X24	=	(X23 >> 11) * (FBM.C7 + 166426);
    X25	=	((X23 & 0x7FF) * (FBM.C7 + 166426)) >> 11;
    X26 = (X21 >= X22) ? (((0 - X24 - X25) >> 11) + FBM.C7 + 166426) : (((X24 + X25) >> 11) + FBM.C7 + 166426);

    PP1	=	((UP - 8388608) - X13) >> 3;
    PP2	=	(X26 >> 11) * PP1;
    PP3	=	((X26 & 0x7FF) * PP1) >> 11;
    PP4	=	(PP2 + PP3) >> 10;

    CF	=	(2097152 + FBM.C12 * DT2) >> 3;
    X31	=	(((CF * FBM.C10) >> 17) * PP4) >> 2;
    X32	=	(((((CF * FBM.C11) >> 15) * PP4) >> 18) * PP4);
    FBM.RP	=	((X31 + X32) >> 15) + PP4 + 99880; //99880气压补偿

}

至此,我们获取到FBM结构体中的,FBM320数据体已经获得的
接下来看转换为实际高度的函数:
void FBM320_GetAltitude(void):FBM320的气压值转换成相对高度

void FBM320_GetAltitude(void) //200Hz
{
	uint8_t buf[3];
	static uint8_t timecnt = 0;
	float  AltitudeFilter;
	switch(timecnt)//温度和气压数据转换时间不一样
	{
		case 0:  
				FBM320_WriteByte(FBM_CONFIG,TEMP_CONVERSION); //280usTEMP_CONVERSION=0x2E
				break;  
		case 1: //5ms转换一次 (836us)
				FBM320_ReadMultBytes(DATA_MSB,3,buf); 
				FBM.ADTemp = (buf[0]<<16)|(buf[1]<<8)|buf[2];
				FBM320_WriteByte(FBM_CONFIG,PRES_CONVERSION+OSR8192); //开启气压转化
				break;
		case 5: //15ms转换一次 (834us)
				FBM320_ReadMultBytes(DATA_MSB,3,buf);  
				FBM.ADPress = (buf[0]<<16)|(buf[1]<<8)|buf[2];
				FBM320_WriteByte(FBM_CONFIG,TEMP_CONVERSION); //开启温度转换
				FBM320_Calculate( FBM.ADPress , FBM.ADTemp );	//将FBM320的原始数据转换成物理量 气压单位是帕,温度单位摄氏度
		  
		if(Init_Altitude())  //这里通过Init_Altitude()函数获取到FBM.InitPress用于后面气压转换为高度
		{
			BAR_Offset_LED();//气压计校准成功指示灯
			ALTIUDE_OK = 1;
		}
		   
		SortAver_Filter((float)FBM.RP,&FBM.RPFilter,12); //去极值均值滤波,取极值均值滤波:顾名思义,在12个数据中排序,去掉最大和最小的,剩下的10个求平均值,赋值给当前时刻的FBM.RPFilter
		//printf("FBM.RP:%0.2f  FBM.RPFilter:%0.2f\r\n",FBM.RP,FBM.RPFilter);
		if(FBM.RPFilter && ALTIUDE_OK) 
		{
			ALT_Updated = 1;
			FBM.Altitude = 44330.0f * (1 - powf((float)FBM.RPFilter/ FBM.InitPress, 0.190295f));
		}
			 
		SortAver_Filter1(FBM.Altitude ,&AltitudeFilter,12); //去极值均值滤波
		if(AltitudeFilter)
			Aver_Filter1(AltitudeFilter,&FBM.AltitudeFilter,8); //滑动窗口滤波,滑动窗口滤波如下图
		
			 
	 FBM.Altitude = ((float)Abs_Altitude((int32_t)FBM.RPFilter))/1000;		//计算绝对高度(相对于海平面)  2021-3去掉注释
				break;
				default:
				break;
		
	  }
	timecnt++; //转换时间计数
	if(timecnt>5)
		timecnt = 0;

}

函数中用到的寄存器:
函数中用到的寄存器
滑动窗口滤波
至此我们就求得了当前的高度。整理一下思路:先获取C0-C12 ->FBM.RP 和 FBM.RT ->FBM.ADTemp和FBM.ADPress ->更精确的FBM.RP->滤波->结合FBM.InitPres->FBM.Altitude->滤波->FBM.AltitudeFilter 用于后面定高算法

与气压计相关的参考资料:
参考资料
参考资料
参考资料

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值