#ifndef __NTC_TY_H #define __NTC_TY_H //#include <STC8HX.h> #include "ADC.h" #ifndef BIAO_PIANYI //阻值表偏移量 #define BIAO_PIANYI 10 #endif float ntcty_read_temp(ADC_Name ntcn,uint8 wei,uint16 cankao); //獲取ntc溫度 uint16 ntcty_read(ADC_Name ntcn,uint8 wei); //ntc轉換取均值一次 float ntcty_gongdian(uint8 ADW);//功能:根據內部參考電壓計算ADC外部參考電壓, float ntcty_ADCdian(ADC_Name ntcn);//根據內部參考電壓計算ADC電壓 //ntc_ty //數據放大1000倍方便整數計算 extern code uint16 ntc_ty[]; //------------------------------------------------------------------------------------------------------------------- // @brief ntc轉換取均值一次 // @param ntcn 選擇ntc通道 // @param wei 讀ADC次數 // @return void // Sample usage: ntc_convert(ntc_P10, 10); //------------------------------------------------------------------------------------------------------------------- uint16 ntcty_read(ADC_Name ntcn,uint8 wei) { uint8 y,i,u; uint16 shuzu[10]; uint16 yaogan_max,yaogan_min,yaogan_sum; y=wei; adc_init(ntcn, ADC_SYSclk_DIV_2, ADC_12BIT); if (ntcn > 15)ntcn = ntcn - 8; for(i=0;i<y;i++) { shuzu[i] = adc_read(ntcn); } for(u=0;u<2;u++)//拋棄最大值和最小值 { yaogan_min = shuzu[0]; yaogan_max = shuzu[0]; for(i=0;i<y;i++) { if(yaogan_max < shuzu[i]) { yaogan_max=shuzu[i]; } if(yaogan_min >= shuzu[i]) { yaogan_min = shuzu[i]; } } for(i=0;i<y;i++) { if(yaogan_max==shuzu[i]) { shuzu[i] =shuzu[y-1] ; break; } } for(i=0;i<y;i++) { if(yaogan_min==shuzu[i] ) { shuzu[i] =shuzu[y-2] ; break; } } y=y-2; } yaogan_sum=0; for(i=0;i<y;i++) { yaogan_sum=yaogan_sum+shuzu[i];//計算剩余AD值的和 } yaogan_sum = yaogan_sum/y;//計算AD平均值 return yaogan_sum;//返回計算的AD平均值 } //*******************************************************************/ //功能:讀ADC電壓值 //形參:無 //返回:電壓值 //詳解:根據內部參考電壓計算ADC電壓, //*******************************************************************/ float ntcty_ADCdian(ADC_Name ntcn)//根據內部參考電壓計算ADC電壓, { uint16 adjg,adck; adjg = ntcty_read(ntcn,6); adck = ntcty_read(ADC_REF,6); return 1.19/adck*adjg; } //*******************************************************************/ //功能:讀供電電壓(ADC外部參考電壓) //形參:ADW:ADC的實際最高位數。12,10,8 //返回:電壓值 //詳解:根據內部參考電壓計算ADC外部參考電壓, //*******************************************************************/ float ntcty_gongdian(uint8 ADW)//功能:根據內部參考電壓計算ADC外部參考電壓, { uint16 adjg; // ntc_init(ADC_REF, ntc_SYSclk_DIV_2); adjg = ntcty_read(ADC_REF,6); switch (ADW) { case 12: return 4095*1.19/adjg; break; case 10: return 2047*1.19/adjg; break; default: return 255*1.19/adjg; break; } } //======================================================================== // 描述: ntc從電阻分度表格里查找最靠近的位置. // 參數: 電阻值*1000. // 返回: 分度表格里最靠近的位置. //======================================================================== uint8 ntcty_find_r(uint16 data) { uint8 start_index, mid = 0, end_index; uint16 dat; start_index = 0; end_index = 50; // 2. 開始二分法查找 while (start_index < end_index) { mid = (end_index + start_index) >> 1; dat = ntc_ty[mid]; if (data < dat) { start_index = mid + 1; } else if (data > dat) { if (mid) { end_index = mid; } else { break; } } else { return (mid); } } return (mid); } //======================================================================== // 描述: 根據查表結果計算溫度. // 參數: 電阻值*1000. // 返回: 溫度. //======================================================================== float ntcty_get_value(uint16 data) { uint8 index; float temp; data = (data > ntc_ty[0]) ? ntc_ty[0] : data; data = (data < ntc_ty[50]) ? ntc_ty[50] : data; index = ntcty_find_r(data); if(ntc_ty[index]>data) { temp = index + (float)(ntc_ty[index]-data)/(ntc_ty[index]-ntc_ty[index+1]);//線性插值 return temp+BIAO_PIANYI-1;//偏移 } else if(ntc_ty[index]<data) { temp = index-(float)(data-ntc_ty[index])/(ntc_ty[index-1]-ntc_ty[index]);//線性插值 return temp+BIAO_PIANYI+1;//偏移 } else { return index+BIAO_PIANYI; } } //======================================================================== // 描述: 獲取ntc溫度. // 參數: None. // 返回: 溫度. //======================================================================== float ntcty_read_temp(ADC_Name ntcn,uint8 wei,uint16 cankao) { float V,V0; V0=ntcty_ADCdian(ntcn);//讀ADC電壓值 V=ntcty_gongdian(wei); //讀供電電壓 V=V/(V0-V)*cankao; V = ntcty_get_value(V*1000);//電阻值放大1000倍查找溫度 V = (int)(10.0 * V + 0.5) / 10.0;//保留一位小數 return V*1.0; } #endif |