#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 |