(五)51基础:8051定时器

释放双眼,带上耳机,听听看~!

介绍

8051微控制器有两个定时器/计数器,可以在时钟频率上工作。定时器/计数器可用于产生时间延迟,计算外部事件等。

时钟

每个定时器都需要一个时钟才能工作,8051通过外部晶振提供它,这是Timer的主要时钟源。8051微控制器中的内部电路为定时器提供时钟源,该定时器是连接到微控制器的晶体频率的1/12,也称为机器周期频率。

(五)51基础:8051定时器
8051定时器时钟

8051定时器时钟

例如,假设我们的晶振频率为11.0592 MHz,那么微控制器将提供1/12即:

定时器时钟频率=(Xtal Osc.frequency)/ 12 =(11.0592 MHz)/ 12 = 921.6 KHz

周期T = 1 /(921.6KHz)=1.085μS

计时器

8051有两个定时器Timer0(T0)和Timer1(T1),两者都是16位宽。由于8051具有8位架构,因此每个都由两个独立的8位寄存器访问,如下图所示。这些寄存器用于加载定时器计数。

(五)51基础:8051定时器
8051定时器寄存器

8051具有定时器模式寄存器和定时器控制寄存器,用于选择操作模式和控制目的。

我们来看看这些寄存器,

TMOD寄存器

TMOD是一个8位寄存器,用于设置timer0和timer1的定时器模式。

8051 TMOD寄存器

(五)51基础:8051定时器
8051 TMOD寄存器

其低4位用于Timer0,高4位用于Timer1

Bit 7,3 – GATE:

1 =仅当INT0 / INT1引脚为高电平且TR0 / TR1置1时,才使能定时器/计数器。

0 = TR0 / TR1置位时使能定时器/计数器。

Bit 6,2 – C/(五)51基础:8051定时器(Counter/Timer): 定时器或计数器选择位

1 =用作计数器

0 =用作定时器

Bit 5:4 & 1:0 – M1:M0: 定时器/计数器模式选择位

这些是定时器/计数器模式选择位,如下表所示

(五)51基础:8051定时器

TCON注册

(五)51基础:8051定时器
8051 TCON寄存器

TCON是8位控制寄存器,包含定时器和中断标志。

Bit 7 – TF1: Timer1溢出标志

1 =发生Timer1溢出(即Timer1变为最大值并翻转回零)。

0 =未发生Timer1溢出。

它通过软件清除。在Timer1溢出中断服务程序中,该位在退出ISR时自动清零。

Bit 6 – TR1: Timer1运行控制位

1 = Timer1启动。

0 = Timer1停止。

它由软件设置和清除。

Bit 5 – TF0: Timer0溢出标志

1 =发生Timer0溢出(即Timer0进入最大值并翻转回零)。

0 =未发生Timer0溢出。

它通过软件清除。在Timer0溢出中断服务程序中,该位在退出ISR时自动清零。

Bit 4 – TR0:  Timer0运行控制位

1 = Timer0启动。

0 = Timer0停止。

它由软件设置和清除。

Bit 3 – IE1:外部中断1边沿标志

1 =发生外部中断1。

0 =外部中断1已处理。

它由硬件设置和清除。

Bit 2 – IT1: :外部中断1触发类型选择位

1 = INT1引脚的下降沿发生中断。

0 = INT1引脚在低电平时发生中断。

Bit 1 – IE0: 外部中断0边沿标志

1 =发生外部中断0。

0 =外部中断0已处理。

它由硬件设置和清除。

Bit 0 – IT0:外部中断0触发类型选择位

1 = INT0引脚的下降沿发生中断。

0 = INT0引脚在低电平时发生中断。

我们来看看定时器模式

定时器模式

定时器具有使用M0和M1位组合在TMOD寄存器中选择的操作模式。

模式0(13位定时器模式)

模式0是13位定时器模式,其中使用8位THx和5位TLx(作为预分频器)。它主要用于与旧的MCS-48系列微控制器进行对接。

(五)51基础:8051定时器
8051定时器模式0

如上图所示,用于形成总13位定时器的8位THx和低5位TLx。使用定时器模式0时,应将高3位的TLx写为0,否则会影响结果。

让我们使用AT89C51微控制器生成一个2ms周期的方波,其中timer0在port1的P1.0引脚上的mode0中。假设xtal振荡器频率为11.0592 MHz。

(五)51基础:8051定时器
8051 Mode0波形示例

8051 Mode0波形示例

由于Xtal振荡器频率为11.0592 MHz,因此机器周期为1.085uSec。因此,需要计数以产生1毫秒的延迟:

计数= =(1×10^-3)/(1.085×10^-6) ≈ 921

Mode0的最大计数为2 ^ 13(0 – 8191),Timer0计数将从0 – 8191递增。因此我们需要加载的值比最大计数少921,即8191。此外,在下面的程序中,我们需要从调用到返回延迟功能的额外13 MC(机器周期)。因此需要加载的Value是:

Value=(8191-Count)+Function_MCycles+1 =7284= 0x1C74

所以我们需要在T​​imer0中加载0x1C74值。

1C74 = 0001 1100 0111 0100 ,现在在TL0中加载低5位,在TH0中加载下一个8位

所以我们得到了,

TL0 = 0001 0100 = 0x14 and TH0 = 1110 0011 = 0xE3

延迟功能的编程步骤

  1. 加载Tmod寄存器值,即TM0 = 0x00,用于Timer0 / 1 mode0(13位定时器模式)。
  2. 加载计算的THx值,即TH0 = 0xE3。
  3. 加载计算的TLx值,即TL0 = 0x14。
  4. 通过设置TRx位启动定时器。即这里TR0 = 1。
  5. 轮询TFx标志直到它没有设置。
  6. 通过清零TRx位来停止定时器。即这里TR0 = 0。
  7. 清除定时器标志TFx位,即TF0 = 0。
  8. 从步骤1到7重复再次延迟。

定时器模式0的程序

/*
 * 8051_Timer_Mode0
 * http://www.qutaojiao.com
 */
#include <reg51.h>			/* Include x51 header file */
sbit test = P1^0;			/* set test pin 0 of port1 */ 

void timer_delay()			/* Timer0 delay function */
{
	TH0 = 0xE3;			/* Load 8-bit in TH0 (here Timer0 used) */
	TL0 = 0x14;			/* Load 5-bit in TL0 */
	TR0 = 1;			/* Start timer0 */
	while(TF0 == 0);		/* Wait until timer0 flag set */
	TR0 = 0;			/* Stop timer0 */
	TF0 = 0;			/* Clear timer0 flag */
}

 

余下程序:

模式116位定时器模式)

模式1是16位定时器模式,用于产生延迟,它使用8位THx和8位TLx组成一个总共16位寄存器。

(五)51基础:8051定时器
8051定时器模式1

让我们使用AT89C51微控制器生成2ms时间周期的方波,其中timer0在mode1的端口1的P1.0引脚上。假设Xtal振荡器频率为11.0592 MHz。

(五)51基础:8051定时器

由于Xtal是11.0592 MHz,我们的机器周期为1.085us。

因此,需要计数以产生1毫秒的延迟。是,

计数=(1×10^(-3)) / (1.085×10^(-6) ) ≈ 921 

并且mode1的最大计数是2 ^ 16(0 – 65535),并且它从0增加到65535所以我们需要加载比最大值少921的值。计数即65535。此外,在下面的程序中,我们需要额外的13个MC(机器周期)从调用到返回延迟功能。因此需要加载的Value是,

Value=(65535-Count)+Function_MCycles+1 =64615= (FC74)Hex

所以我们需要在T​​H0中加载FC74 Hex值高字节,在TL0中加载低字节,

TH0 = 0xFC & TL0 = 0x74

延迟功能的编程步骤

  1. 加载Tmod寄存器值,即TM0 = 0x01,用于Timer0模式1(16位定时器模式)。
  2. 加载计算的THx值,即TH0 = 0xFC。
  3. 加载计算的TLx值,即TL0 = 0x74。
  4. 通过设置TRx位启动定时器。即这里TR0 = 1。
  5. 轮询TFx标志直到它没有设置。
  6. 通过清零TRx位来停止定时器。即这里TR0 = 0。
  7. 清除定时器标志TFx位,即TF0 = 0。
  8. 从步骤1到7重复再次延迟。

定时器模式的程序1

/*
 * 8051_Timer_Mode1
 * http://www.qutaojiao.com
 */
#include <reg51.h>		/* Include x51 header file */
sbit test = P1^0;		/* set test pin0 of port1 */ 

void timer_delay()		/* Timer0 delay function */
{
	TH0 = 0xFC;		/* Load higher 8-bit in TH0 */
	TL0 = 0x74;		/* Load lower 8-bit in TL0 */
	TR0 = 1;		/* Start timer0 */
	while(TF0 == 0);	/* Wait until timer0 flag set */
	TR0 = 0;		/* Stop timer0 */
	TF0 = 0;		/* Clear timer0 flag */
}

 

余下程序:

模式2(8位自动重载定时器模式)

模式2是8位自动重载定时器模式。在此模式下,我们只需加载THx-8位值。当Timer启动时,THx值自动被装入TLx,TLx从该值开始计数。在TLx的值从0xFF溢出到0x0之后,TFx标志被置位,并且来自THx的值再次自动加载到TLx寄存器中。这就是为什么这被称为自动重载模式。

(五)51基础:8051定时器
8051定时器模式2自动重新加载

在这里,我们在PORT1.0上生成200us的方波。在mode2中使用Timer1的时间段。我们将使用11.0592 MHz Xtal振荡器频率。

(五)51基础:8051定时器

8051 Mode2示例Wave

由于Xtal是11.0592 MHz,我们的机器周期为1.085us。因此,需要计数以产生1毫秒的延迟。是,

计数=(100×10^(-6)) / (1.085×10^(-6) )≈92

并且mode2的最大计数是2 ^ 8(0 – 255)并且它从0到255递增,因此我们需要加载比其最大值少92的值。计数即255.因此需要加载的Value是:

Value=(255-Count)+1 =164= 0xA4

所以我们需要在高字节中加载A4的十六进制值,

TH1 = 0xA4

延迟功能的编程步骤

  1. 加载Tmod寄存器值,即Timer1 mode2的TMOD = 0x20(8位定时器自动重载模式)。
    加载计算的THx值,即TH1 = 0xA4。
    为TLx加载相同的值,即TL1 = 0xA4。
    通过设置TRx位启动定时器。即这里TR1 = 1。
    轮询TFx标志直到它没有设置。
    清除定时器标志TFx位,即TF1 = 0。
    从步骤5和6重复再次延迟。

定时器模式2的程序

/*
 * 8051_Timer_Mode2
 * http://www.qutaojiao.com
 */
#include <reg51.h>			/* Include x51 header file */
sbit test = P1^0;			/* set test pin0 of port1 */ 

void main()
{
	TMOD = 0x20;			/* Timer1 mode2 (8-bit auto reload timer mode) */
	TH1 = 0xA4;			/* Load 8-bit in TH1 */
	TL1 = 0xA4;			/* Load 8-bit in TL1 once */
	TR1 = 1;			/* Start timer1 */
	while(1)
	{
		test = ~test;		/* Toggle test pin */
		while(TF1 == 0);	/* Wait until timer1 flag set */
		TF1 = 0;		/* Clear timer1 flag */
	}
}

 

8051中的定时器中断

8051具有两个分配有不同向量地址的定时器中断。当定时器计数从其最大值翻转到0时,它设置定时器标志TFx。如果启用了全局和定时器中断,这将中断8051微控制器以服务ISR(中断服务程序)。

(五)51基础:8051定时器

定时器溢出中断分配有表中所示的向量地址。8051微控制器在发生相应的中断时直接跳转到向量地址。

(五)51基础:8051定时器

8051定时器中断

这里我们将使用Timer0中断在PORT1.0上产生10Hz的方波。我们将在mode1中使用Timer0,振荡器频率为11.0592 MHz。

(五)51基础:8051定时器

8051定时器中断示例波形

由于Xtal是11.0592 MHz,我们的机器周期为1.085us。因此,需要计数以产生50毫秒的延迟。是,

计数 =(50×10^(-3)) / (1.085×10^(-6) ) ≈ 46080

并且mode1的最大计数是2 ^ 16(0 – 65535),并且它从0到65535递增,因此我们需要加载比其最大值少46080的值。计数即65535.因此需要加载的Value是:

Value=(65535-Count)+1 =19456= (4C00)Hex

因此,我们需要在较高字节和较低字节中加载4C00 Hex值:

TH0 = 0x4C & TL0 = 0x00

注意,TF0标志无需通过软件清除,因为微控制器在完成ISR例程后将其清除。

定时器中断程序

/*
 * 8051_Timer_Interrupt
 * http://www.qutaojiao.com
 */
#include<reg51.h>		/* Include x51 header file */
sbit test = P1^0;		/* set test pin0 of port1 */

void Timer_init()
{
	TMOD = 0x01;		/* Timer0 mode1 */
	TH0 = 0x4C;		/* 50ms timer value */
	TL0 = 0x00;      
	TR0 = 1;  	      	/* Start timer0 */
}


void Timer0_ISR() interrupt 1	/* Timer0 interrupt service routine (ISR) */
{
	test = ~test;  		/* Toggle port pin */
	TH0 = 0x4C;      	/* 50ms timer value */
	TL0 = 0x00;      
}

 

余下程序:

本节课程序下载:

给TA打赏
共{{data.count}}人
人已打赏
515151-基础

(四)51基础:8051掉电和空闲模式

2019-3-24 14:31:42

515151-基础

(六)51基础:8051中断

2019-3-24 17:46:24

3 条回复 A文章作者 M管理员
  1. edj

    8051 vs arduino 計時及中斷就理論和實驗有何不同?

    • Luca

      原理其实一样,只不过arduino操作中断计时器的时候,封装成了库,操作简便一些。

  2. 寰寜

    我想学习一下

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索
'); })();