Compartir tecnología

04: Temporizador

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


Cuando se utiliza el temporizador, éste depende del circuito oscilador interno para contar. Cuando se configura para uso con temporizador, el valor de la memoria del contador aumenta en 1 en cada ciclo de la máquina.

1. Cómo configurar el temporizador

1. El oscilador de cristal (oscilador de cristal) emite pulsos y registra el número de pulsos para cronometrar.
2. La frecuencia del pulso es la frecuencia del reloj y el recíproco de esta frecuencia es el período de oscilación (ciclo del reloj), que también es la unidad de tiempo más pequeña en la computadora.
Insertar descripción de la imagen aquí

Como se muestra en la figura: la frecuencia del oscilador de cristal es 11,0592 MHz, luego su ciclo de reloj es 1/11,0592 MHz (segundo), es decir, un ciclo de pulso dura tantos segundos.

3. El ciclo de la máquina es el ciclo de la CPU y el tiempo requerido para una operación básica se llama ciclo de la máquina. Generalmente, un ciclo de máquina consta de varios ciclos de reloj. Normalmente es 12 veces/6 veces.
Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

  • ¿Cuánto tiempo ha pasado desde que sumaste 1?
    Cuando la frecuencia del oscilador de cristal es 11.0592MHz, es igual a 11059.2KHz = 11059200Hz
    Ciclos de máquina = 12 x ciclos de reloj = 12 x (1/frecuencia de reloj) segundos = 12 / frecuencia de reloj segundos = 12 / 11059200 segundos = 12 000 000 / 11059200 microsegundos = 1,085 (us)
    Es decir: al usar un múltiplo de 12, el contador hará +1 cada 1.085us

2. ¿Cómo implementar el conteo?

Configurando los registros relevantes: La siguiente figura muestra los registros relevantes del temporizador.
Insertar descripción de la imagen aquí

  • Como se muestra en la figura, hay 2 registros: el primero es TCON y el segundo es TCOM, ambos de 8 bits cada uno.
  • Como se muestra en la figura, hay dos tipos de temporizadores: el primero es el temporizador de bits T0 y el segundo es el temporizador T1. Ambos tienen 16 bits cada uno.

2.1. Registro de control TCON

Insertar descripción de la imagen aquí

TF0:定时器T0溢出中断标志,当定时器0开始计数时,计数到规定的时间时,定时器产生了溢出。TF0自动由0变位1(由硬件置1)。
如果不用中断,需要手动清零。

TR0:定时器T0的控制位,当为1时,定时器T0才能计数,相当于T0的开关(由软件控制)。
  • 1
  • 2
  • 3
  • 4

2.2. Registro de modo de trabajo TCOM

Insertar descripción de la imagen aquí

GATE:门控制位,当GATE=0时:计数条件只有TR1一个(TR1=1就计数,TR1=0就不计数)。
			   当GATE=1时:是否计数不仅取决于TR1还取决于INT1引脚
C/T :时钟输入选择为,为1时,时钟从外部引脚P3.5口输入;为0时,时钟从内部输入
M1      M0
0        0        :13位定时器,使用高8位和低5位
0        1        :16位定时器,全用
1        0        :8位自动重装载定时器,当溢出时将TH1存放的值自动重装入TL1.
1        1        :定时器无效
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.3. Temporizador T0

Insertar descripción de la imagen aquí

El temporizador T0 tiene un total de 16 bits, divididos en los 8 bits altos TH0 y los 8 bits bajos TL0. Por lo tanto, se pueden contar un total de 2 ^ 16 números (65536), y el ciclo de contar 1 número es 1.085us, por lo que el valor predeterminado es comenzar a contar desde 0 y el tiempo acumulado es de aproximadamente 71 ms.

3. Caso: Utilice el temporizador T0 para controlar que el LED se encienda y apague en intervalos de 1 s.

Código ①:

#include <REGX52.H>

sbit LED1 = P3^7;
void main(void)
{
	int cnt = 0;
	LED1 = 1;//先让灯熄灭的状态
	
/*1、选择定时器T0,并配置为16位定时器*/
	TMOD =0x01;							// 0000 0001
	
/*
	2、定一个10ms的时间,数1下需要1.085us
	10ms需要数则需要数9216下,那从65536-9126=56320
	从56320这里开始数,数9216下就到了65536。当超过了
	65536时就报表了,控制寄存器TCON的TF0由0变为1	
*/
	TL0 = 0x00; //0000 0000
	TH0 = 0xDC;//1101 1100
	
/*3、打开定时器T0*/
	TR0 = 1;
	
	TF0 = 0;//先个溢出标志清零
	while(1)
	{
		if(TF0 == 1)//10ms报表了
		{	
			TF0 = 0;//软件清零,现在不使用中断
			TL0 = 0x00; //重新给初值
			TH0 = 0xDC;
			cnt++;
			if(cnt == 100)//数100次,相当于1s
			{
				cnt = 0;
				LED1 = !LED1;
			}
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

【Nota】

  • Después de cada informe, se debe dar al temporizador un nuevo valor inicial.
  • cnt aumenta en 1 cada 10 milisegundos. Cuando cnt aumenta a 100, significa que ha pasado 1 segundo.

Optimización de código②:

#include <REGX52.H>

sbit LED1 = P3^7;

void Timer0_Init_10ms(void)//定时器初始化10ms
{
	TMOD =0x01;							
	
	TL0 = 0x00; //0000 0000
	TH0 = 0xDC;//1101 1100
	
	TR0 = 1;
	TF0 = 0;
}

void main(void)
{ 
	int cnt = 0;
	LED1 = 1;//先让灯熄灭的状态
	Timer0_Init_10ms();
	
	while(1)
	{
		if(TF0 == 1)//10ms报表了
		{	
			TF0 = 0;//软件清零,现在不使用中断
			TL0 = 0x00; //重新给初值
			TH0 = 0xDC;
			cnt++;
			if(cnt == 100)//数100次,相当于1s
			{
				cnt = 0;
				LED1 = !LED1;
			}
			
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

Encapsule la inicialización del temporizador T0 en una función y llámela directamente cuando sea necesario.
Pero usar TMOD = 0x01; dicha inicialización también tiene fallas:

假如定时器T1正在使用,且为16位定时器。则TMOD的高4位应该为:0x1(0001)
而我们使用定时器T0时TMOD初始为0x01,则TMOD的高4位为0x0(0000),则把定时器T1变为一个13位定时器了。所以还需要改进
  • 1
  • 2

Optimización de código ③:

#include <REGX52.H>

sbit LED1 = P3^7;

void Timer0_Init_10ms(void)		//10毫秒@11.0592MHz
{
	//AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0xDC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

void main(void)
{ 
	int cnt = 0;
	LED1 = 1;//先让灯熄灭的状态
	Timer0_Init_10ms();
	
	while(1)
	{
		if(TF0 == 1)//10ms报表了
		{	
			TF0 = 0;//软件清零,现在不使用中断
			TL0 = 0x00; //重新给初值
			TH0 = 0xDC;
			cnt++;
			if(cnt == 100)//数100次,相当于1s
			{
				cnt = 0;
				LED1 = !LED1;
			}
			
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

Encontramos que la inicialización de TMOD es:

TMOD &= 0xF0;		//设置定时器模式
TMOD |= 0x01;		//设置定时器模式
  • 1
  • 2

¿Cuáles son los beneficios de inicializar así?

假如定时器T1正在使用,且为16位定时器。则TMOD的高4位应该为:0x1(0001),而要使用定时器T0,且也为16位定时器,则TMOD =  0x11;
TMOD &= 0xF0;表示TMOD = TMOD & 0xf0,则与出来的TMOD = 0x10,由此可见,这一步就是让TMOD的高4位不变,低4位清零。
TMOD |= 0x01;表示TMOD = TMOD | 0x01,则或出来的TMOD = 0x11,由此可见,这一步就是让TMOD的高4位不变,低4位初始化。
通过这样初始化,既保证了TMOD的高4位不变(不改变定时器T1的初始化),由对低4位进行了改变(对定时器T0初始化)。
当然:也可以直让TMOD = 0x11;
  • 1
  • 2
  • 3
  • 4
  • 5