找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5061|回复: 3
打印 上一主题 下一主题
收起左侧

通过温湿度传感器HTU20D来加深理解分辨率和精度

[复制链接]
跳转到指定楼层
楼主
ID:108935 发表于 2016-3-15 02:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    昨天有人反应我写的错别字太多,那我恭喜你看明白了我想表达的意思,只要是我偏科偏得厉害。

言归正传啊!
       最近做的这个基于卫星定位的便携式污染源监测系统,对温湿度要有高了些,对价格也比较敏感,所以对温湿度的选择比较慎重了些。顺便我有分析了下,AD的精度和分辨率的问题:

很多人对于精度和分辨率的概念不清楚,这里我做一下总结,希望大家不要混淆。

像我们搞电子的,经常跟“精度”与“分辨率”打交道。简单点说,“精度”是用来描述物理量的准确程度的,而“分辨率”是用来描述刻度划分的。从定义上看,这两个量应该是风马牛不相及的。我是这么理解的,“精度”就是描述物理量 的精确程度的,也就是我们常说的准不准的问题,或者说与真实值差多少的问题;“分辨率”是用来表述分辨能力的,分辨能力强的未必测试的准确,比如说温度变化多少时它能分辨出来。
        在简单做个比喻:有这么一把常见的塑料尺(中学生用的那种),它的量程是10厘米,上面有100个刻度,最小能读出1毫米的有效值。那么我们就说这把尺子的分辨率是1毫米,或者量程的1%;而它的实际精度就不得而知了(算是0.1毫米吧)。当我们用火来烤一下它,并且把它拉长一段,然后再考察一下它。我们不难发现,它还有有100个刻度,它的“分辨率”还是1毫米,跟原来一样!然而,您还会认为它的精度还是原来的0.1毫米么?(这个例子是引用网上的,个人觉得比喻的很形象!)


回到电子技术上,
所以很多朋友一谈到精度,马上就和分辨率联系起来了,包括有些项目负责人,只会在那里说:这个系统精度要求很高啊,你们AD的位数至少要多少多少啊
其实,仔细浏览一下AD的数据手册,会发现跟精度有关的有两个很重要的指标:DNL和INL。似乎知道这两个指标的朋友并不多,所以在这里很有必要解释一下。
DNL:Differencial NonLiner——微分非线性度
INL:Interger NonLiner——积分非线性度(精度主要用这个值来表示)
他表示了ADC器件在所有的数值点上对应的模拟值,和真实值之间误差最大的那一点的误差值。也就是,输出数值偏离线性最大的距离。单位是LSB(即最低位所表示的量)。当然,像有的AD如△—∑系列的AD,也用Linearity error来表示精度。

分辨率的计算:测量电压范围/(2^AD位数-1)

就HTU20D温湿度传感器来说:
温度部分:

由上图不难看出,在14bit时,HTU20D传感器的温度部分的分辨率是0.01°C,在12bit时,温度的分辨率是0.04°C。这里的14bit与12bit就是设定的AD转换的位数啊。但是大家看看表中给出的温度的“精度(Temperature Accuracy@25°C)”是±0.3°C,不管你在设置AD转换位数是14位还是12位时,传感器本身的精度数不变的,0.3就是0.3°C。所以精度和分辨率是两个完全不同的我概念。

下面再看看湿度吧

       HTU20D湿度的的“分辨率”是,在12bits时为0.04%RH; 在8bits时 0.7%RH,
那么他的“精度”总是±3%RH,   如此看来分辨率和精度真的是不同了,呵呵   大家再想想,同是在一个传感器中的温度和湿度两个物理量的温度的精度是±0.3,而湿度的精度是±3  。对吧
你在看看上面的两个表格,如果吧温度和湿度都设置是12bit时,他们的分辨率是相同的,都是0.04,不是吗?你在仔细看看
至于0.04这个数是如何来的呢!  你知道吗?  考虑考虑吧,

下面我给出我的读写HTU20D/HTU21D的程序仅供参考,不过我在项目中应用过了,还没发现有什么问题呢
/*================================================================
【名 称】void I2CDelay (unsigned char t)
【功 能】模拟IIC用的短延时
【备 注】
【作 者】
【时 间】2015年10月18日
================================================================*/
void I2CDelay (unsigned char t)
{
while(t--);
}
/*================================================================
【名 称】void I2CInit(void)
【功 能】I2C初始化,空闲状态
【备 注】
【作 者】
【时 间】2015年10月18日
================================================================*/
void I2CInit(void)
{
SDA = 1;
SCL = 1;
}

/*================================================================
【名 称】void I2CStart(void)
【功 能】I2C起始信号
【备 注】SCL、SDA同为高,SDA跳变成低之后,SCL跳变成低
【作 者】
【时 间】2015年10月18日
================================================================*/
void I2CStart(void)
{
   SDA = 1;
   SCL = 1;
   I2CDelay(10);
   SDA = 0;
   I2CDelay(20);
   SCL = 0;
   I2CDelay(20);
}
/*================================================================
【名 称】void I2CStop(void)
【功 能】I2C停止信号
【备 注】SCL、SDA同为低,SCL跳变成高之后,SDA跳变成高
【作 者】
【时 间】2015年10月18日
================================================================*/
void I2CStop(void)
{
   SDA = 0;
   SCL = 0;
I2CDelay(10);
   SCL = 1;
   I2CDelay(10);
   SDA = 1;
   I2CDelay(10);
}

/*================================================================
【名 称】unsigned char I2CWRByte(unsigned char WRByte)
【功 能】I2C写一个字节数据,返回ACK或者NACK
【备 注】从高到低,依次发送
【作 者】
【时 间】2015年10月18日
================================================================*/
unsigned char I2CWRByte(unsigned char WRByte)
{
unsigned char i;
SCL = 0;
for(i=0;i<8;i++)
{
  if(WRByte&0x80)
  {
   SDA = 1;
  }
  else
  {
   SDA = 0;
  }
  I2CDelay(10);
  SCL=1;   //输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样
  I2CDelay(50);
  SCL=0;
  I2CDelay(10);
  WRByte <<= 1;
}
SDA = 1;
SCL = 1;
I2CDelay(20);
if(SDA==1)   //SDA为高,收到NACK
{
  SCL=0;
  I2CDelay(50);
  return NACK;
}
else     //SDA为低,收到NACK
{
  SCL=0;
  I2CDelay(50);
  return ACK;
}
}

/*================================================================
【名 称】unsigned char I2CRDByte(unsigned char AckValue)
【功 能】I2C读一个字节数据,入口参数用于控制应答状态,ACK或者NACK
【备 注】从高到低,依次接收
【作 者】
【时 间】2015年10月18日
================================================================*/
unsigned char I2CRDByte(unsigned char AckValue)
{
unsigned char i,RDByte=0;
SCL = 0;
SDA = 1;   //释放总线
for (i=0;i<8;i++)
{
  RDByte <<= 1; //移位
  SCL = 1;  //给出上升沿
  I2CDelay(30); //延时等待信号稳定
  if(SDA==1)   //采样获取数据
  {
   RDByte |= 0x01;
  }
  else
  {
   RDByte &= 0xfe;
  }
  SCL = 0;     //下降沿,从机给出下一位值
  I2CDelay(10);
}   
SDA =  AckValue; //应答状态
I2CDelay(10);
SCL = 1;                        
   I2CDelay(50);         
   SCL = 0;
   SDA = 1;               
   I2CDelay(1);
return RDByte;
}
/*================================================================
【名 称】void HTU21Init(void)
【功 能】HTU21初始化函数,主函数中调用
【备 注】从高到低,依次接收
【作 者】
【时 间】2015年10月18日
================================================================*/
void HTU21Init(void)
{
I2CInit();//I2C初始化
I2CStart();//启动I2C
I2CWRByte(HTU21ADDR&0xfe);//写HTU21I2C地址
I2CWRByte(0xfe);
I2CStop();//停I2C
Delay(600);//短延时
}

/*================================================================
【名 称】long ReadHtu21(char whatdo)
【功 能】读取函数函数
【备 注】
【作 者】
【时 间】2015年10月18日
================================================================*/
long ReadHtu21(char whatdo)
{
unsigned long temp;
unsigned char Humidity,HumidityH,HumidityL;
unsigned long wendu;
I2CStart();
if(I2CWRByte(HTU21ADDR&0xfe)==ACK)
{
  if(I2CWRByte(whatdo)==ACK)
  {
   do
   {
    Delay(30);
    I2CStart();
   }while(I2CWRByte(HTU21ADDR|0x01)==NACK);
   HumidityH = I2CRDByte(ACK);
   HumidityL = I2CRDByte(ACK);
   I2CRDByte(NACK);
   I2CStop();   
   HumidityL &= 0xfc;
   temp = HumidityH*256+HumidityL;
   
   if (whatdo==((char)0xf5))
   {
    Humidity = (unsigned char)((temp*125)/65536-6)%0xff;   
    return Humidity;
   }
   else
   {
    temp=((long)17572)*temp;
    temp=temp/((long)65536);
    wendu =temp-((long)4685);
    return wendu;  //输出
   }  
  }
}
return 0;
}
你如果感觉有收获就分享给更多的朋友吧,或者你把你的心得体会也分享给我和他。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:204196 发表于 2018-2-28 11:25 | 只看该作者
收藏,挺好的资料!
回复

使用道具 举报

板凳
ID:126422 发表于 2018-5-29 19:58 | 只看该作者
买了一片测试,温、湿度显示,变化按+/-0.5变化,不是线性变化,大家遇到过吗。
回复

使用道具 举报

地板
ID:389478 发表于 2018-12-6 00:53 | 只看该作者
lijn 发表于 2018-5-29 19:58
买了一片测试,温、湿度显示,变化按+/-0.5变化,不是线性变化,大家遇到过吗。

我的是+-0.7度,换SHT20就正常,用HTU20D就是+-0.7度,不理解为啥这样。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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