用于tiny13小内存cpu进行NTC温度转换的简易算法
(转载)用于tiny13小内存cpu进行NTC温度转换的简易算法
tiny13单片机体积小,功能全,特别适合简单任务应用的场合,例如温度、压力等2-3路参数检测及PWM、开关、电机、风扇、加热等2-3路输出控制的场合,是个头小、功能强的典型代表。但它的内存小是个致命缺点,只有1k的程序空间,设计时要时刻优化内存的使用。
一个典型情况是使用常用的温度测量元件NTC进行温度测量时,由于NTC是非线性元件,温度与电阻变化关系是指数曲线,其典型关系曲线如下:
因此,测量电阻的阻值计算出实际温度,使用类似以下的计算公式:y = -28.5ln(x) + 203.45,对于对数函数计算,在普通单片机中使用C语言编程调用数学函数库进行即可,但使用T13时就不能使用它,例如我用tiny45试了一下,在cvavr环境下只增加一个i=log(x)语句,编译后代码增加了1224个字节。因此,对T13而言,需要数学函数库进行精确计算是不可能任务,并且对于不需要高精度结果的情况下也是不必要的。
工程使用中,对精度要求不是很高时,多采用查表法,或插值计算,代码量小,计算速度快,结果误差是可以接受的。因此在这介绍使用一种分段线性插值的计算算法。
使用条件:
1、10K阻值的NTC,20摄氏度时电阻10K。2、使用75K电阻与NTC串联,加5V电压,单片机ADC测NTC的电压。3、T13设定为1.1V内部电压参考。
使用过程方法:
1、通过计算作出R/T相关性指数曲线,使用多段直线进行模拟拟合,获得与原指数曲线拟合效果最好的几段直线,求取每段直线的函数公式,如下图:
在5v电压下,NTC的理论电压是:Vr=5/(75+Rntc)*Rntc,ADC读数是:1023/1*Vr,我的CPU内部参考电压是1V,如果是1.1V,则为1023/1.1*Vr。
2、取得各段直线分段点数据,及各直线的K、B参数,形成以下表格:
/*
线性函数公式:y=kx+b
折线分段点 k b
496 -0.0425 50.9
281 -0.0692 63.9
195 -0.116 77.4
137 -0.1726 88.5
98 -0.2542 99.7
0 -0.401 113.8
*/
3、构建数组如下及最终计算函数如下:
uint f1[6]={0,98,137,195,281,496}; //分段线性插值端点
uint f2[6]={401,254,173,116,69,43}; //k系数*1000
uchar f3[6]={113,99,88,76,63,50}; //b系数
uchar i;
uint m;
uchar ntc_temp(uint a) { //计算ntc转换温度值,返回2位整数,输入参数a为ADC结果
i=6;
while(i--){if(a>*(f1+i)){ m=f3-a*f2/1000; break;}}
return m;
}
使用cvavr编译后,只占用不到150字节空间。
4、实际工作情况:
通过使用18B20测量结果进行对比,将NTC和18B20在相同环境进行测量对比,结果如下:
18B20 NTC
67 67-68
52 52-53
47 47-48
39 39
35 35
30 30
20 20
13 13
11 11
9 7
部分图片:
6、结论,代码体积小、精度较高,可用于温度范围在10-90度、显示精度为整数、测量精度误差不超过2度的环境,如果扩大测量范围,可根据情况重新计算范围,选定分压电阻值;缺点是由于NTC的离散性,更换NTC时要可能要重新计算各个参数。