关于二分法 与分段线性化查表法 ,欢迎探讨 这个表用在K型热电偶温度测量上
1,、二分法举个例子:
我的理解 顺序表(2、5、7、10、14、15、18、 23 、35、 41 、 52)
找出12的位置
查4次,先和中间数15比,比15小
在和前半段中间数7比:比7大
只剩俩数了,和10比:比10大,
和14比:比14小
2、线性分段
公式为 Y=2T+ n (n=0 、1 、2 、3 、 4.......54)
这个公式是用AD值算温度的Y为AD值,T温度
列出每个分段的
n Y
0 2~43
1 44~70
2 71~91
3 92~110
4 111~129
比如 Y= 94
查的过程:1、 和中间数71比:比71大 2、 和后半段中间数91比:比91大
那么在表 3 中
则n=3 T=(94-3)/2=45.5 按分度表计算这是对的
我将K型分度放大250倍,用10位ADREF=5V ,分成1024份
-----------------------------------------
T K K*250 AD=y
-----------------------------------------
1 0.039 9.75 2
2 0.079 19.75 4.0448
3 0.119 29 6.0928
4 0.158 39.75 8.1408
5 0.198 49.5 10.1376
6 0.238 59.5 12.1856
7 0.277 69.25 14.1824
8 0.317 79.25 16.2304
9 0.357 89.25 18.2784
10 0.397 99.25 20.3264
11 0.437 109.25 22.3744
12 0.477 119.25 24.4224
13 0.517 129.25 26.4704
14 0.557 139.25 28.5184
15 0.597 149.25 30.5664
16 0.637 159.25 32.6144
17 0.677 169.25 34.6624
18 0.718 179.5 36.7616
19 0.758 189.5 38.8096
20 0.798 199.5 40.8576
21 0.838 209.5 42
21.5 43
N=0 Y=2T+0
-------------------------------------
21.5 44
22 0.879 219.75 45
23 0.919 229.75 47.0528
24 0.96 240 49.152
25 1 250 51.2
26 1.041 260.25 53.2992
27 1.081 270.25 55.3472
28 1.122 280.5 57.4464
29 1.163 290.75 59.5456
30 1.203 300.75 61.5936
31 1.244 311 63.6928
32 1.285 321.25 65.792
33 1.326 331.5 67.8912
34 1.366 341.5 69.9
34.5 70
N=1Y=2T+1
---------------------------------------
34.5 71
35 1.407 351.75 72.03
36 1.448 362 74.1376
37 1.489 372.25 76.2368
38 1.53 382.5 78.336
39 1.571 392.75 80.4352
40 1.612 403 82.5344
41 1.653 413.25 84.6336
42 1.694 423.5 86.7328
43 1.735 433.75 88.832
44 1.776 444 90.9
44.5 91
N=2 Y=2T+2
-----------------------------------------
44.5 92
45 1.817 454.25 93.03
46 1.858 464.5 95.1296
47 1.899 474.75 97.2288
48 1.941 485.25 99.3792
49 1.982 495.5 101.4784
50 2.023 505.75 103.5776
51 2.064 516 105.6768
52 2.106 526.5 107.8272
53 2.147 536.75 109.9
53.5 110
N=3 Y=2T+3
----------------------------------------
53.5 111
54 2.188 547 112.0256
这个表加工过将段与段 连续起来,计算只做整数部分!
看了不不少做热电偶 线性化的期刊文献,似乎没看见这样做的,但我觉得可以
有做过类似的东西的欢迎指导! 个人认为二分法比较容易编程.特别是对应于热电耦的查表.
而且,查表的结果可能还要线性化插值,最后得出一个对应的温度值. 回复【1楼】ywl0409 老黄牛
-----------------------------------------------------------------------
恩是这样的,我的做法是直接求得温度,并且能够完全与热电偶分度表对应上,并不需要插值的计算 void check(int *a ,int l ,int h, int value)
{
int mid;
mid=(h+l)/2;
if(l<=h)
{
if(value>a)
{
l=mid+1;
check(a,l,h,value);
}
else if(value<a)
{
h=mid-1;
check(a,l,h,value);
}
else if(value==a)
{
printf("Find\n");
exit(0) ;
}
printf("Not Find\n");
exit(0);
}
}
int main(int argc, char* argv[])
{
int a={2,44,71,92,111};
int low,high;
int n;
low=2;
high=111;
printf("输入要查找的ad值:\n");
scanf("%d",&n);
check(a,low,high,n);
//high=sizeof(a)/sizeof(int);
return 0;
}
二分法 学习。 别沉下去哦 学习 我觉得最后总要插值的,要不然就需要去分析靠近哪个值.
分度表只是给出两个对应的温度点的电压值,比如1度对应39.9uV,0度对应0V.
那么,如果当你的测量电压是20.7uV的时候,就需要去插值计算,或者根据你的要求,去靠近1度或者0度了. LS可能理解的不很明确,AD值从0~ 1023 都能转成相应的温度值的。AD值取整,温度能精确到0.5℃对于一般的系统是够用的了 那还是根据你AD转换来的电压精度来换算的.
按照你的做法,就是如果电压值落在了两个相邻的数据之间,那就是0.5度了.
我估计,要想正好获得和分度表中的数据一样的电压值是不太容易的.总有可能会有偏差.这还是和你的AD转换精度有关.
比如,你在1度的时候,采集到的电压值不会正好是39.9uV,那么就会得到0.5度或者1.5度的输出了.
可以这样理解吗? 回复【9楼】ywl0409 老黄牛
我估计,要想正好获得和分度表中的数据一样的电压值是不太容易的.总有可能会有偏差
-----------------------------------------------------------------------
恩 是这样,最开始我就是这样认为的,后来发现 AD值的整数部分与温度值的线性真的很好,才想出这样的办法,精度好坏那要看AD的了,至于插值我老感觉很麻烦 回复【9楼】ywl0409 老黄牛
-----------------------------------------------------------------------
很感谢对这个帖子的关注,和对这个问题的意见,我现在在做一个M16恒温焊台,传感器是K偶,补偿用18B20,1602显示。硬件部分焊接完了
程序部分 就差这个查表程序了
http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_552369.jpg
(原文件名:截图00.jpg)
多提意见 K型热电偶?是不是T12系列的一体头? 嗯,你的用途是在测量烙铁温度上.
那么,也许你的最高温度设在500度的话,那么你的1LSB就对应0.5度,那是不需要插值来计算的.
而且,这里计算出来的0.5度也根本不需要考虑进去的. 回复【13楼】ywl0409 老黄牛
-----------------------------------------------------------------------
是这样的。要真能达到0.5的精度就挺好的了
回复【12楼】zzy9903 9903
-----------------------------------------------------------------------
烙铁头是国产A1322 一体;它的是K热电偶的 看到了,貌似这个A1322与T12都差不多,都是用的K型热电偶,不过一个是分体另一个是一体,我也想做一个焊台,无奈水平不济,目前正在收集资料与学习中,上面的电路图太小了,看不清,能否给个大图学习一下?谢谢 回复【15楼】zzy9903 9903
-----------------------------------------------------------------------
图画的不咋地,随手画画有的地方有错误没来得及改、、 争取月内做好后 电路代码全部公开 奥,好的,期待楼主的大作 楼主的QQ多少,我想和你一起讨论 一、
const unsigned char a=; //用每个线性分段开头的数建的表1
const unsigned char b=; //用每个线性分段尾数的数建的表2
for (i=0;i<5;i++)
{
uchar t,ad;
ad=get_ad();
if(a<=ad)
if(ad<=b)
{
t=( ad - i ) / 2;
}
}
二、
const unsigned charTEMP_AD={2,44,71,92,111 }//用每个线性分段开头的数建的表
for (i=0;i<5;i++)
{
ad=get_ad(); // 取得AD值
if(TEMP_AD<=ad)
if(ad<TEMP_AD)
t=( ad - i ) / 2;
break;
}
我的意图:将AD值取出,如果这个值在某一范围内,那么它在这个分段上,这个分段函数(AD=2t+n)的n就是这个范围所对应的指针(i)。
得到i值,因为我要用这个 i 值 进行计算。
t=( AD值 - i ) / 2; 是我要计算的公式
我写了两段两种想法,不知对不对 请帮看下那种合理有错误请纠正,我qq93307969 加你QQ了,没有回音 mark! 我现在出来办点事,下午回来加你 归来 了,谁在帮看看19L这么写怎么样?并没用二分法,是查每一分段的第一个数,后带入线性公式计算,条件什么的在1L #include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
unsigned charTEMP_AD=
{ 0, 44, 71, 92,111,130,147,162,179,196,
215,234,253,278,305,342,383,430,467,498,
523,546,567,586,605,624,641,658,673,690,
705,720,735,748,763,778,791,806,819,832,
845,858,873,886,897,910,923,936,947,960,
973,984,997,1010,1021};//用每个线性分段开头的数建的表
void main(void)
{
while(1)
{
uchar i;
for (i=0;i<56;i++)
{
uint ad,t;
ad=ADC_convert(); // 取得AD值
if(ad>=TEMP_AD)
{
if(ad<TEMP_AD)
{
t=(ad-i-1)/2;
break;
}
}
}
}
} 我写的软件,数据拟合,然后直接查表就可以了,省去了二分查表的麻烦。
数据拟合功能就是为了干这个用的!
软件在我的资料中自己找,代码写下:
unsigned char Tables = {
0u,//(0.000, 0.054)
0u,//(16.238, 0.228)
1u,//(32.476, 0.567)
1u,//(48.714, 1.057)
2u,//(64.952, 1.683)
2u,//(81.190, 2.422)
3u,//(97.429, 3.254)
4u,//(113.667, 4.154)
5u,//(129.905, 5.100)
6u,//(146.143, 6.069)
7u,//(162.381, 7.043)
8u,//(178.619, 8.003)
9u,//(194.857, 8.934)
10u,//(211.095, 9.824)
11u,//(227.333, 10.665)
11u,//(243.571, 11.449)
12u,//(259.810, 12.174)
13u,//(276.048, 12.839)
13u,//(292.286, 13.445)
14u,//(308.524, 13.997)
14u,//(324.762, 14.500)
15u,//(341.000, 14.961)
15u,//(357.238, 15.389)
16u,//(373.476, 15.793)
16u,//(389.714, 16.183)
17u,//(405.952, 16.568)
17u,//(422.190, 16.960)
17u,//(438.429, 17.366)
18u,//(454.667, 17.796)
18u,//(470.905, 18.257)
19u,//(487.143, 18.757)
19u,//(503.381, 19.301)
20u,//(519.619, 19.894)
21u,//(535.857, 20.537)
21u,//(552.095, 21.234)
22u,//(568.333, 21.984)
23u,//(584.571, 22.786)
24u,//(600.810, 23.639)
25u,//(617.048, 24.539)
25u,//(633.286, 25.483)
26u,//(649.524, 26.466)
27u,//(665.762, 27.483)
29u,//(682.000, 28.530)
30u,//(698.238, 29.601)
31u,//(714.476, 30.693)
32u,//(730.714, 31.801)
33u,//(746.952, 32.922)
34u,//(763.190, 34.054)
35u,//(779.429, 35.196)
36u,//(795.667, 36.348)
38u,//(811.905, 37.510)
39u,//(828.143, 38.685)
40u,//(844.381, 39.876)
41u,//(860.619, 41.087)
42u,//(876.857, 42.320)
44u,//(893.095, 43.579)
45u,//(909.333, 44.866)
46u,//(925.571, 46.180)
48u,//(941.810, 47.518)
49u,//(958.048, 48.870)
50u,//(974.286, 50.223)
52u,//(990.524, 51.552)
53u,//(1006.762, 52.824)
54u,//(1023.000, 53.992)
};
计算:
inline unsigned char GetValue(unsigned int ADC){ //ADC是你的采样值
return Tables[(unsigned char)(ADC>>4)];
}
使用AVR和GCC编译器的话,将上述东西分配到Flash中,并用pgm_read_uchar,这里不具体分析了。 回复【24楼】qwt950
-----------------------------------------------------------------------
对于K偶这段代码在实际的系统当中测试通过,完全能将检测的AD值与温度值吻合起来!!
相对于600*2个数的顺序查表 节省了大量存贮空间,同样节省了查表的时间!
这种方法用的不是二分法与题目相违、、 我用proteus仿真了 lz的这个算法,很是准确,非常棒~~
有一事不明,望LZ赐教AD=y,y值是如何得来,不应该是直接对应AD值吧? 回复【27楼】Soul.art 单片猪
-----------------------------------------------------------------------
是AD采集的值0--1024,计算得到的是带有小数的 我只取的整数部分 毕业了,今天再次来到这里,有些伤感心酸!在这里我学到了很多! 24L 这段代码的由来很巧合,是将热点偶信号放大250倍后,将电压值转化为AD值,才能使 AD值与温度值满足这样的关系! 我做的设计已经算是基本完成,实物做出来了可以恒温,但输出不是数字PID的,一大遗憾啊明天传上来 点击此处下载 ourdev_564376HBTIOH.rar(文件大小:2.49M) (原文件名:设计.rar)硬件电路设计
点击此处下载 ourdev_564377DPA7FB.rar(文件大小:288K) (原文件名:恒温控制程序.rar)
输出本应该用PID的可最终没能实现,用开关量进行控制,有继续做的把这里改善一下! 楼主的设计很好,在学校里就有这个水平相当不错了!
谢谢你的资料 好贴 mark 学习 谢谢你的无私奉献 mark mark 楼主你好,请问你有没有做过更高精度的温度测量,你做过的最高测温精度能达到多少? 楼主,希望能加你QQ,向你请教几个问题。我的QQ:993698637 学习啦不错的东西 那我用的是AD7135,89C51处理,1602显示,程序怎么弄啊,我实在弄不来,LZ帮帮忙把 希望LZ帮帮忙,QQ:51071930 好资料 记号 很好 很值得研究一下 mark 直接用公式计算,我做过温度变送器,公式计算最准准确。温度变送器的要求比你这个高多了。 mark 标记以后学习 楼主资料弄的很详细,学习了 标记以后学习
页:
[1]