前言:之前的文章中也有關於使用I2C器件進行溫度的採集的文章
採集溫度的方式不止使用感測器,也可以使用NTC溫敏電阻進行採集,此方法的外圍電路較為簡單切成本較低,程式碼也較為容易實現。
實現原理:先透過差分取樣電路進行採集,採集之後可以獲取NTC或者定值電阻的電壓;已知這些資訊可以透過歐姆定律得到當前電路的電流,根據串聯電路電流處處相等的特性可再透過歐姆定律獲取當前NTC的阻值。(溫度越高NTC阻值越小,溫度越低NTC阻值越大)
獲取到了當前NTC的阻值可以透過查表得到一個粗略的溫度,也可以透過公式獲得當前的溫度較為準確一些。
NTC 熱敏電阻溫度計算公式:Rt = R*EXP(B(1/T1-1/T2))
其中,T1和T2指的是K度,即開爾文溫度。
Rt 是熱敏電阻在T1溫度下的阻值。
R是熱敏電阻在T2常溫下的標稱阻值。100K的熱敏電阻25℃的值為10K(即R=10K)。T2=(273.15+25)
EXP是e的n次方
透過此公式可以得到溫度轉換的公式:T1 =1/(ln(Rt/R)/B+1/T2)-273.15+0.5;
這裡+0.5的誤差矯正。
1、NTC電阻的選型:
NTC實際的選型B值是一個很關鍵的引數,同時也要考慮自己的實際應用去選擇合適阻值的電阻;筆者這裡為了簡便計算選擇了10k的定值電阻與B值為3950的10k的NTC;
硬體設計:
2、程式碼實現:
#include "CH59x_common.h" #include "math.h" uint16_t adcBuff[40]; float sum=0;//多次取樣和 float averagevalue =0;//平均值 volatile uint8_t adclen; volatile uint8_t DMA_end = 0; float basicvalue = 3.3;//輸入電壓 float Difference=0;//壓差 float currentvalue=0;//電流 float NTC=0;//NTC阻值 float temp=0;//溫度
int main() { uint8_t i; SetSysClock(CLK_SOURCE_PLL_60MHz); /* 配置串列埠除錯 */ DebugInit(); PRINT("Start @ChipID=%02X\n", R8_CHIP_ID); PRINT("\n4.Diff channel sampling...\n"); GPIOA_ModeCfg(GPIO_Pin_4 | GPIO_Pin_12, GPIO_ModeIN_Floating); ADC_ExtDiffChSampInit(SampleFreq_3_2, ADC_PGA_1_4); ADC_ChannelCfg(0); R8_ADC_CFG|= RB_ADC_BUF_EN; while(1) { for(i = 0; i < 10; i++) { adcBuff[i] = ADC_ExcutSingleConver(); // 連續取樣20次 } for(i = 0; i < 10; i++) { PRINT("%d \n", adcBuff[i]); sum+= adcBuff[i]; } PRINT("sum %f\n",sum); averagevalue = (((sum/10)/512)-4)*1.05; PRINT("average:%f V\n", averagevalue); Difference = basicvalue-averagevalue; PRINT("Difference:%f V\n", Difference); currentvalue = Difference/10000; NTC=averagevalue/currentvalue; PRINT("NTC:%f Ω\n",NTC); // T1 =1/(ln(Rt/R)/B+1/T2)-273.15 temp=1/((log(NTC/10000)/3950)+(1/(273.15+25)))-273.15+0.5; PRINT("temp:%f ℃\n",temp); sum = 0; DelayMs(1000); } }
3、驗證現象:
程式碼列印溫度:
實際溫度:
4:注意事項:
再使用的時候需要使用精度較高的定製電阻,MCU的供電電壓與參考電壓穩定,同時NTC的供電要穩定。
常用溫度阻值對照表:
僅用於個人學習分享;
如有錯漏請指正。