在atmel AVR 8bit gcc上获得两个16位有符号整数的绝对差异的有效方法是什么?

时间:2014-05-11 15:56:35

标签: avr signed avr-gcc 16-bit atmega

我从I2C总线获得16位有符号整数,并将它们存储在本地int16变量中 该传感器是MEMS陀螺仪,它经常出现高或低数据值,这似乎是许多MEMS陀螺仪的普遍问题。

所以正常读数是-2到+2,并且不时(取决于我的轮询率)我得到非常大的值(如-30000或25000)。

我没有办法在硬件中解决这个问题,我想用软件来解决它。 我寻找一种有效的方法来做这样的事情而不需要32位:

伪代码:

#define SPIKE 0x3000; // a change of SPIKE or larger is ignored
int16_t currentvalue=-2330; // the current value (last sensor result)
int16_t newvalue=-31000; // the new value from sensor, a spike


difference = abs(abs(newvalue) - abs(lastvalue)); // would need some branches more

if (difference < SPIKE) currentvalue = newvalue; // if SPIKE the new value is just not taken

我找不到一个好的有效的方法来保持16位空间,并获得新旧之间的绝对差异,而没有木材的if分支。
我确信有一个很好的有效方法,我只是没有足够的经验处理签名值。

我甚至不需要实际计算绝对差值,如果绝对差值大于SPIKE,则足以获得工作检测。

我想避免32位空间。

1 个答案:

答案 0 :(得分:1)

你的算术似乎有缺陷。如上所述,你可以允许从10000跳转到-10000。相反,你只想使用abs()一次。

difference = abs(newvalue - lastvalue);

你也可以完全避免使用abs()。

difference = newvalue - lastvalue; 
if (difference < 0) difference *= -1;

if (difference < SPIKE) currentvalue = newvalue;

difference = newvalue - lastvalue; 

if (difference > -1*(SPIKE) && difference < SPIKE) currentvalue = newvalue;

这些可能同样有效。如果有任何差异,最后一个可能是最好的,因为乘法发生在编译器中。我留给你测试一下。