簡體   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