当前位置:文档之家› 定时器中断延时程序

定时器中断延时程序

定时器中断延时程序
(1)该类型的delay()函数采用的延时是通过对变量进行递减或递增实现的,很难计算精确的延时时间。

(2)由于跑马灯的状态函数和延时函数是和主任务耦合到一起的,因此主任务的执行时间要对延时的时间产生影响。

如图6-12所示,假设一个跑马灯的延时函数的延时时间是1s,但是由于主函数可能存在不同的分支,因此当主函数执行不同分支程序时,实际的跑马灯延时时间是不一样的。

图6-12 程序分支对delay()函数的影响
因此,对于某些对定时精度有要求的场合,例如某项工程需要跑马灯1s更换一个状态(最典型的例子就是时钟指示),就不能采用变量递减或递增的延时方法,而要采用更加精确的中断定时方法。

中断的概念在前面的章节已经有过详细讲解,这里不再赘述,与采用递增递减延时函数相比,采用中断来进行跑马灯的状态更换有以下几个优点。

(1)采用中断函数进行延时,可以精确保证延时的精度,即有效地保证跑马灯状态更换的频率;
(2)采用中断函数进行跑马灯状态的更换,在进行延时期间,并不占用单片机资源,单片机可以执行其他的任务。

采用中断延时函数来进行跑马灯状态更换的软件结构如图6-13所示,主程序和跑马灯状态变换程序是独立分开的,当中断发生时,主程序被打断,进行跑马灯状态的变换。

AT89S51单片机里有两个独立的计时器T0和T1,为了得到精确的定时中断,在这里采用T0的模式0来产生定时中断。

如图6-14所示为T0工作于模式0时的结构图。

图6-13 采用时间中断函数的程序结构
图6-14 计时器T0的工作模式0
当T0工作于模式0时,相关需要配置的寄存器如下:
(1)TMOD寄存器:TMOD寄存器是管理计时器T0和T1工作模式和相关配置的寄存器,寄存器内各位如图6-15所示,需要配置的功能位如下所示。

·M10-M00:M10-M00用于选择T0的工作模式,工作于模式0时,T0是一个13位的定时器/计数器,如图6-14所示,THx和TLx分别为8bits和5bits长度,共为13位计数器。

·C/T0#:如图6-14所示,C/T0#决定T0的工作方式是计时器还是计数器,当配置为0时,T0工作方式是计时器,T0的计数器由晶振脉冲时钟的6分频进行触发;而当配置为1时,T0工作方式是计数器,T0的计数器由来自T0引脚的外部脉冲进行触发,可以用于记录外部输入脉冲数。

此处应将C/T0#配置为0。

·GATE0:如图6-14所示,GATE0位决定T0的启动方式,当配置为0时,由TR0启动计时器;当配置为1时,由外部中断启动计时器。

此处应将GATE0配置为0。

图6-15 TMOD寄存器
(2)TCON寄存器:TCON寄存器是对T0和T1进行控制的寄存器,寄存器各位如图6-16所示,需要配置和使用的功能位如下:
· TR0:如图6-14所示,TR0控制计数器THx和TLx的停止与启动,该位由软件进行置位与复位,在模式0时,TR0置1为启动T0计数;TR0清零时为停止T0计数。

·TF0:如图6-14所示,当T0计数器溢出时,TF0置1,并向CPU请求中断,当CPU 响应时,硬件自动对TF0清零,同时TF0也可以由程序查询或清零。

图6-16 TCON寄存器
(3)TH0和TL0:TH0和TL0在模式0下是一个13位长度的计数器,TH0为高8位,TLx为低5位。

TH0和TL0在单片机复位时的初值都是0,当计数器累加溢出时产生中断,因此,为了得到指定频率的中断,必须要计算计数器的装载的初值,下面以产生2ms的中断为例。

如图6-14所示,单片机的外部晶振脉冲在6分频以后对计数器T0进行触发,如使用的是24MHz的外部晶振,则触发的频率如下所示。

f = 24MHz/6 = 4MHz
则2ms共需要的触发数或计数值如下:
2ms * 4MHz = 8000 = 0x1F40
因此可知,需要计数8000后T0溢出产生中断,则T0的初始装载值如下:
2^13 – 8000 = 192 = 0x00C0 = 0000000011000000B;
因此T0计数器的初始装载值为0x00C0,需要注意的是,T0是由THx和TLx组成的,因此0x00C0要按照如图6-17所示的方式装载到THx和TLx中去,其中TH0的初始值为
0x06,TL0的初始值为0x00。

图6-17 T0计数器初始值的装载
除了对计时器T0相关寄存器进行配置以外,为了使T0能够产生中断,还需要对单片机的中断寄存器IE进行配置,IE寄存器的结构如图6-18所示,需要配置的功能位如下:·EA:EA位对AT89S51的所有中断进行管理,当EA置1时,单片机开放中断资源,当EA清零时,单片机屏蔽所有的中断请求。

因此在完成必要的初始化后,需要产生中断时,EA位必须置1。

·ET0:ET0位对T0产生的中断进行管理,当ET0置1时,T0溢出时,TF0置1将产生中断,当ET0清零时,T0产生的中断被屏蔽。

图6-18 IE寄存器
由前面的分析,可以得到采用T0计时器中断进行延时的跑马灯状态控制程序如下,该段代码采用龙舞花样作为示例。

/**********************************************
* File: T0IntLEDsExample.c
* Description: LEDs T0 Int Triggle
* Created Date: 2007-09-14
* Last Modified: 2007-09-14
* Author: Jeffrey - Schicksal@
* Notes: None
**********************************************/
#include <REGX51.h>
#define TH0_VALUE 0x06
#define TL0_VALUE 0x00
unsigned int timer_tick;
unsigned int timer_tick_1s;
void LEDs_Move();
void LEDs_Error();
void LEDs_Gragon();
void TIMER_Init();
注意上面的代码有以下几个特点。

(1)跑马灯龙舞花样状态的变换由中断每一秒进行一次变换,在主程序结构中已经找不到龙舞花样的相关代码了,这和如图6-13所示结构是一致的。

(2)要使用计时器来进行延时操作,初始化操作是不可少的,例如初始化计时器T0的工作模式、预装载计数器TH0和TL0的值、确定由软件启动还是由外部中断启动等,都是在函数void TIMER_Init(void)中完成的。

注意:如果没有正确初始化计时器,计时器并不能够正常工作!
(3)要使用计时器中断,除了要将计时器中断ET0进行使能配置以外,全局中断使能位EA也必须配置为使能,否则所有的中断都无法产生。

相关主题