栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

单片机ADC消抖处理 温度转换

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

单片机ADC消抖处理 温度转换



目录
  • 前言
  • 滤波
  • 温度转换
    • 硬件简述
    • 温度查找


前言

单片机在实际读取AD值时,读到的值是不稳定的,在不断的变化,如果不经过处理,直接使用,是很难获得其准确的值,因此我们需要对其进行消抖滤波处理。


滤波

一般来说AD值的不稳,我们可以将一段时间读取到的数值取平均值,为了防止数值突变的影响,我们可以减去最大和最小值。

我们10ms读取一次AD值,取10次AD值的平均值即可。

static u16_t s_wMaxAdVal = 0; // AD最大值
static u16_t s_wMinAdVal = 1023; // AD最小值
static u16_t s_wSumAdVal = 0; // AD和
static u16_t s_wAdFiltVal = 0; // 滤波后的值
static u8_t s_nAdCnt = 0;

void AdFilter(u16_t wAdData)
{
  if (wAdData > s_wMaxAdVal)
  {
    wMaxAdVal = wAdData;
  }
  if (wAdData < s_wMinAdVal)
  {
    s_wMinAdVal = wAdData;
  }
  s_nAdCnt++;
  if (s_nAdCnt <= 10)
  {
    s_wSumAdVal += wAdData;
  }
  else
  {
    s_nAdCnt = 0;
    s_wSumAdVal -=  (s_wMaxAdVal + s_wMinAdVal);
    s_wAdFiltVal = s_wSumAdVal >> 3; // 除以8
    
    s_wMaxAdVal = 0;
    s_wMinAdVal = 1023;
    s_wSumAdVal = 0;
  }
}

该函数中s_wAdFiltVal的值即是滤波后的AD值。


温度转换

通常我们可以使用热敏电阻来检测温度,但是热敏电阻的阻值和温度的关系一般不可以通过数学表达式来描述,而是根据热敏电阻的规格书中阻值和温度的关系表来查找。

因此我们需要在程序中编写查找与AD值对应的温度。


硬件简述


简单的分压计算,通过温度与阻值的关系表,计算出温度与AD值关系表。


下面列出一个计算好的关系表:

#define RT_NUM 160
#define MINTEMP 0
const u16_t  wRTtable[RT_NUM] =
{
    
     994,  992, 991,   989,  987,  985,  983,  981,  979,  977,
    
     975,  973,  970,  968,  965,  962,  960,  957,  954,  951,  
 
     947,  944,  941,  937,  934,  930,  926,  922,  918,  913,
 
     909,  905,  900,  895,  890,  885,  880,  875,  870,  864,     
 
     858,  853,  847,  841,  835,  828,  822,  816,  809,  802, 
 
     795,  788,  781,  774,  767,  760,  752,  745,  737,  729, 
 
     721,  713,  705,  697,  689,  681,  673,  665,  656,  648, 
   
     640,  631,  623,  614,  606,  597,  589,  581,  572,  564,  
  
     555,  547,  538,  530,  521,  513,  505,  497,  488,  480,  
  
     472,  464,  456,  448,  440,  433,  425,  417,  410,  402, 
  
     395,  388,  381,  374,  366,  360,  353,  346,  339,  333, 
  
     326,  320,  300,  308,  302,  296,  290,  284,  278,  273, 
  
     267,  262,  257,  251,  246,  241,  236,  232,  227,  222, 
 
     218,  213,  209,  205,  200,  196,  192,  188,  184,  181, 
 
     177,  173,  170,  166,  163,  159,  156,  153,  150,  147, 
     
     144,  141,  138,  135,  132,  130,  127,  124,  122,  119, 
};

注: 温度应该是连续递增的。


温度查找

学过C语言的同学,应该都知道二分法查找,每次将当前的值与目标范围的中间值进行比较,从而不断缩小查找范围,时间复杂度为O( log ⁡ 2 n log_{2}{n} log2​n)

void FindAdcTemp(u16_t wAdcVal, u16_t wTempData)
{
  u8_t nBegin = 0;
  u8_t nEnd= 0;
  u8_t nMiddle = 0;
  
  nEnd = RT_NUM -1;
  if (wAdcVal <= *(wRTtable + nEnd))
  {
    wTempData = RT_NUM + MINTEMP;
  }
  else if (wAdcVal >= *(wRTtable + nBegin))
  {
    wTempData = MINTEMP;
  }
  else 
  {
    while ((nBegin < nEnd) && (wAdcVal != *(wRTtable + nMiddle)))
    {
      nMiddle = nBegin + (nEnd - nBegin)>>1;
      if (wAdcVal > *(wRTtable + nMiddle))
      {
        nEnd = nMiddle - 1;
      }
      else
      {
        nBegin = nMiddle + 1;
      }
    }
    wTempData = MINTEMP + (nBegin -1);
    
    if (wAdcVal < *(wRTtable + nBegin -1))
    {
      wDiffAdcVal = (*(wRTtable + nBegin -1) - wAdcVal)*10;
      wDiffAdcVal /= *(wRTtable + nBegin -1) - *(wRTtable + nBegin);
      if (wDiffAdcVal >= 5) // 四舍五入
      {
        wTempData = MINTEMP + nBegin;
      }
    }
  }
}

我们只要调用FindAdcTemp这个函数,就可以根据当前的AD值,计算得到最接近的温度值。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/692093.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号