【发布时间】:2022-06-13 22:34:21
【问题描述】:
希望你今天过得愉快。
我遇到了一个奇怪的问题。我正在使用定制 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 总线传输。
【问题讨论】:
-
可能是因为
temp是一个整数数组。所以(temp[i] / 10000)对于您显示的所有输入来说只有 3 个。realTemp[i] = (double)(temp[i] / 10000);应该是realTemp[i] = temp[i] / 10000.0; -
请注意:看到“realTemp[i]*realTemp[i]”重复了这么多次,让我感到刺痛。使用临时变量,节省输入并提高可读性。
-
这真的需要一个五阶多项式来模拟特征吗?如果您从“趋势线”中获取这些系数,请谨慎行事,Excel 默认会隐藏可能影响曲线形状的有效数字。给定一个 12 位 ADC,您真的需要那么多阶数或那么多有效数字吗?就您而言(没有 FPU),使用浮点的需要会增加代码大小并且速度会有些慢。定点实现可能更可取,但我当然会首先考虑简化曲线拟合,并且在某种程度上更合理。可用精度。
-
只使用带有一些曲线点和一些线性插值的表格可能会更好/更快。