Compartilhamento de tecnologia

Microcontrolador Puzhong 51: explicação detalhada e aplicação de temporizadores e contadores (7)

2024-07-12

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

Insira a descrição da imagem aqui

introdução

Temporizadores e contadores são módulos de hardware usados ​​para medir intervalos de tempo ou contar eventos. Eles podem ser usados ​​em muitas aplicações, como geração de atrasos precisos, medição de frequências, contagem de eventos externos, etc. O temporizador do microcontrolador 51 pertence aos recursos internos do microcontrolador, e a conexão e operação de seu circuito são completadas dentro do microcontrolador. Este artigo apresentará detalhadamente o princípio de funcionamento, método de configuração e aplicação de temporizadores e contadores no microcontrolador 51.

Este capítulo abordará conhecimentos relacionados a interrupções. Para conteúdo específico, consulte:Explicação do sistema de interrupção

Nota: Os recursos do temporizador estão relacionados ao modelo do microcontrolador. Diferentes modelos de microcontroladores podem ter diferentes números de temporizadores e métodos de operação, mas de modo geral, os métodos de operação de T0 e T1 são comuns a todos os 51 microcontroladores.

Como funciona o cronômetro

O temporizador é como um pequeno despertador dentro do microcontrolador. De acordo com o sinal de saída do relógio, o valor da unidade de contagem aumenta um a cada “um segundo”. Quando o valor da unidade de contagem aumenta para o "tempo definido de lembrete de alarme", a unidade de contagem emitirá uma solicitação de interrupção para o sistema de interrupção, gerará um "lembrete de toque" e fará com que o programa salte para a função de serviço de interrupção para execução .

O princípio de funcionamento do temporizador/contador é baseado em pulsos de clock. No modo temporizador, eles usam uma fonte de relógio interna para contar; no modo contador, eles usam uma fonte de pulso externa para contar; Cada temporizador/contador possui um registro que armazena o valor da contagem atual.

Registro do modo de operação do temporizador/contador TMOD

As funções de temporização e contagem são controladas pelos bits de controle do registrador de função especial TMOD. CT Quadrado {T}CE Para fazer uma seleção, as informações do registro TMOD estão listadas na tabela a seguir. Pode-se observar que os 2 temporizadores/contadores possuem quatro modos de operação, selecionados através de M1 e M0 do TMOD. Os modos 0, 1 e 2 dos dois temporizadores/contadores são iguais, mas o modo 3 é diferente. As funções em cada modo são as seguintes:
Insira a descrição da imagem aqui

Modo de trabalho do temporizador

Ao definir M1 e M0 no registro TMOD, o temporizador/contador 0 e 1 tem quatro modos de operação diferentes.

Modo 0 (temporizador/contador de 13 bits)

Insira a descrição da imagem aqui
O diagrama do modo de trabalho é o seguinte:
Insira a descrição da imagem aqui

Modo 1 (temporizador/contador de 16 bits)

O modo 1 é exatamente igual ao modo 0, exceto que todos os 16 bits de TH0 e TL0 são usados. Neste modo, o overflow de 8 bits de TL0 é transportado para TH0, e o overflow de TH0 define o sinalizador de overflow TF0 em TCON.

Quando GATE=0(TMOD.3), se TR0=1, o temporizador conta. Quando GATE=1, a entrada externa INTO pode controlar o temporizador 0, para que a medição da largura de pulso possa ser alcançada. TRO é o bit de controle no registro TCON. Para a descrição da função específica de cada bit do registro TCON, consulte a introdução do registro TCON na seção anterior.

Nota: O temporizador do microcontrolador da série STC89C51RC/RD+ possui duas taxas de contagem: uma é o modo 12T, adicionando 1 a cada 12 clocks, o mesmo que o microcontrolador 8051 tradicional, a outra é o modo 6T, adicionando 1 a cada 6 clocks, a velocidade A; A taxa T0, que é 2 vezes maior que a do microcontrolador 8051 tradicional, é definida no programador STC-ISP ao gravar o programa do usuário.

Modo 2 (modo de recarga automática de 8 bits)

Neste modo, o temporizador/contador pode recarregar automaticamente o contador de 8 bits. O overflow do TL0 não apenas configura o TF0, mas também recarrega o conteúdo do TH0 no TL0. (TH0 pode ser definido primeiro e o conteúdo de TH0 permanecerá inalterado durante a reinstalação)
Insira a descrição da imagem aqui

Modo 3 (dois contadores de 8 bits)

Para o Timer 0, neste modo, o Timer 1 para a contagem e o efeito é o mesmo que definir TR1 como 0.


Para o temporizador 0, neste modo, TL0 e TH0 do temporizador 0 funcionam como dois contadores independentes de 8 bits. A figura abaixo mostra o diagrama lógico do temporizador 0 no modo 3. TL0 ocupa o bit de controle do temporizador 0: CT Quadrado {T}CE , GATE, TRO, INTO e TFO. THO está limitado à função de temporizador (período de contagem) e ocupa TR1 e TF1 do temporizador 1. Neste momento, TH0 controla a interrupção do temporizador 1.

O Modo 3 é fornecido para adicionar um temporizador/contador adicional de 8 bits, dando ao microcontrolador três temporizadores/contadores. O modo 3 é aplicável apenas ao temporizador/contador 0. Quando o temporizador T1 está no modo 3, é equivalente a TR1-0 e interrompe a contagem, e T0 pode ser usado como dois temporizadores.
Insira a descrição da imagem aqui

Processo de configuração do temporizador

  1. Atribua valores ao TMOD para determinar como T0 e T1 funcionam.
  2. Calcule o valor inicial de acordo com o tempo a ser cronometrado e escreva-o em TH0, TL0 ou TH1, TL1.
  3. Se forem utilizadas interrupções, atribua um valor ao EA e abra o temporizador de interrupção total.
  4. Defina TR0 ou TR1 para iniciar a cronometragem ou contagem do temporizador/contador.

Nota: A ferramenta de programação STC-ISP vem com o valor inicial do tempo a ser calculado. Você pode copiar o código de acordo com a modalidade que escolher.
Insira a descrição da imagem aqui

Demonstração de código - LED1 pisca em intervalo de 1 segundo

A luz indicadora LED1 é controlada para piscar em intervalos de 1 segundo através da interrupção do temporizador 0 O diagrama físico é conectado: D1 é conectado ao pino P2_0 O clock de 12.000MHz é acionado em um intervalo de um milissegundo. cada vez. A função de gatilho de interrupção é usada para contagem. Quando é 1000, é um segundo.

#include <REGX52.H>

sbit LED1 = P2^0;

void External0_ISR(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;	//需要手动复原			
	TH0 = 0xFC;	//需要手动复原
    // 中断处理代码
	if(count == 1000)
	{
		count = 0;
		LED1 = !LED1;
	}
	count++;
}


void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0 = 1;//打开T0中断
	EA = 1;//打开总中断
	TR0 = 1;				//定时器0开始计时
}


void main()
{
	Timer0_Init();
	while(1)
	{
		
	}	
}
  • 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

Demonstração de código - o botão 1 controla o status da luz LED de funcionamento

Nesta demonstração, as funções _crol_left shift e _cror_right shift na biblioteca INTRINS.H são usadas. Quando o botão KEY1 é pressionado, a luz de funcionamento do LED mudará o estado de direção e piscará. Conexão física da imagem: K1 é conectado ao pino P0_0 e as oito luzes LED são inseridas no pino P2.

  • Crocodilo(unsigned char val, unsigned char n): Gire os caracteres para a direita e gire val para a direita em n bits.
  • Crol-Crocodilo(unsigned char val, unsigned char n): Gira os caracteres para a esquerda, gira val para a esquerda em n bits
#include <REGX52.H>
#include <INTRINS.H>

sbit KEY1 = P0^0;
sbit KEY2 = P0^1;
unsigned char LEDMode;

void DelayXms(unsigned int xms)	//@12.000MHz
{
	unsigned char data i, j;
	
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0 = 1;//打开T0中断
	EA = 1;//打开总中断
	TR0 = 1;				//定时器0开始计时
}

void External0_ISR(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;	//需要手动复原			
	TH0 = 0xFC;	//需要手动复原
    // 中断处理代码
	if(count == 1000)
	{
		count = 0;
		if(LEDMode == 0)
			P2 = _crol_(P2,1);
		if(LEDMode == 1)
			P2 = _cror_(P2,1);

	}
	count++;
}

unsigned char Getkey()
{
	unsigned char keyNumber = 0;
	if(KEY1 == 0)
	{
		DelayXms(5);
		while(KEY1 == 0);
		DelayXms(5);
		keyNumber = 1;
	}
	if(KEY2 == 0)
	{
		DelayXms(5);
		while(KEY2 == 0);
		DelayXms(5);
		keyNumber = 2;
	}
	return keyNumber;
}


void main()
{
	unsigned char keyNum = 0;
	P2 = 0xfe;
	Timer0_Init();
	while(1)
	{
		keyNum = Getkey();
		if(keyNum)
		{
			if(keyNum == 1)
			{
				LEDMode++;
				if(LEDMode>=2)
				{
					LEDMode = 0;	
				}
			}
		}
	}
}
  • 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
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

Demonstração de código - display do relógio temporizador LCD1602

Este código de demonstração usa o módulo LCD1602 como display. O módulo LCD1602 não será explicado em detalhes e instruções especiais do capítulo serão fornecidas posteriormente. Se você precisar da biblioteca LCD1602, pode me enviar uma mensagem em particular. Conexão física da imagem: Basta conectar o módulo LCD1602 à placa.

#include <REGX52.H>
#include "LCD1602.h"

unsigned char Sec=55,Min=59,Hour;//秒分时

void DelayXms(unsigned int xms)	//@12.000MHz
{
	unsigned char data i, j;
	
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0 = 1;//打开T0中断
	EA = 1;//打开总中断
	TR0 = 1;				//定时器0开始计时
}

void External0_ISR(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;	//需要手动复原			
	TH0 = 0xFC;	//需要手动复原
    // 中断处理代码
	if(count == 1000)
	{
		count = 0;
		Sec++;
		if(Sec == 60)
		{
			Sec = 0;
			Min++;
			if(Min == 60)
			{
				Min = 0;
				Hour++;
				if(Hour == 24)
				{
					Hour = 0;
				}
			}

		}
	}
	count++;
}

void main()
{
	Timer0_Init();
	LCD_Init();
	LCD_ShowString(1,1,"Time:");
	LCD_ShowString(2,1,"00:00:00");
	while(1)
	{
		LCD_ShowNum(2,1,Hour,2);
		LCD_ShowNum(2,4,Min,2);
		LCD_ShowNum(2,7,Sec,2);
	}	
}
  • 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
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75