搜索
bottom↓
回复: 9

电桥测ntc,ad读到的值如何转换为温度

[复制链接]

出0入0汤圆

发表于 2013-10-27 13:32:59 | 显示全部楼层 |阅读模式
电桥测ntc,ad读到的值如何转换为温度?
MF                             52        103                      H        3435                 F                    A
NTC热敏电阻        环氧系列        电阻值        阻值允差        B值              B值允差        B值类别
                                        10KΩ          ±5%              3435K        ±1%                B25/50
程序应该怎么写

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入663汤圆

发表于 2013-10-27 14:31:57 | 显示全部楼层
基本参数:
B = 3435
R0 = 10K
T0 = 273.15 + 25

预先计算好常数:
r∞ = R0 * e^(-B / T0)

测出NTC电阻值R,通过下式即可换算为温度T:
T = B / ln(R / r∞) - 273.15

如果要求精度较高,还要对T做多点曲线拟合校正。

出0入0汤圆

 楼主| 发表于 2013-10-28 14:16:46 | 显示全部楼层
gzhuli 发表于 2013-10-27 14:31
基本参数:
B = 3435
R0 = 10K

这个算法在单片机中是如何表达呢,有示例程序吗

出0入0汤圆

发表于 2013-10-28 14:29:47 | 显示全部楼层
这是我在网上看到的,测试可以用
#define TEMP_B 3470.0            //热敏电阻的B值
#define TEMP_R 5000.0            //25度时的电阻值

float NTC_Cal_Temp(float R_Value)
{
        float x=0;
        float y=0;

        x = log((R_Value/TEMP_R));
  y = 1/(x/TEMP_B+1/298.15);
  y -= 273.15;

  return y;
}

float NTC_Cal_R(uint32 ADC_Data)
{
  float R_Value;
  float Vr;

  Vr = (ADC_Data / 4096.0) * 6.6;//得到电阻上的分压
  R_Value = (4700.0 * Vr)/(5 - Vr);
  return R_Value;

}

出20入70汤圆

发表于 2013-10-28 14:32:50 | 显示全部楼层
我都是查表的。

先在excel内算好电压对应的采样值(相隔1度),然后再做简单的线性计算。

出20入70汤圆

发表于 2013-10-28 14:34:36 | 显示全部楼层
  1. /*
  2. *******************************************************************************
  3. *                             ntc对应采样电压值数组
  4. *------------------------------------------------------------------------------
  5. * 注释第一行:对应温度
  6. *-------------------------------------------------------------------------------
  7. * 测量温度范围定为-10℃-150℃(可能会有零点几的数据出入)
  8. ********************************************************************************
  9. */
  10. static int16u code ntc_adc[] =
  11. {      
  12.         62454 ,   61415 ,  60359 ,  59286 ,  58199 ,  57098 ,  55985 ,  54862 ,  
  13.         53730 ,   52592 ,  51448 ,  50302 ,  49153 ,  48005 ,  46858 ,  45715 ,  
  14.         44576 ,   43444 ,  42320 ,  41205 ,  40101 ,  39009 ,  37930 ,  36865 ,  
  15.         35816 ,   34783 ,  33767 ,  32769 ,  31790 ,  30829 ,  29889 ,  28968 ,  
  16.         28068 ,   27189 ,  26331 ,  25494 ,  24678 ,  23883 ,  23110 ,  22358 ,  
  17.         21627 ,   20916 ,  20226 ,  19557 ,  18908 ,  18279 ,  17669 ,  17078 ,  
  18.         16506 ,   15952 ,  15416 ,  14898 ,  14396 ,  13912 ,  13444 ,  12991 ,  
  19.         12554 ,   12132 ,  11724 ,  11331 ,  10951 ,  10584 ,  10230 ,   9889 ,  
  20.          9559 ,    9241 ,   8935 ,   8639 ,   8353 ,   8078 ,   7813 ,   7557 ,  
  21.          7310 ,    7072 ,   6842 ,   6620 ,   6407 ,   6201 ,   6002 ,   5810 ,  
  22.          5625 ,    5446 ,   5274 ,   5108 ,   4948 ,   4793 ,   4644 ,   4500 ,  
  23.          4361 ,    4227 ,   4098 ,   3973 ,   3852 ,   3735 ,   3623 ,   3514 ,  
  24.          3409 ,    3308 ,   3210 ,   3115 ,   3024 ,   2936 ,   2850 ,   2768 ,  
  25.          2688 ,    2611 ,   2536 ,   2464 ,   2394 ,   2327 ,   2262 ,   2198 ,  
  26.          2137 ,    2078 ,   2021 ,   1966 ,  
  27. };                                                                                       
  28. #define NTC_ADC_ARRAY_NUM (sizeof(ntc_adc)/sizeof(int16u))
  29. #define INDEX_MAX       NTC_ADC_ARRAY_NUM-2            /* 数组下标的最大可用取值,对应 80℃采样值下标 */
  30. #define INDEX_MIN       2                            /* 数组下标的最小可用取值,对应-10℃采样值下标 */
  31. #define TEMPER_REF      -15                     /* 温度基准点,即下标为0时对应的温度                    */
  32. #define TEMPER_LAST     100                     /* 温度最后值,即数组最后一个对应的温度        */

  33. /*
  34. *******************************************************************************
  35. * 函数名称: search_data()
  36. * 输   入: search_value  查找基准值
  37. * 输   出:
  38. * 作   者:
  39. * 日   期: 2010.08.11
  40. * 功能描述: 二分查找adc采样值
  41. *------------------------------------------------------------------------------
  42. *注     意:
  43. *    1.    返回值为查找表格中第一个小于查找值(search_value)的下标;
  44. *    2.    查找值(search_value)大于查找表格中最大值时,返回1
  45. *          查找值(search_value)小于查找表格中最小值时,返回查找表格数量,即最大下标+1
  46. *******************************************************************************
  47. */
  48. static int16u search_data(int16u search_value)
  49. {
  50.    register int16u  max = NTC_ADC_ARRAY_NUM - 1;
  51.    register int16u  min = 1;
  52.    register int16u  mid;

  53.    while(min <= max)
  54.    {
  55.        mid = (max + min) / 2;

  56.        if(search_value > ntc_adc[mid])
  57.        {
  58.            max = mid - 1;
  59.        }
  60.        else
  61.        {
  62.            min = mid + 1;
  63.        }
  64.    }

  65.    return min;
  66. }

  67. /*
  68. *******************************************************************************
  69. * 函数名称: temper_calc()
  70. * 输   入: index       数组下标
  71. *           adc0_value  ad滤波后的采样值
  72. * 输   出: ntc温度测量值
  73. * 作   者:
  74. * 日   期: 2010.10.26
  75. * 功能描述: 温度计算(分段线性插值算法)
  76. *******************************************************************************
  77. */
  78. static int16s temper_calc(int16u index, int16u adc0_value)
  79. {
  80.         if (index > INDEX_MAX || index < INDEX_MIN)
  81.         {
  82.                 return TEMPER_ERROR;        //  返回错误采样温度
  83.         }
  84. //     else if (index < INDEX_MIN)
  85. //     {
  86. //         return -150;        //  返回-15.0℃
  87. //     }
  88.         else
  89.         {
  90.        /*************************************************
  91.         === 直线近似计算 ===
  92.         y1 = kx1+b       x <-> adc_value
  93.         y2 = kx2+b       y <-> temper
  94.         yn = kxn+b
  95.               y2 - y1     yn - y1
  96.         k  = --------- = ---------
  97.               x2 - x1     xn - x1
  98.               (y2 - y1)*(xn - x1)
  99.         yn = --------------------- + y1
  100.                     (x2 - x1)
  101.         *************************************************/

  102.        int16s temper;
  103.                                        
  104.        temper  = 10*(ntc_adc[index-1] - adc0_value);   //  放大10倍,temper放大10倍
  105.        temper /= (ntc_adc[index-1] - ntc_adc[index]);  //  (xn - x1)
  106.        temper += 10*(index + TEMPER_REF - 1);
  107.       
  108.        return temper;            
  109.         }      
  110. }

  111. /*
  112. *******************************************************************************
  113. * 函数名称: adc0_battery_temper_calc()
  114. * 输   入: adc0_sample_num            ad采样次数
  115. *           adc0_sample_sum                ad采样总和
  116. * 输   出:
  117. * 作   者:
  118. * 日   期: 2011.11.23
  119. * 功能描述: 输出220V电压计算
  120. *******************************************************************************
  121. */
  122. void adc0_battery_temper_calc(int16u adc_value)
  123. {                     
  124.         register int16s temper;              // 温度值
  125.         register int16u index;               // 查表下标值

  126.         index  = search_data(adc_value);                     // 取温度数组下标
  127.         temper = temper_calc(index, adc_value);              // 温度计算

  128.         battery_sample.battery_temper = temper;  
  129. }
复制代码

出0入663汤圆

发表于 2013-10-28 16:53:45 | 显示全部楼层
cityfuture 发表于 2013-10-28 14:16
这个算法在单片机中是如何表达呢,有示例程序吗

4L的算法和我的公式是等效的,对于单片机来说鸭梨最大的就是log()和浮点除法运算,至于变通办法就只能自己发挥了。

出0入0汤圆

发表于 2013-10-29 17:23:06 | 显示全部楼层
拟合,分段线性或者用公式都可以

出0入0汤圆

发表于 2013-10-27 13:33:00 | 显示全部楼层
本帖最后由 lmt50211 于 2013-10-31 13:57 编辑

uchar code table_temp[]=//定义温度数据表
{
42, 44, 45, 47, 49, 51, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 79,
81, 83, 85, 87, 90, 92, 94, 96, 99,101,103,106,108,110,112,115,117,119,122,124,
126,129,131,133,135,138,140,142,144,146,148,150,151,155,157,159,161,163,165,167,
169,171,173,174,176,178,180,182,183,185,187,188,190,191,193,194,196,197,199,200,
201,203,204,205,206,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
};
//====================================================================
//===          温度转换函数          ===//
void temp_process(void)
{
        uchar i;
                r_temp_adc=adc_conver();      //ADC转换
        if(r_temp_adc>=223)              //开路判断
        {
                r_temp_room=100;
        }
        else if(r_temp_adc<=42)          //短路判断
        {
                r_temp_room=0;       
                }
        else
        {               
                     while(r_temp_adc>=table_temp)//比较采集AD值和表格温度点值,以判断出温度
                {
                        i++;       
                }       
                r_temp_room=i;            //查表计算温度值
        }       
}
这个方法精度比较低,表格也会比较大,但用于精度要求不高的地方还是很有优势的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-10-31 15:19:09 | 显示全部楼层
我觉得查表法最简单的了,把数值放到数组里对比一下就可以的了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 14:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表