我想用DCM融合加速度、陀螺仪、磁强计生成欧拉角和四元数。
几个函数如下:
void CompDCMAccelUpdate (tCompDCM∗psDCM, float fAccelX, float fAccelY, float fAccelZ)
void CompDCMGyroUpdate (tCompDCM∗psDCM, float fGyroX, float fGyroY, float fGyroZ)
void CompDCMMagnetoUpdate (tCompDCM∗psDCM, float fMagnetoX, float fMagnetoY, float fMagnetoZ)
问题是:
从传感器读回来的是16-bit 二进制补码,就是带符号位的。
而上述函数的参数要求是float类型,直接送一个16位 二进制补码可以吗?是不是在输入的正负变化时,DCM也会突变?我该如何处理?
库里的MPU6050.c里是这样写的:
if(pfAccelX) { *pfAccelX = (float)((int16_t)((psInst->pui8Data[0] << 8) | psInst->pui8Data[1]) * fFactor); }
这里将两个8位并成16位,但符号位并无处理,直接强制转换成float。
为了避免意想不到的情况,我希望弄明白此事..
xyz549040622:
而上述函数的参数要求是float类型,直接送一个16位 二进制补码可以吗?
这个应该不可以吧,你需要把这个二进制的补码转换为浮点值,但是这个具体也没搞过,你可以参考下TI给的例程,看看他们是如何实现转换的。
xyz549040622:
回复 Dehua Mo:
楼主可以解释下么,俺的基础也不好。
Dehua Mo:
回复 xyz549040622:
我也是初学者,我只是把我的想法和验证过程说说:
还是SW里的例程 pfAccelX = (float)((int16_t)((psInst->pui8Data[0] << 8) | psInst->pui8Data[1]) * fFactor);
psInst->pui8Data[0]、psInst->pui8Data[1]分别装着从MPU6050读回的加计MSB、LSB,其类型为unsigned char;
这里将他们拼成16位,然后强制转换成short(16位的带符号位),再强制转换成float;
我通过程序验证:假如读回来的值是0xFFFF,此值为补码,表示的值为-1;(如果有人不清楚补码-原码具体算法,百度吧)
然后定义一个float a;
a=(float)( ( short)(0xFFFF) ); 结果a=-1;正确
如果去掉short: a=(float) (0xFFFF) ); 结果a=65535;这不是我们希望的;
关键就在于这个神奇的short…虽然问题解决了,但是其中的奥妙还是值得研究一下…
xyz549040622:
回复 Dehua Mo:
我大概懂了那么一点点,MSB,LSB都是8位的,要想合并,必须转换为16位的数,这里如果不使用强制转换为short,MSB和LSB合并后,应该会合并为一个不知道类型的无符号数据,所以这里使用强制转换了。