通常我们需要使用ADC模块处理NTC传感器数据转换成实际温度值硬件电路中会采用分压电路NTC作为一个分压电阻参考电压Vadc不变温度变化电阻值随之变化Adc端口采集到的电压(Vin)也会变化根据采集到的电压可以反推理出NTC(R1)阻值。R2:分压电路中上拉电阻R1:分压电路中上拉电阻使用的是下面型号的NTC电阻温度和电阻值一一对应我们可以采用线性查表的方式计算出实际的温度。#include stdint.h #include stdbool.h /* Resistance-temperature lookup table entry structure */ typedef struct { float32 f32resistance; /* Resistance value, table sorted in ascending order */ float32 f32temperature; /* Corresponding temperature value */ } EvAdc_LookupEntryType_T; /* Request/response structure: both input and output */ typedef struct { float32 f32resistance; /* Input: resistance value to look up */ float32 f32temperature; /* Output: calculated temperature (valid only if bTempValid is true) */ boolean bTempValid; /* Output: true if lookup succeeded, false on error */ } EvAdc_LookupResultType_T; /* Internal static constant table, strictly ascending (no equal adjacent resistances) */ const EvAdc_LookupEntryType_T gc_f32a_Templookuptable_CMP[] { {100.0F, 25.0F}, {200.0F, 30.0F}, {300.0F, 36.0F}, {400.0F, 42.0F}, {500.0F, 50.0F} /* Extend as needed */ }; typedef struct { float32 f32_VHTemp; float32 f32_VHPressure1; float32 f32_VHPressure2; uint32 u32_P1Raw; uint32 u32_P2Raw; float32 f32_ECASLSD01mA; float32 f32_ECASLSD02mA; float32 f32_ECASLSD03mA; float32 f32_ECASLSD04mA; float32 f32_ExhValveVolA; EvAdc_LookupResultType_T st_AdcMOSFETM; EvAdc_LookupResultType_T st_AdcPCBM; } EvAdc_SigPhyDataType_T; static void EvAdc_LookupTemperature(EvAdc_LookupResultType_T *p_TestResult); static void EvAdc_TempLinearSearch(EvAdc_LookupResultType_T *p_TestResult, uint32 u32TableSize); /** * brief Look up temperature by resistance (linear search linear interpolation) * * param p_Result [in/out] Pointer to result structure * Input: f32resistance set * Output: f32temperature and bTempValid filled * * note Internal static table is read-only, ensuring reentrancy. * If resistance is out of range, the boundary temperature is returned and bTempValid true. * If input pointer is NULL or table is invalid, bTempValid false, temperature remains 0. * Strictly follows MISRA C 2012: single return statement, no hidden control flow. */ static void EvAdc_LookupTemperature(EvAdc_LookupResultType_T *p_TestResult) { static const uint32 u32TableSize; u32TableSize sizeof(gc_f32a_Templookuptable_CMP) / sizeof(gc_f32a_Templookuptable_CMP[0U]); /* Single return point at the end */ if (p_TestResult ! NULL) { /* Resistance below lower bound */ if (u32TableSize 2U) { /* Resistance below lower bound */ if (p_TestResult-f32resistance gc_f32a_Templookuptable_CMP[0U].f32resistance) { p_TestResult-f32temperature gc_f32a_Templookuptable_CMP[0U].f32temperature; p_TestResult-bTempValid FALSE; } /* Resistance above upper bound */ else if (p_TestResult-f32resistance gc_f32a_Templookuptable_CMP[u32TableSize - 1U].f32resistance) { p_TestResult-f32temperature gc_f32a_Templookuptable_CMP[u32TableSize - 1U].f32temperature; p_TestResult-bTempValid FALSE; } else { EvAdc_TempLinearSearch(p_TestResult, u32TableSize); } } } } /** * brief Perform linear search and interpolation on the temperature lookup table. * * This function searches the global constant table gc_f32a_Templookuptable_CMP * for the interval containing the input resistance, then computes the corresponding * temperature via linear interpolation. The result is stored in the output structure. * * param p_TestResult [in/out] Pointer to structure holding: * - f32resistance: Input resistance to look up. * - f32temperature: Output computed temperature. * - bTempValid: Output validity flag. * param u32TableSize [in] Number of entries in the lookup table. * Must be at least 2 to allow interpolation. * * note This function is reentrant as it only reads global constant data. * * note MISRA C 2012 compliance: * - Single exit point (the function returns void, no explicit return needed). * - All control statements use braces. * - No reliance on implicit type conversions. * - Defensive check against division by zero. */ static void EvAdc_TempLinearSearch(EvAdc_LookupResultType_T *p_TestResult, uint32 u32TableSize) { float32 f32CalcTemp 0.0F; boolean bTempValid FALSE; float32 f32ResLow,f32ResHigh,f32TempLow,f32TempHigh; /* Linear search for the interval [i-1, i] */ for (uint32 i 0U; i u32TableSize; i) { /* Exact match */ if (p_TestResult-f32resistance gc_f32a_Templookuptable_CMP[i].f32resistance) { f32CalcTemp gc_f32a_Templookuptable_CMP[i].f32temperature; bTempValid TRUE; break; } /* Found first element greater than input resistance */ if (gc_f32a_Templookuptable_CMP[i].f32resistance p_TestResult-f32resistance) { f32ResLow gc_f32a_Templookuptable_CMP[i - 1].f32resistance; f32ResHigh gc_f32a_Templookuptable_CMP[i].f32resistance; f32TempLow gc_f32a_Templookuptable_CMP[i - 1].f32temperature; f32TempHigh gc_f32a_Templookuptable_CMP[i].f32temperature; /* Defensive check: avoid division by zero (table should guarantee inequality) */ if (f32ResHigh ! f32ResLow) { f32CalcTemp f32TempLow ((f32TempHigh - f32TempLow) * (f32resistance - f32ResLow) \ / (f32ResHigh - f32ResLow)); bTempValid TRUE; } /* If f32ResHigh f32ResLow, bTempValid remains false (table anomaly) */ break; } } if (i u32TableSize) { f32CalcTemp gc_f32a_Templookuptable_CMP[u32TableSize - 1U].f32temperature; } p_TestResult-f32temperature f32CalcTemp; p_TestResult-bTempValid bTempValid; } /*For example*/ void main(void) { float32 f32MosVolt,f32PcbVolt; f32MosVolt g_EvAdc_MosVolt; f32PcbVolt g_EvAdc_PcbVolt; /* Input: resistance value to look up */ g_EvAdc_DevInfo.Data.st_AdcPCBM.f32resistance (f32MosVolt * 10.0F)/(5.0F -f32MosVolt); g_EvAdc_DevInfo.Data.st_AdcMOSFETM.f32resistance (f32PcbVolt * 10.0F)/(5.0F -f32PcbVolt); EvAdc_LookupTemperature(g_EvAdc_DevInfo.Data.st_AdcPCBM); EvAdc_LookupTemperature(g_EvAdc_DevInfo.Data.st_AdcMOSFETM); }