我有这个函数形成一个使用MAXIM的71M6511进行能量计设计的示例代码,用于执行此计算。
E = W * 6.6972*10^-13 * VMAX * IMAX (Wh)
VMAX = 600 (but it is stored in the code with a resolution of 0.1 making it 6000)
IMAX = 208 (also stored as 2080)
这里是WattHour的能量,
W是由能量芯片测量的千瓦时的原始值。计算根据能量芯片documentation(第77页)中提供的上述等式将其转换为WattHour,并将其作为带符号的32位整数返回。
这是代码
#define ONE_MILLION (1000000L)
#WATTSCALE 1885L // 6.6972E-12 * 2^48.
static U32 Whr (U08x *w)
{ // 'w' is a 8-byte quantity.
U08 xdata x[13], y[12]; // Need extra digit for divide.
U32 xdata scale;
U08 xdata t[4+4+1];
scale = (U32) Vmax * (U32) Imax; //scale=[Vmax*10E+01] * [Imax*10E+01].
multiply_8_4 (y, w,(U08x *)&scale); // y = w * Vmax * Imax * 10E+02.
scale = WATTSCALE; //[LSB * 2^48 * 10E+01] (10E-03 Wh).
multiply_8_4 (x + 1, y,(U08x *)&scale); //[x*2^16] = [y/2^32]*[LSB * 2^48] (mWh)
//..dropped low-order 4-bytes of 'y'.
scale = ONE_MILLION; // Modulo ONE_MILLION.
divide (x + 1, (U08x *) &scale, 10, 4, t);// x / 1,000,000;
x[7] = 0; //Clear high order of 4-byte result.
return (* (U32x *) &x[7]); // Return 32-bit answer (x % 1,000,000).
}
multiply_8_4()是一个函数,它将8字节数据(这是w指向的数据)乘以4字节数据(比例),并将结果放在另一个缓冲区(在本例中为缓冲区x)
我只是想知道为什么简单的计算(在我看来)复杂,乘法和divsion乘以2 ^ 48和2 ^ 32等等。
程序员的选择是否有任何特殊原因?
答案 0 :(得分:3)
他们似乎正在使用一个不进行浮点计算的8位微控制器。他们还声明,当以字节而不是短路或整数完成时,从内存中获取数据会更有效。您显示的代码实现了一个固定点乘法,其中常量和值被缩放以在二进制点的两侧提供足够的空间,从而不会发生溢出,因此可以满足其需要。
答案 1 :(得分:0)
由于某种原因,程序员选择/必须对整数而不是浮点值进行计算。所以:
他无法对有效数字超过1的值进行操作。如果您尝试将6.6972 * 10 ^ -13存储为整数,则会得到0.因此,6.6972 * 10 ^ -13乘以2 ^ 48给1885.094214 ...在点之后切割数字可能很好。
不是