历史上的今天
返回首页

历史上的今天

今天是:2025年01月02日(星期四)

正在发生

2018年01月02日 | 存储器功能的数字温度计-DS1624技术应用与原理分析

2018-01-02 来源:eefocus

1.DS1624基本原理
   DS1624是美国DALLAS公司生产的集成了测量系统和存储器于一体的芯片。数字接口电路简单,与I2C总线兼容,且可以使用一片控制器控制多达8片的DS1624。其数字温度输出达13位,精度为0.03125℃。DS1624可工作在最低2.7V电压下,适用于低功耗应用系统。


(1).DS1624基本特性
⊕.无需外围元件即可测量温度
⊕.测量范围为-55℃~+125℃,精度为0.03125℃
⊕.测量温度的结果以13位数字量(两字节传输)给出
⊕.测量温度的典型转换时间为1秒        
⊕.集成了256字节的E2PROM非易性存储器
⊕.数据的读出和写入通过一个2-线(I2C)串行接口完成
⊕.采用8脚DIP或SOIC封装,如图2.34.1
带有存储器功能的数字温度计-DS1624技术应用
    图2.34.1
(2).引脚描述及功能方框图
带有存储器功能的数字温度计-DS1624技术应用
其引脚描述如表1所示:
DS1624的功能结构图如图4.34.2所示:
带有存储器功能的数字温度计-DS1624技术应用
图4.34.2
(3).DS1624工作原理
温度测量
图4.34.3是温度测量的原理结构图
带有存储器功能的数字温度计-DS1624技术应用
          图4.34.3 温度测量的原理结构图
  DS1624在测量温度时使用了独有的在线温度测量技术。它通过在一个由对温度高度敏感的振荡器决定的计数周期内对温度低敏感的振荡器时钟脉冲的计数值的计算来测量温度。DS1624在计数器中预置了一个初值,它相当于-55℃。如果计数周期结束之前计数器达到0,已预置了此初值的温度寄存器中的数字就会增加,从而表明温度高于-55℃。
  与此同时,计数器斜坡累加电路被重新预置一个值,然后计数器重新对时钟计数,直到计数值为0。
通过改变增加的每1℃内的计数器的计数,斜坡累加电路可以补偿振荡器的非线性误差,以提高精度,任意温度下计数器的值和每一斜坡累加电路的值对应的计数次数须为已知。
  DS1624通过这些计算可以得到0.03125℃的精度,温度输出为13位,在发出读温度值请求后还会输出两位补偿值。表2给出了所测的温度和输出数据的关系。这些数据可通过2线制串行口连续输出,MSB在前,LSB在后。
表2 温度与输出数据关系表

  由于数据在总线上传输时MSB在前,所以DS1624读出的数据可以是一个字节(分辨率为1℃),也可以是两个字节,第二个字节包含的最低位为0.03125℃。
表2是13位温度寄存器中存储温度值的数据格式

  其中 S-为符号位,当S=0时,表示当前的测量的温度为正的温度;当S=1时,表示当前的测量的温度为负的温度。B14-B3为当前测量的温度值。最低三位被设置为0。
DS1624工作方式
DS1621的工作方式是由片上的配置/状态寄存器来决定的,如表4,该寄存器的定义如下:


  其中DONE为转换完成位,温度转换结束时置1,正在进行转换时为0;1SHOT为温度转换模式选择。1SHOT为1时为单次转换模式,DS1624在收到启动温度转换命令EEH后进行一次温度转换。1SHOT为0时为连续转换模式,此时DS1624将连续进行温度转换,并将最近一次的结果保存在温度寄存器中。该位为非易失性的。
片内256字节存储器操作
  控制器对DS1624的存储器编程有两种模式:一种是字节编程模式,另一种是页编程模式。
  在字节编程模式中,主控制器发送地址和一个字节的数据到DS1624。
  在主器件发出开始(START)信号以后,主器件发送写控制字节即1001A2A1A00(其中R/W控制位为低电平“0”)。指示从接收器被寻址,DS1624接收后应答,再由主器件发送访问存储器指令(17H)后,DS1624接收后应答,接着由主器件发送的下一个字节字地址将被写入到DS1624的地址指针。主器件接收到来自DS1624的另一个确认信号以后,发送数据字节,并写入到寻址的存储地址。DS1624再次发出确认信号,同时主器件产生停止条件STOP,启动内部写周期。在内部写周期DS1624将不产生确认信号。
在页编程模式中,如同字节写方式,先将控制字节、访问存储器指令(17H)、字地址发送到DS1624,接着发N个数据字节,其中以8个字节为一个页面。主器件发送不多于一个页面字节的数据字节到DS1624,这些数据字节暂存在片内页面缓存器中,在主器件发送停止信号以后写入到存储器。接收每一个字节以后,低位顺序地址指针在内部加1。高位顺序字地址保持为常数。如果主器件在产生停止条件以前要发送多于一页字的数据,地址计数器将会循环,并且先接收到的数据将被覆盖。像字节写操作一样,一旦停止条件被接收到,则内部写周期将开始。
存储器的读操作
  在这种模式下,主器件可以从DS1624的EEPROM中读取数据。主器件在发送开始信号之后,主器件首先发送写控制字节1001A2A1A00,主器件接收到DS1624应答之后,发送访问存储器的指令(17H),收到DS1624的应答之后,接着发送字地址将被被写入到DS1624的地址指针。这时DS1624发送应答信号之后,主器件并没有发送停止信号,而是重新发送START开始信号,接着又发送读控制字节1001A2A1A01,主器件接收到DS1624应答之后,开始接收DS1624送出来的数据,主器件每接收完一个字节的数据之后,都要发送一个应答信号给DS1624,直到主器件发送一个非应答信号或停止条件来结束DS1624的数据发送过程。
DS1624的指令集
  数据和控制信息的写入读出是以表5和表6所示的方式进行的。在写入信息时,主器件输出从器件(即DS1624)的地址,同时R/W位置0。接收到响应位后,总线上的主器件发出一个命令地址,DS1624接收此地址后,产生响应位,主器件就向它发送数据。如果要对它进行读操作,主器件除了发出命令地址外,还要产生一个重复的启动条件和命令字节,此时R/W位为1,读操作开始。下面对它们的命令进行说明。
  访问存储器指令[17H]:该指令是对DS1624的EEPROM进行访问,发送该指令之后,下一个字节就是被访问存储器的字地址数据。
  访问设置寄存器指令[ACH]:如果R/W位置0,将写入数据到设置寄存器。发出请求后,接下来的一个字节被写入。 如果R/W位置1,将读出存在寄存器中的值。
  读温度值指令[AAH]:即读出最后一个测温结果。DS1624产生两个字节,即为寄存器内的结果。
  开始测温指令[EEH]:此命令将开始一次温度的测量,不需再输入数据。在单次测量模式下,可在进行转换的同时使DS1624保持闲置状态。在连续模式下,将启动连续测温。
  停止测温指令[22H]:该命令将停止温度的测量,不需再输入数据。此命令可用来停止连续测温模式。发出请求后,当前温度测量结束,然后DS1624保持闲置状态。直到下一个开始测温的请求发出才继续进行连续测量。


2. 实验任务
 用一片DS1624完成本地数字温度的测量,并通过8位数码管显示出测量的温度值。其硬件电路图如图4.34.4所示
3.电路原理图
带有存储器功能的数字温度计-DS1624技术应用
                     图4.34.4
4.系统板上硬件连线
(1).把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“动态数码显示”区域中的ABCDEFGH端子上。
(2).把“单片机系统”区域中的P2.0-P2.7用8芯排线连接到“动态数码显示”区域中的S1S2S3S4S5S6S7S8端子上。
(3).把DS1624芯片插入到“二线总线模块”区域中的8脚集成座上,注意芯片不插反。
(4).把“二线总线模块”区域中的PIN1 PIN2分别用导线连接到“单片机系统”区域中的P1.6和P1.7端子上。
(5).把“二线总线模块”区域中的PIN4 PIN5 PIN6分别用导线连接到“电源模块”区域中的GND端子上。
5.程序设计内容
(1)由于DS1624是I2C总线结构的串行数据传送,它只需要SDA和SCL两根线完成数据的传送过程。因此,我们在进行程序设计的时候,也得按着I2C协议来对DS1624芯片数据访问。有关I2C协议参看有关资料,这里不详述。对于AT89S51单片机本身没有I2C硬件资源,所以必须用软件来模拟I2C协议过程。
(2)要从DS1624中读取温度值,首先启动DS1624的内部温度A/D开始转换,对应着有相应的命令用来启动开始温度转换,有关DS1624的指令集参考前面的叙述。一般情况下,DS1624经过一次温度的变换,需要经过1秒钟左右的时间,所以等待1秒钟后,即可读取内部的温度值,对于读取的温度值,仍然通过DS1624的指令集来完成温度的读取。但所有有数据的传送过程必须遵循I2C协议。
6.C语言源程序
#include
#include
unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7,
                                 0xef,0xdf,0xbf,0x7f};
unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f,
                                    0x66,0x6d,0x7d,0x07,
                                    0x7f,0x6f,0x77,0x7c,
                                    0x39,0x5e,0x79,0x71,0x00};
unsigned char code dotcode[32]={0,3,6,9,12,16,19,22,
                                25,28,31,34,38,41,44,48,
                                50,53,56,59,63,66,69,72,
                                75,78,81,84,88,91,94,97};
sbit SDA=P1^6;
sbit SCL=P1^7;
unsigned char displaybuffer[8]={0,1,2,3,4,5,6,7};
unsigned char eepromdata[8];
unsigned char temperdata[2];
unsigned char timecount;
unsigned char displaycount;
bit secondflag=0;
unsigned char secondcount=0;
unsigned char retn;
unsigned int result;
unsigned char x;
unsigned int k;
unsigned int ks;

void delay(void);
void delay10ms(void);
void i_start(void);
void i_stop(void);
void i_init(void);
void i_ack(void);
bit i_cLOCk(void);
bit i_send(unsigned char i_data);
unsigned char i_receive(void);

bit start_temperature_T(void);
bit read_temperature_T(unsigned char *p);

void delay(void)
{
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}

void delay10ms(void)
{
  unsigned int i;
  for(i=0;i<1000;i++)
    {
      delay();
    }
}
void i_start(void)
{
  SCL=1;
  delay();
  SDA=0;
  delay();
  SCL=0;
  delay();
}
void i_stop(void)
{
  SDA=0;
  delay();
  SCL=1;
  delay();
  SDA=1;
  delay();
  SCL=0;
  delay();
}
void i_init(void)
{
  SCL=0;
  i_stop();
}
void i_ack(void)
{
  SDA=0;
  i_clock();
  SDA=1;
}
bit i_clock(void)
{
  bit sample;
  SCL=1;
  delay();
  sample=SDA;
  _nop_();
  _nop_();
  SCL=0;
  delay();
  return(sample);
}
bit i_send(unsigned char i_data)
{
  unsigned char i;
  for(i=0;i<8;i++)
    {
      SDA=(bit)(i_data & 0x80);
      i_data=i_data<<1;
      i_clock();
    }
  SDA=1;
  return(~i_clock());
}
unsigned char i_receive(void)
{
  unsigned char i_data=0;
  unsigned char i;
  for(i=0;i<8;i++)
    {
      i_data*=2;
      if(i_clock()) i_data++;
    }
  return(i_data);
}
bit start_temperature_T(void)
{
  i_start();
  if(i_send(0x90))
    {
      if(i_send(0xee))
        {
          i_stop();
          delay();
          return(1);
        }
        else
          {
            i_stop();
            delay();
            return(0);
          }
    }
    else
      {
        i_stop();
        delay();
        return(0);
      }
}
bit read_temperature_T(unsigned char *p)
{
  i_start();
  if(i_send(0x90))
    {
      if(i_send(0xaa))
        {
          i_start();
          if(i_send(0x91))
            {
              *(p+1)=i_receive();
              i_ack();
              *p=i_receive();
              i_stop();
              delay();
              return(1);
            }
            else
              {
                i_stop();
                delay();
                return(0);
              }
        }
        else
          {
            i_stop();
            delay();
            return(0);
          }
    }
    else
      {
        i_stop();
        delay();
        return(0);
      }
}
void main(void)
{
  P1=0xff;
  timecount=0;
  displaycount=0; 
  TMOD=0x21;
  TH1=0x06;
  TL1=0x06;
  TR1=1;
  ET1=1;
  ET0=1;
  EA=1;
  if(start_temperature_T())                    //向DS1624发送启动A/D温度转换命令,成功则启动T0定时1s。
    {
      secondflag=0;
      secondcount=0;
      TH0=55536/256;
      TL0=55536%6;
      TR0=1;     
    }
  while(1)
    {
      if(secondflag==1)
        {
          secondflag=0;
          TR0=0;
          if(read_temperature_T(temperdata))      //T0定时1s时间到,读取DS1624的温度值
            {
              for(x=0;x<8;x++)
                {
                  displaybuffer[x]=16;
                }
              x=2;
              result=temperdata[1];                     //将读取的温度值进行数据处理,并送到显示缓冲区
              while(result/10)
                {
                  displaybuffer[x]=result;
                  result=result/10;
                  x++;
                }
              displaybuffer[x]=result;
              result=temperdata[0];
              result=result>>3;
              displaybuffer[0]=(dotcode[result]);
              displaybuffer[1]=(dotcode[result])/10;             
              if(start_temperature_T())      //温度值数据处理完毕,重新启动DS1624开始温度转换
                {
                  secondflag=0;
                  secondcount=0;
                  TH0=55536/256;
                  TL0=55536%6;
                  TR0=1;                       
                }
            }
        }
    }
}
void t0(void) interrupt 1 using 0                       //T0用于定时1s时间到
{
  secondcount++;
  if(secondcount==100)
    {
      secondcount=0;
      secondflag=1;
    }
  TH0=55536/256;
  TL0=55536%6;
}
void t1(void) interrupt 3 using 0                       //T1定时1ms用数码管的动态刷新
{
  timecount++;
  if(timecount==4)                                           //T1定时1ms到
    {
      timecount=0;
      if (displaycount==5)
        {
          P0=(displaycode[displaybuffer[7-displaycount]] | 0x80); //在该位同时还要显示小数点
        }
        else
          {
            P0=displaycode[displaybuffer[7-displaycount]];
          }
      P2=displaybit[displaycount];
      displaycount++;
      if(displaycount==8)
        {
          displaycount=0;
        }
    }
}


推荐阅读

史海拾趣

Eurofarad公司的发展小趣事

随着Eurofarad产品质量的不断提高和市场份额的逐步扩大,公司开始积极拓展国际市场。Eurofarad的产品已经广泛应用于航空航天、国防、医疗、铁路、石油勘探等领域,赢得了全球客户的信赖和好评。同时,Eurofarad还与国际知名企业建立了紧密的合作关系,共同推动电子行业的发展。

ELPIDA公司的发展小趣事

ELPIDA公司成立于1999年,是日本在DRAM(动态随机存取存储器)领域的重要企业。它的成立是对当时日本半导体产业的一次重要整合,由NEC、日立、三菱电机等公司的DRAM业务合并而成。这一举措旨在振兴日本在DRAM领域的竞争力,并保护国内DRAM产业。

安碁科技(AKER)公司的发展小趣事

1990年,安碁科技股份有限公司正式成立,标志着其进军石英振荡器领域的起点。公司初创时期,面临着激烈的市场竞争和技术挑战。然而,安碁科技凭借对技术的执着追求和对市场的敏锐洞察,逐步在行业中崭露头角。通过不断的技术研发和产品创新,公司逐渐建立了自己的品牌地位,为后续的发展奠定了坚实的基础。

FerriShield公司的发展小趣事

随着技术的成熟和市场的认可,FerriShield开始拓展产品线。公司研发团队不断改进和优化原始的铁磁屏蔽材料,并推出了针对不同应用场景的系列产品。例如,针对智能手机和平板电脑的轻薄型电磁屏蔽膜,以及针对大型数据中心的高效电磁屏蔽板。这些新产品的推出,使得FerriShield的市场份额逐步扩大。

GHz Technology ( Microsemi )公司的发展小趣事

FerriShield公司起源于一家小型电子材料研究实验室。创始人Dr. Smith是一位材料科学家,他发现了一种新型的铁磁屏蔽材料,能够有效减少电子设备中的电磁干扰。这一发现引起了业界的广泛关注。Dr. Smith决定将其商业化,并创立了FerriShield公司。凭借这种创新材料,FerriShield在成立初期就获得了多项专利,并成功吸引了第一轮风险投资。

Beckhoff Automation GmbH公司的发展小趣事

品质是电子行业的生命线,BCD Semi公司深知这一点。因此,公司始终将品质管理放在首位,建立了完善的品质管理体系和质量控制流程。公司从原材料采购、生产制造到产品出厂,每一个环节都进行严格的质量把控,确保产品的高品质和稳定性。同时,BCD Semi还不断引进先进的生产设备和技术,优化生产流程,提高生产效率,为客户提供更优质的产品和服务。

问答坊 | AI 解惑

51单片机C语言控制与应用教程

51单片机C语言控制与应用教程,很好的,初学者用…

查看全部问答>

难题请教,51从外部flash的FFFD地址启动?怎么做啊

我有一颗芯片 ip210w由 8051内核和一个MAC组成 芯片手册有一句话:CPU starts up and runs instructions at address 0xFFFD of external Flash. 就是这句话把我郁闷了好久,怎么烧程序都不行。CPU都跑不起来。 请教高手如何让我的CPU跑起来,谢 ...…

查看全部问答>

程序执行时间问题

问个VC问题  (应用程序通过pci采集板读数据) 应用程序的WM_TIMER在电脑刚开机(开机2,3分钟左右)会被阻塞吗? 我有段定时器(100ms)的执行程序,我想知道这段程序的执行时间。开始time1=GetTickCount(),末尾time=GetTickCount()-ti ...…

查看全部问答>

不能捕捉到CArchiveException 请各路英雄指教

大家好, 最近我遇到一个问题,在我的应用程序中(MFC工程), 里面有一句代码,是对文件读写的,如果这儿有一个空文件(里面什么内容也没有), 但我们又对它进行了读操作(调用CArchive >>进行读出),那么这儿一定会有个 CArchiveException异 ...…

查看全部问答>

如何把调试用的串口改为普通的串口来使用

各位仁兄: 1:我是在wince6.0 开发板是友坚的S5PC100 2: 由于项目需要想把调试串口改为普通的串口来使用 3:请问各位大侠指教 4:我自己把SMDKC100.bat里面的 set BSP_DEBUGPORT=SERIAL_UART0   隐去,把UART0加载,编译可以通过 ...…

查看全部问答>

关于uClinux mtd map 文件的 地址问题

在分区的时候  假如我的FLASH有  2M 我希望分成三部分               1920KB    64KB   64KB 我的map文件如下: static struct mtd_partition fir ...…

查看全部问答>

EVC4.0编译后生成的EXE在目标板上执行 出错 乱码

1、开始我使用的共享MFC库出错,后来我使用的静态MFC库,不出错了,,,但我在PB里已经向目标板加上了MFC组件,不知道为什么出错 2、我生成的EXE文件里如果有中文会显示乱码,不如应该如何解决 先谢谢了…

查看全部问答>

设置P5.2为输入, 接VCC, P5DIR &= 0xFB;后,P5IN是0x00!怎么办?

也就是说P5.2在输入模式情况下,并且接了VCC, 应该在P5IN变量和P5.2对应的比特位上读入1才对啊? 我用电压表量过,P5.2引脚上的电压就是VCC高电平,可是为啥P5IN会是0x00呢? 除了是芯片坏了,还有别的情况吗?那位大侠碰到过这种事情?…

查看全部问答>

今天调试板子,发现不法连接

今天调试板子,发现无法连接。第一个想到的是电源电压(焊DSP之前有测过电压都是对的)。 把所有的电容测了,发现RTS管脚处,用了一个RC 滤波电路。C上电压变成2.75V。去掉电容,DSP可连接。 将原本的4.7K,电阻换小后,电压上抬到3V左右。DSP工 ...…

查看全部问答>

大家好,有个问题,请教一下

我想用泰勒级数来逼近正弦函数sinx,然后在ccs里编程如下,可是出现了错误,搞了很久,不知道怎么解决,希望得到帮助。。。 while(1) {   double  x,y,A,B,C,D,E;   double  i;   for(i=0 ...…

查看全部问答>