如何检测/防止计数器溢出

时间:2011-04-01 12:28:46

标签: c embedded overflow

我在16位字段上有一个计数器,该计数器随时间由硬件外设递增/递减 我定期对其值进行采样,将差值加到32位字段中。

我的问题是在计算差异时检测16位字段的上溢/下溢。

我们举一个例子:
在样本n-1处,计数器值Vn-1是65530 作为样本n,计数器值Vn是4 计数器已增加10.但差值(Vn - Vn-1)将类似于65529(不确定精确值)。​​

我发现检测此溢出的唯一方法是将差值与大于最大增量的固定值(我选择10000)进行比较。
你知道一个解决方案来管理这种溢出而不与这个主观价值进行比较吗?

这是一个代码示例:

static sint32 overallCount = 0;
sint32 diff;
static sint16 previousValue = 0;
sint16 currentValue;

currentValue = sampleValue();

diff = ((sint32) currentValue) - previousValue;
if(diff > 10000) {
    diff -= 65536;
} else if ((-diff) > 10000) {
    diff += 65536;
}

overallCount += diff;

4 个答案:

答案 0 :(得分:7)

我之前的回答有一些错误,所以我重写了它,但想法是一样的,正确使用无符号类型。

使currentValue和previousValue都是所选大小的无符号整数(例如uint16_t)。然后只是减去它们。如果int的类型比int更大,则差异将隐式提升为uint16_t,因此您需要将结果转换或隐式转换回uint16_t。所以:

static uint16_t previousValue;
uint16_t currentValue = sampleValue();
uint16_t diff = currentValue - previousValue;

这可以在赋值中使用隐式转换,但如果愿意,可以使用。

答案 1 :(得分:1)

另一个选择是跟踪溢出计数。使用uint16_t作为值,

if (currentValue < previousValue) overflows++;

然后,要获得32位值,请将溢出与currentValue结合使用。

result = currentValue | (overflows << 16);

答案 2 :(得分:0)

以下是一些适合您的想法:

  1. 在32位字段中进行添加,然后验证结果是否适合16位字段。
  2. 测试旧值的高位是否因添加而改变。
  3. 在组装中添加,然后检查进位标志。

答案 3 :(得分:0)

您可以尝试使用Kalman filter来检测溢出。