3

我使用 MAXIM 的71M6511将这个函数形成一个示例代码,用于能量计设计,该 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)

这里的 E 是瓦特小时的能量,

W是能量芯片测量的千瓦时的原始值。计算根据能量芯片文档(第 77 页)中提供的上述公式将其转换为瓦特小时,并将其作为带符号的 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)

我只是想知道为什么简单的计算(在我看来)如此复杂,因为乘法和除法是 2^48 和 2^32 等等。

除了程序员的选择之外,还有什么特别的原因吗?

4

2 回答 2

3

看来他们使用的是不进行浮点计算的 8 位微控制器。他们还指出,从内存中获取数据以字节而不是短整数或整数形式完成时效率更高。您展示的代码实现了一个定点乘法,其中常量和值按比例缩放以在二进制点的两侧提供足够的空间,从而不会发生溢出,并且有足够的精度来满足他们的需求。

于 2012-09-07T16:53:00.650 回答
0

出于某种原因,程序员选择/不得不对整数而不是浮点值进行计算。所以:

  1. 他不能对有太多有效数字低于 1 的值进行运算。如果您尝试将 6.6972*10^-13 存储为整数,您将得到 0。因此,6.6972*10^-13 乘以 2^48 得到 1885.094214 ...在点之后切割数字可能很好。

  2. 不是

于 2012-09-07T16:56:51.023 回答