用C51语言实现单片机高精度定时的算法

人生的个人 2018-07-03

为提高8051单片机定时精度,扩展8051系列单片机的用途,本文分析了8051系列单片机定时器溢出中断与CPU响应中断的时间误差。在此基础上,提出了应用C51高级语言对多个定时器进行精确定时的误差补偿方法,并且使用Keil Uvision2仿真调试软件搭建一段数字显示式倒计时的实例程序,通过分析和调试误差补偿算法,使8051单片机在多个定时器同时使用的情况下,定时误差最终小于3个机器周期,是目前8051单片机高精度定时的一种新算法。

对于8051系列单片机的定时应用已经有不少讨论,有的利用汇编语言对其定时器的中断时间进行误差补偿[4],但该方法的系统编程繁琐,且开发周期长等;有的利用C51程序实现T0的精确定时[5],但其算法仅适用于某些特定情况,且稳定性不高。因此,本文针对单片机多个定时器同时使用的定时误差进行分析,提出应用C51高级语言进行高精确定时的新算法,以解决上述定时方法所存在的问题,并给出了应用实例,具有一定的实用性。

1 定时误差产生的原因

产生定时误差的主要原因有:①定时器产生溢出中断信号时,CPU正在执行某指令;②定时器溢出中断信号时,CPU正在执行某中断服务程序。

1.1 定时器工作方式的分析

8051单片机的2个定时/计数器,有方式0~方式3的4种工作方式。本文以最常用的定时方式1作讨论,其工作原理如图1所示。

用C51语言实现单片机高精度定时的算法

图1 工作方式1(16位定时/计数器)示意

由图1可知,单片机工作在方式1时,若定时/计数值计满溢出后,则定时/计数器的初值将被置零,并继续从THx=0x00,TLx=0x00开始计数。由于定时初值不会被重新装入,所以需要利用程序重新对THx、TLx赋值。但赋值操作需要占用一定时间,如果不补偿,会造成下一次定时/计数溢出中断信号的时间与理想值不符(即误差)。

1.2 影响定时器误差的因素

用C51语言实现单片机高精度定时的算法

1.3 定时误差的非固定性特点

由式(1)看出,对于不同指令对应的T0~T3有很大差异,即定时器的定时误差具有非固定性特点。在多个定时器同时使用时,误差的非固定性更明显。如第一个循环CPU正在执行某中断服务程序a,第二个循环CPU正要执行中断服务程序b,这时误差将远远大于CPU执行一条指令(如MOV)时的误差。误差的非固定性不仅给误差分析带来不便,而且对于高精度定时任务将产生不良影响,如造成转速测试不准、定时误差过大。

2定时误差的修正算法

由于定时器溢出中断与处理器响应中断的时间误差的非固定性,所以不能简单依靠设置一个固定补偿参数来修正。为此,本文尝试采用对每次中断进行动态补偿的方式进行修正(简称新算法),其算法流程如图2所示。

若单片机工作于方式1(或方式0),当中断溢出信号产生时,THx、TLx重新由0开始计数。因为在用户对定时器赋初值前的一刻,THx、TLx中的计数值就代表误差的时间。所以,将THx、TLx从溢出到用户对其重新赋值时已有的计数值读出,并补偿到计数初值当中,就可以消除定时/计数器的连续定时误差。

用C51语言实现单片机高精度定时的算法

图2 修正算法流程

3新算法的应用实例

现代工业通常使用的低频脉冲发生器、低速测速系统、时间控制系统等,均需要高定时精度、周期长的时钟信号作为时间基准。使用新算法,可使上述系统得到很高的定时精度。图3给出了一个由单片8051 MCU应用新算法构成倒计时系统的实例。

用C51语言实现单片机高精度定时的算法

图3 单芯片控制数码管显示倒计时系统实例框图

在该计时电路中,以AT89S51/C51内部的定时器T0作为时钟基准。由于T0中断信号的准确度直接关系到系统的定时精度,所以如何获得高精度的T0时钟信号,是本系统设计的关键。

3.1 应用C语言的编程实例

图4为倒计时系统的程序流程图。在该主程序中同时使用了两个定时器T0和T1,而且两者的中断时间为整倍数关系,故容易因为中断冲突造成中断时间不准确,这是多个定时器同时使用中普遍存在的问题。为此,本文围绕此实例程序,提出如何通过使用新算法来提高倒计时系统的定时精度。

用C51语言实现单片机高精度定时的算法

图4 系统应用程序流程图

未用新算法时,在T0中断处加入断点,进行模拟调试(定时间隔: 0.01s),其定时时间记录见表1。

用C51语言实现单片机高精度定时的算法

表1 未使用修正算法的定时时间记录

从表1看出,T0中断的基本误差(时间)是随机变化的;1秒后累计误差时间已经超过0.01s。由此可见,其定时精度低。

3.2误差修正程序

新算法的修正流程,如图2所示。其修正程序首先是在代码头部加入修正变量定义:

用C51语言实现单片机高精度定时的算法

在加入修正程序后,再次进行模拟调试(定时间隔0.01s),T0的定时时间记录见表2。

用C51语言实现单片机高精度定时的算法

表2 使用新算法的定时时间记录

由表2看出,在实例程序中加入修正算法后,T0的基本误差与累计误差都得到修正,定时时间精确可靠。

3.3新算法对定时器复用有效性的校验

新算法对同时工作的定时器(即复用)是否有效呢,还需要进一步校验。在T0中断服务头部加入如下修正代码:

用C51语言实现单片机高精度定时的算法

在T1中EA=0处设置程序断点进行模拟调试(定时间隔0.001s),其定时时间见表3。

用C51语言实现单片机高精度定时的算法

表3 加入新算法后T1的定时时间记录

同时,在T0中EA=0处设置程序断点进行分析(定时间隔0.01s),其定时时间见表4。

用C51语言实现单片机高精度定时的算法

表4 加入新算法后T0的定时时间记录

通过以上实验数据的处理分析发现:在使用新算法之前,1秒后累计误差时间超过0.01s,程序的定时误差很大,无法满足长时间精确定时的需要。使用新算法之后,无论是单独运行的定时器还是同时运行的两定时器均能精确定时,并且还能自动补偿累计误差给定时间隔带来的影响。可见,新算法对于多个定时器同时工作的高精度定时仍然有效。

4应用新算法的注意事项

理论上新算法可以添加在中断服务程序的任意一段中,但由于新算法是通过实时读取THx、TLx寄存器的当前值进行定时修正,有可能会因为中断服务程序过长而产生多次进位的情况,造成算法失效。因此,在中断服务程序较短,且TLx的初始值加上修正值不会产生进位信号的情况下,新算法可以不必对THx进行修正并能放置在中断服务程序的任意位置;若中断服务程序较长,新算法的代码则应该放置在中断服务程序的起始位置,并且对THx进行修正。

结论

本文使用C51高级语言实现误差补偿的方法,对多个定时器溢出中断与CPU响应中断的非固定性时间误差可以进行有效修正,并将定时器定时时间误差控制在3个机器周期内,这对于需要精确时钟信号的控制系统具有重要的意义。该方法在测距中得到应用,成本非常低廉,精度得到很大提高。因此,该方法对于提高系统的控制精度,扩展8051系列单片机的应用范围都具有较高的实用价值。

(摘编自《电气技术》,原文标题为“用C51语言实现单片机高精度定时的新算法”,作者为刘帆、林育兹等。)

¥39.53
购买

相关推荐