联系方式
联系人:黄小姐
联系电话:0755-25848978, 83738778
传真号码:0755-83738639
公司地址:深圳市宝安区西乡街道宝源路深圳市名优工业产品展示采购中心B座1区五楼508号
Email:sales@sandat.com
邮编:518102
公司网址:http://www.sandat.com
文章详情

SMT16030温度传感器如何与MCS51单片机连接

日期:2024-03-27 21:35
浏览次数:11784
摘要:

用英特尔MCS-51 单片机测量占空因数

Paul C. de Jong and Ferry N. Toth

测量占空因数*快的方法是借助硬件的帮助。MCS-51单片机因为装备了两个内部计时器/计数器,因此为这样使用提供了可能性。

端口INT0 (P3.2)INT1 (P3.3)能通过硬件直接控制时器/计数器。因此我们把它们看作“快速输入”其他所有引脚只能通过软件来控制计时器/计数器。包括传感器SMT 160在内的内部硬件结构如图1所示。

                 图1  8051内部硬件结构

此应用指南描述了:A)四个通过硬件测量占空因数的汇编程序。B)一个通过软件测量的程序。*后我们将讨论哪种情况可以改善分辨率。

A1通过INT0 引脚实现硬件控制的测量

当使用硬件测量占空因数时,关于CPU的任务执行方面会有一些限制:计时器TIMER0 TIMER1都被占用,通常TIMER1为通讯产生波特率。测量时,CPU不允许发送或接收任何数据。

使用这种快速**的测量方法还有另一个限制,通过CPU空闲前的中断信号来实现。这很重要,因为在指令处理时会触发中断,而触发中断的指令首先被完成而且不同指令执行时间不一样。在空闲期间CPU不动作。两个计时器对空闲指令不动作,这是MCS-51的一个重要特性。CPU 将通过中断信号再次启动。这样,CPU在中断信号下会作出迅速反映。这种特殊的测量方法要求CPU不能运行其他任何后台程序,那样会使测量和后台程序均出错。

计时器/计数器选择工作在16-bits计时模式下。因此,计时器/计数器模式控制寄存器当值是19H时启动。这种模式下TIMER0只有当P3.2是逻辑1时才工作,而TIMER1只能由软件来控制。TIMER1用来测量总的测量时间。一次测量完成后占空因数 P由下面公式来决定。

 

contents of TIMER0

p=  ---------------------------

contents of TIMER1

当使用中断信号使测量开始和停止时,在信号跳变处可探测到的分辨率在1μs以内。在输入信号下降沿产生一个中断信号(当中断标志是激活的)。

用流程图(fig. 2)说明测量。首先,设定两个计时器的内容。当检测到0-1跳变时,初始部分开始传输。然后,中断信号使能标记被赋值并且调用空闲模式。此刻处理器等待中断。当输入信号产生下一个1-0跳变时,产生中断,设定计数器控制寄存器内的TR0 TR1(TCON)。现在只有当P3.2变为高电平时TIMER0才运行。因此它测量输入信号是1的时间。TIMER1在整个测量过程中都处于工作状态。注意TIMER1启动3μs太迟了,因为一个中断处理要花费3μs。但在停止时同样也采用这种方式,所以在*后结果中消除了延迟。

关于测量时间,需要选择固定周期数或固定测量时间。因为周期可以在300μs800μs之间变化,所以固定周期数是一个低效率的选择。对周期短的信号的测量时间也会很短所以结果会受到取样噪声的干扰。因此对应于16bits的机器周期选择一个固定的测量时间。测量将在TIMER1产生溢出之后完成。这样获得17bits的结果,这些结果还需要复杂的软件处理。使用带有一个偏移的TIMER1初始化(测量前)解决了这个问题。这个偏移与两个周期传感器信号的*大长度相符合(时间上大概是1.6ms)。从17bits的结果中减去偏移量,就得到16bits的数据。

TIMER1产生一个溢出时,测量必须停止(见图2中右边的分支)。传感器信号的下一个1-0跳变发生时,中断使能标志位被重置并且空闲模式再次被调用。中断发生之后,TCON寄存器中的 TR0  TR1被清零。

TIMER1中的偏移修正之后,利用两个计时器中的内容来计算占空比。

图2  分辨率为一个机器周期的占空因数测量的流程图

A2. 通过INT0 引脚串行通信测量 

上一节所介绍的方法是使用8051空闲模式在中断的瞬间(输入信号的下降沿)和对TIMER0开始取样的瞬间之间来产生一个恒定延迟(中断反映时间)。这是必须的,因为指令处理触发中断时,这个指令首先被完成,并且不是所有指令的执行时间都是相同的。

在空闲模式期间,任何指令都不被执行,因为此时8051的执行模块不可用。但中断计时器和串行模块在运行。这种模式下功耗显著减少。

为了实现恒定的反映时间。只能有一个中断源是可用的(像图一中所示的)。但有时我们需要同时测量温度和实现串行通信。可能需要串行通信像计时器一样中断它自己来产生波特率。使用33MHz 8051能同时实现1200波特通信和占空因数测量,而不需要增加加硬件,如图3所示。

这样,Timer 1的溢出率需要用来产生波特率。使用32.9856 MHz的晶体计时器TIMER1需要计数859个时钟才能溢出。假定使用16位模式,Timer 1溢出位产生一个中断(TF1)重载分配器的值。因为我们使用的是一个快速的处理器,所以同样的中断处理器能够在短时间内为软件计数器增量。软件计数器与Timer 1的实际值相结合作为一个时间基准来决定SMT160输出信号的周期。

Timer 0保留其功能来累计周期信号的高电平。

当然,由于我们使用了三个中断处理器(INT0, TF1, Serial)中断反应时间不再是连续的。因此测量结果的分辨率将会衰减三倍。然而,这可以通过采用较高时钟速度的处理器来进行补偿。

图3同步测量和串行通信

A3.利用Timer 2测量占空因数捕获寄存器

许多8051派生处理器,包括805216 bit 8051XA,都有一个附加的计时器,Timer 2 (. 4)Timer 2是一个**的16位的计时器/计数器,带有一个捕获/重载寄存器。在我们的应用中,捕获寄存器的功能是瞬时载入Timer 2(捕获)的值,并将值保存起来,直到中断处理器读取它。消除了中断反应时间的影响,规定中断反应时间要小于中断比率。

图4 利用计时器2和计时器0测量占空因数

使用计时器2测量SMT160信号周期,Timer 0则用来测量高电平的时间。Timer 1用做串行接口波特率发生器。有时,TIMER0不能为测量SMT16030的高电平时间留做备用,例如当采用实时操作系统(RTOS)。实时操作系统的调度程序常需要一个时钟信号来产生每个处理过程的时间片。在这种情况下Timer 0被实时操作系统使用,通过外加一个异或门(. 5)Timer2就足以测量SMT160的占空因数,通过将触发器的OUT端接到Timer 2的中断处理器,上升沿和下降沿都可以获取。

图5  只用计时器2测量占空因数

A4.使用可编程记数器阵列(PCA)测量占空因数 

8051FX派生系列有一个附加硬件:可编程记数器阵列。包括一个计时器和5个捕获寄存器。计时器可以通过编程运行在频率Osc/12  Osc/4下。与普通8051相比,使用FX类型能够在同样测量时间里达到三倍的测量分辨率。

图6 使用PCA测量占空因数

此外,捕获寄存器可以通过编程来捕获信号的上升沿或下降沿转换,或两者同时捕获。所以不需要一个附加的异或门。因为此捕获寄存器同时可用于上升沿和下降沿,所以使用这个系列的处理器中断反应时间不是必需的(. 6)。这意味着中断处理器能够可以通过**程序语言,如C语言,来控制写入。下面给出了通过中断处理器测量SMT160信号n个周期的例子。

void PCAHandler(void) interrupt 6 using 1 {

   static union Word2Byte CaptureUp, CaptureDo;

   if (PCAOverFlow) { /* PCA Overflow? */

      PCAOverFlow = FALSE;

      if (!Ready) {

         if (OverFlow > 3) { /* 3 overflows => error */

            SetCaptureOff(); /* Capture off */

            PCACapture0 = FALSE; /* Clear flags */

            PCACapture1 = FALSE;

            Ready = TRUE; /* measurement done */

    Error = TRUE;

         } else {

            OverFlow++;

              };

         };

    } else {

      if (PCACapture1) { /* rising edge? */

         PCACapture1 = FALSE; /* Clear flag */

         if (!Ready) {

            CaptureDo.Byte.Hi = CCAP1H; /* save PCA value */

            CaptureDo.Byte.Lo = CCAP1L;

            HiTime += (CaptureDo.Word - CaptureUp.Word);

         }; /* determine low period */

      } else {

         PCACapture0 = FALSE;

         if (!Ready) {

            CaptureUp.Byte.Hi = CCAP0H;   /* save PCA counter */

            CaptureUp.Byte.Lo = CCAP0L;

            if (First) {

st

               First = FALSE; /* 1  time just caputure value */

       HiTime = LoTime = 0;

               SetPCA1NegEdge(); /* enable falling edges */

            } else {

               LoTime += (CaptureUp.Word - CaptureDo.Word);

               if (--Count == 0) { /* when Count = 0 ready */

                  SetCaptureOff(); /* capture off */

                  PCACapture0 = FALSE; /* clear flags */

                  PCACapture1 = FALSE;

                  PCAOverFlow = FALSE;

                  Ready = TRUE; /* measurement ready */

               };

            }; /* determine high period */

         };

      };

      if (!Ready) {

      };

      OverFlow = 0; /* we have a signal */

   };

   return;

}

我们通过主程序与中断处理器连接。使用下列程序。

#include <pca.h>

#include <stdio.h>

#define PERIODS 25

struct DoubleByte {

  unsigned char Hi, Lo;

};

union Word2Byte {

  unsigned short Word;

  struct DoubleByte Byte;

};

static volatile bit First, Ready, Error;

static volatile unsigned int Count = 0, Periods = 51;

static volatile unsigned char OverFlow;

static volatile unsigned long HiTime, LoTime;

void StartCount(void) {

   First = TRUE; /* Initializes all varialbes */

   OverFlow = 0;

   Count = Periods;

   Ready = FALSE;

   Error = FALSE;

   SetPCA0PosEdge(); /* Enable capture */

}

void SetPeriods(unsigned APeriods) {

   Periods = APeriods;

}

bit IsReady(void) {

   return(Ready);

}

bit IsError(void) {

   return(Error);

}

float GetDutyCycle(void) {

   return (float)HiTime / (HiTime + LoTime);

}

主程序需要初始化中断处理器一次,然后重复测量,直到测量完成。检测误差并显示结果。

main() {

   SetPeriods(51);

   while(TRUE) {

      StartCount();

      while(!IsReady()); continue;

      if(IsError()) printf("An error has occured\n");

      else printf(!°The termperature is %f\n!

         (GetDutycycle() - 0.32) / 0.0047));

   }

}

B. 软件测量

只有I/ O端口P3.2 P3.3可以用来检测中断。因此,当传感器与其他I/ O端口相连,只有使用软件才能测量占空因数。此外还需要两个计数器。虽然是软件控制,但也可能用到一个硬件计时器。TIMER0能够计算测量时间。快速的软件程序用来测量传感器信号为“1”的状态。结果储存在名字为HIGH_COUNTER的计数器中。计时器TIMER0每个机器周期都增加,机器周期需要花费1μs,软件取样率花费3μs。要获得占空因数p,依据等式HIGH_COUNTER需要乘3。

 

HIGH COUNTER X 3

p=---------------------------

TIMER0

通常HIGH_COUNTER 应该存储的数据多于8位,因此需要两个8位寄存器。这就减小了取样速度,因为,需要两个命令把这两个寄存器连接起来(低字节溢出检测,根据测试结果对高字节增量)。提供了可供选择的方案:当输入信号是低电平时,HIGH_COUNTER等待直到信号变为高电平。这个时间可以用来计算HIGH_COUNTER( 7)。图中展示了一个被称作TEMPORARY_HIGH_COUNTER的暂存器的使用。此暂存器包含了一个周期内输入信号为高电平时的取样数目。当输入信号变为低电平,暂存器TEMPORARY_HIGH_COUNTER中的值被累加到HIGH_COUNTER中,在这个计算时段,传感器信号不再被取样。

这对占空因数有一个限制。但计算只花费15μs,对一个周期在600μs左右的信号来说,即使占空因数等于0.95,也不会出现问题。测量时间的计算存储在硬件计时器/计数器TIMER0中,TIMER0使用软件在输入信号1-0跳变时来启动和停止。

图7 a)占空因数软件测量流程图(测量高电平的部分)

b) 7a中的时间图.。时间间隔时通过**高速存储器计算HIGH_COUNTER

暂存器不需要计算,所以这个动作对采样率没有影响。暂存器增量的速度是3μs。  

例:占空因数调制信号的采样噪声的标准偏差可以用下面的等式计算。

where: t连续采样间隔时间

      T输入信号周期

      T测量时间 (=N *T p)

      N = 一次测量内的周期数

 

输入信号的周期在300μs (40)800μs (-40   120 )之间。测量时间大约64 ms

 (因为存在偏移所以小于2×1μs)。当取样率是1μs时,取样噪声在5 ×10和10(5.7*10-5和9.33*10-5)。根据经验,数值的95%都分布在主值的±2σ范围之内 (正态分布).

取样率是3μs时,取样噪声是它的三倍。

C.平均测量结果的理解

使用通用的A/D转换器来平均测量结果不会提高分辨率。在特定条件下,平均测量结果可以提高占空因数测量的平均值。测量结果之间必须没有相关性。当SMT160信号周期不是处理器计时器周期的整数倍时,这一点更为重要。我们可以通过使用频率计数器测量下降沿的抖动来确定这一点,将阈值时间设为τms.。这种抖动体现了τ的一个功能。这种效果可以在带有数据终端缓冲器功能的示波器上显示出来。这种功能允许在触发后的第n个下降沿处放大。正如你所看到的一样,抖动随着n的增大而增大。当这个抖动时间大于单片机计时器的周期时,连续占空因数测量就不再具有相关性。这意味着当检测到连续测量之间的某一*小延迟后,分辨率将会与取样数目的平方根成正比。

 

图8 抖动作为一个门时间功能

上图是使用时钟为1.25 MHz的微处理器实际测量的。用这种设备,量化噪声大致等于两次测量间隔1 ms的热噪声。这说明,对于不相关的占空因数测量,必须要有1 ms的时间间隔。由于具有电磁干扰等原因不同的设备噪音可能会有不同的特点。用图中可以估计出使用4 MHz的微处理器(例如使用PCA的可以以16 MHz运行的 8051FA),测量之间的零延迟也可以应用。这样可以获得*大测量速度。

 

粤公网安备 44030602001744号