Partage de technologie

04 : Minuterie

2024-07-12

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


Lorsque la minuterie est utilisée, elle compte sur le circuit oscillateur interne. Lorsqu'elle est configurée pour une utilisation par minuterie, la valeur de la mémoire du compteur est incrémentée de 1 à chaque cycle de la machine.

1. Comment régler la minuterie

1. L'oscillateur à cristal (oscillateur à cristal) émet des impulsions et enregistre le nombre d'impulsions pour la synchronisation.
2. La fréquence de l'impulsion est la fréquence de l'horloge, et l'inverse de cette fréquence est la période d'oscillation (cycle d'horloge), qui est également la plus petite unité de temps dans l'ordinateur.
Insérer la description de l'image ici

Comme le montre la figure : la fréquence de l'oscillateur à cristal est de 11,0592 MHz, puis son cycle d'horloge est de 1/11,0592 MHz (seconde), c'est-à-dire qu'un cycle d'impulsion prend autant de secondes.

3. Le cycle machine est le cycle CPU et le temps requis pour une opération de base est appelé cycle machine. Généralement, un cycle machine se compose de plusieurs cycles d'horloge. Normalement, c'est 12 fois/6 fois.
Insérer la description de l'image ici

Insérer la description de l'image ici

  • Combien de temps s'est écoulé depuis l'ajout de 1 ?
    Lorsque la fréquence de l'oscillateur à cristal est de 11,0592 MHz, elle est égale à 11059,2 KHz = 11059200 Hz.
    Cycles machine = 12 x cycles d'horloge = 12 x (1/fréquence d'horloge) secondes = 12 / fréquence d'horloge secondes = 12 / 11059200 secondes = 12 000 000 / 11059200 microsecondes = 1,085 (us)
    Autrement dit : lorsque vous utilisez un multiple de 12, le compteur fera +1 tous les 1,085us

2. Comment mettre en œuvre le comptage ?

En configurant les registres concernés : La figure suivante montre les registres pertinents du temporisateur.
Insérer la description de l'image ici

  • Comme le montre la figure, il y a 2 registres : le premier est TCON et le second est TCOM, tous deux comportant 8 bits chacun.
  • Comme le montre la figure, il existe deux types de temporisateurs : le premier est le temporisateur de bits T0 et le second est le temporisateur T1. Ils sont tous deux de 16 bits chacun.

2.1. Registre de contrôle TCON

Insérer la description de l'image ici

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

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

2.2. Registre du mode de fonctionnement TCOM

Insérer la description de l'image ici

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. Minuterie T0

Insérer la description de l'image ici

Le temporisateur T0 a un total de 16 bits, divisés en 8 bits de poids fort TH0 et 8 bits de poids faible TL0. Par conséquent, un total de 2^16 nombres (65536) peut être compté, et le cycle de comptage de 1 nombre est de 1,085us, donc la valeur par défaut est de commencer à compter à partir de 0, et le timing cumulé est d'environ 71 ms.

3. Cas : utilisez la minuterie T0 pour contrôler l'allumage et l'extinction de la LED à intervalles de 1 s.

Code ① :

#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

【Noter】

  • Après chaque rapport, le temporisateur doit recevoir une nouvelle valeur initiale.
  • cnt augmente de 1 toutes les 10 millisecondes. Lorsque cnt augmente jusqu'à 100, cela signifie qu'une seconde s'est écoulée.

Optimisation du code② :

#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

Encapsulez l’initialisation du timer T0 dans une fonction et appelez-la directement en cas de besoin.
Mais utiliser TMOD = 0x01 ; une telle initialisation présente également des défauts :

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

Optimisation du code ③ :

#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

On trouve que l’initialisation de TMOD est :

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

Quels sont les avantages d’une telle initialisation ?

假如定时器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