[英]Equation seems to be outputting wrong value in embedded C (stm32)
希望你今天过得愉快。
我遇到了一个奇怪的问题。 我正在定制 BMS PCB 上的 STM32 F103 C8T6 微控制器上的嵌入式 C 代码,但我对根据热敏电阻 ADC 值计算实际温度的代码有一些问题。
通过excel,我们确定了我们需要使用从ADC值来计算摄氏温度的公式是: y = -0.5022x^5 + 6.665x^4 - 35.123x^3 + 92.559x^2 - 144.22x + 166.76
。
因此,在我的代码中,我有以下几行,其中 temp[i] 是原始 ADC 值,realTemp[i] 是转换后的值:
realTemp[i] = (double)(temp[i] / 10000);
realTemp[i] = -0.5022 * realTemp[i]*realTemp[i]*realTemp[i]*realTemp[i]*realTemp[i] + 6.665 * realTemp[i]*realTemp[i]*realTemp[i]*realTemp[i] - 35.123 * realTemp[i]*realTemp[i]*realTemp[i] + 92.559 * realTemp[i]*realTemp[i] - 144.22 * realTemp[i] + 166.76;
我没有使用 math.h 中的 pow 函数,因为它过去给我们带来了问题。
我们在 temp[i] 变量中得到的值如下:35480、35496、35393、35480。当在 excel 中将这些值与我们的函数一起使用时,我们得到了正确的输出,介于 25.3 和 25.5 摄氏度之间,但是 C上面列出的代码在 realTemp 数组中输出 36。 我不确定十进制值,但我不关心它们,因为该值在几行之后被类型转换为 uint16,以便通过 CAN 总线传输。
使用浮点除法,而不是整数除法。
// Integer division ------v-------------v
// realTemp[i] = (double)(temp[i] / 10000);
realTemp[i] = temp[i] / 10000.0;
正如其他人所说,您正在进行整数除法,然后将结果转换为double
- 您需要将除法本身作为double
进行。
在有问题的微控制器上,您的代码会很大而且很慢。 这可能不是问题,假设温度值通常不会经常变化,所以慢代码可能适合您。
您还需要小心使用高次多项式 - 它们很容易不稳定,尤其是当您尝试将它们外推到非常高或非常低的温度时。 如果您决定通过切换到float
来使代码更快,这将是一个特别冒险的事情。
这种事情的更好方法通常是查找表(它可能很大但实现起来更简单),或者使用线性样条曲线(占用空间更小但实现起来更复杂)。
Chux 的回答是正确的,我只是想更多地解释一下为什么会这样。
temp[i]
是uint16
,因此公式temp[i] / 10000
是整数除法,结果将是(temp[i] / 10000)
的底。 因此,最终转换为double
是在一个已经下限的值上执行的。
通过将10000
转换为10000.0
,这意味着用float/double
对整数进行除法将执行浮点除法。 这样,结果将与您的预期相似。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.