繁体   English   中英

方程似乎在嵌入式 C (stm32) 中输出错误值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM