Arduino UNO Interrupt Timer

La minuterie est une fonction intégrée dans chaque microcontrôleur et a certaines fonctions concernant le passage du temps. La fonction Timer d'un microcontrôleur peut être expliquée spécifiquement par le fait que le Timer fonctionne pour déterminer quand le programme sera exécuté et quand le programme sera arrêté. La minuterie d'un microcontrôleur se compose de plusieurs registres dont les valeurs diminuent et augmentent automatiquement. Sur l'Arduino UNO, il existe deux types de timers, à savoir un timer avec une résolution de 8 bits et un timer avec une résolution de 16 bits. Cependant, FS Tech ne discutera pas plus spécifiquement de ce timer car dans cette instruction, nous nous concentrons sur la façon d'exécuter et de régler le timer sur l'Arduino UNO.

Pourquoi utiliser un temporisateur d'interruption ?

Le réglage du timer sur le microcontrôleur nous permet d'exécuter des programmes en utilisant des temps très spécifiques à certains intervalles de temps d'une manière multitâche. Comme nous le savons, Arduino exécute un programme en boucle en utilisant la fonction void loop(void) {} dans l'ordre dans lequel il est écrit, mais il sera très difficile de déterminer le temps des événements contenus dans cette fonction. Cela est dû au fait que certaines commandes sont exécutées très rapidement et d'autres très lentement, en fonction du nombre de programmes exécutés et d'instructions conditionnelles telles que if, while, do while ou for loop. La minuterie qui s'exécute sur la fonction Arduino loop() est très difficile à prévoir en raison des nombreuses fonctions contenues dans la bibliothèque Arduino.

La minuterie d'interruption du microcontrôleur vous permet de contrôler la durée d'exécution de la fonction loop() à des intervalles de temps précis. Lorsque la minuterie d'interruption est exécutée, elle arrête la durée d'exécution de la fonction loop() et exécute une série de programmes distincts s'exécutant sur une minuterie en dehors de la fonction loop() et renvoyant la minuterie pour exécuter à nouveau la fonction loop() après qu'une autre minuterie a fini d'exécuter le programme.

Voici quelques-uns des avantages que présente l'utilisation d'une minuterie d'interruption :

  • Mesure des signaux entrants à intervalles réguliers
  • Calcule le temps entre deux programmes
  • Transmet et génère des signaux à certaines fréquences
  • Vérifier périodiquement les données sérielles entrantes
  • Exécuter deux programmes simultanément (multitâche)
  • Et bien d'autres encore

Prescaler et calcul des valeurs de la minuterie

L'Arduino Uno possède trois minuteries, la minuterie 0, la minuterie 1 et la minuterie 3. Chaque minuterie de l'Arduino Uno a un réglage de temps qui augmente avec chaque période de temps jusqu'à ce qu'il atteigne une certaine valeur qui est stockée dans un registre, et sera réinitialisé chaque fois que la valeur de temps a été atteinte. Ce cycle se poursuit lorsque l'Arduino est allumé. La valeur de la minuterie dépend de la taille des bits d'adresse de la minuterie, par exemple, une minuterie avec une valeur de 8 bits a une plage de valeurs entre 0-255 et une minuterie avec une résolution de 16 bits a une plage de valeurs de 0-65535.

Pour pouvoir calculer un timer, on peut utiliser un calcul appelé prescaler. Ce calcul peut s'écrire avec l'équation suivante.

TimerSpeed(Hz) = ArduinoClockSpeed(16MHz) / prescaler

Valeur de l'échelle à l'adresse de l'échelle

Le tableau ci-dessus indique la valeur du prescaler à chaque adresse du prescaler, de sorte que l'équation de la valeur de calcul du Timer peut être écrite à l'aide de l'équation suivante.

Fréquence d'interruption (Hz) = ArduinoClockSpeed(16MHz) / ((prescaler * (compareMatchRegister + 1))

+1 en raison de la comparaison des valeurs de registre correspondantes indexées à 0.

Ainsi, si vous voulez une valeur de prescaler, l'équation peut être écrite selon l'équation suivante.

CompareMatchRegister = 16MHz / (prescaler * DesiredInterruptFrequency) - 1

N'oubliez pas que si vous utilisez Timer-0 et Timer-2, la valeur doit être inférieure à 256 et que si vous utilisez Timer-1, la valeur doit être inférieure à 65536. 

Comment utiliser les interruptions de temporisation pour exécuter des programmes multitâches ?

Timer-0 2KHz

				
					void setup(void) {
	cli() ;
	TCCR0A = 0 ;
	TCCR0B = 0 ;
	TCNT0 = 0 ;
	OCR0A = 124 ;
	TCCR0A |= (1<<WGM01) ;
	TCCR0B |= (1<<CS01) | (1<<CS00) ;
	TIMSK0 |= (1<<OCIE0A) ;
	sei() ;
}
				
			

TCCR0A = 0 ; TCCR0B, TCNT0 = 0 ; renvoie la valeur du temps à 0.

OCR0A réglage du registre de comparaison pour des incréments de 2KHz (16*10^6)/(2000*64)-1

WGM01 activer la CTC

CS01 & CS00 définir les bits CS01 & CS00 pour le prescaler 64

TIMSK0 activation de l'interruption de la comparaison de la minuterie

Timer-1 1Hz

				
					void setup(void) {
	cli() ;
	TCCR1A = 0 ;
	TCCR1B = 0 ;
	TCNT1 = 0 ;
	OCR1A = 15624 ;
	TCCR1B |= (1<<WGM12) ;
	TCCR1B |= (1<>CS10) ;
	TIMSK1 |= (1<<OCIE1A) ;
	sei() ;
}
				
			

TCCR1A = 0 ; TCCR1B, TCNT1 = 0 ; permet de ramener la valeur du temps à 0.

OCR1A réglage du registre de comparaison pour des incréments de 1Hz (16*10^6)/(1*1024)-1

WGM12 activer la CTC

CS10 & CS12 définir les bits CS10 & CS12 pour le prescaler 1024

TIMSK1 activation de l'interruption de la comparaison de la minuterie

Timer-2 8KHz

				
					void setup(void) {
	cli() ;
	TCCR2A = 0 ;
	TCCR2B = 0 ;
	TCNT2 = 0 ;
	OCR2A = 249 ;
	TCCR2A |= (1<<WGM21) ;
	TCCR2B |= (1<<CS21) ;
	TIMSK2 |= (1<<OCIE2A) ;
	sei() ;
}
				
			

TCCR2A = 0 ; TCCR2B, TCNT2 = 0 ; permet de ramener la valeur du temps à 0.

OCR2A réglage du registre de correspondance des comparaisons pour des incréments de 8KHz (16*10^6)/(8000*8)-1

WGM21 activer la CTC

CS21 régler les bits CS21 pour le prescaler 8

TIMSK1 activation de l'interruption de la comparaison de la minuterie

Par exemple, le mode CTC peut être utilisé pour régler le temps de fonctionnement de la minuterie.

TCCR0A |= (1 << WGM01) ; // pour le Timer 0

TCCR1B |= (1 << WGM12) ; // pour le Timer 1

TCCR2A |= (1 << WGM21) ; // pour le Timer 2

Il s'agit d'un prescaler qui peut être utilisé dans le tableau ci-dessous.

TCCR1B |= (1 << CS11) ; // 8 prescaler pour le timer 1 

TCCR2B |= (1 << CS22) ; // Prescaler 64 pour le timer 2

TCCR0B |= (1 << CS02) | (1 << CS00) ; // 1024 prescaler pour le timer 0

La commande que vous voulez exécuter pendant l'interruption du timer se trouve dans le sketch Arduino résumé comme suit, en dehors de la fonction void setup(void) et de la fonction void loop(void), ainsi que des exemples expliqués de chaque timer.

ISR(TIMER0_COMPA_vect) {

// pour le Timer 0

}

ISR(TIMER1_COMPA_vect) {

// pour la minuterie 1

}

ISR(TIMER2_COMPA_vect) {

// pour la minuterie 2

}

Exemple de programme Arduino pour activer une minuterie

Exemple pour Timer-0 2KHz

				
					void setup(void) {
	pinMode(11, OUTPUT) ;
	
	cli() ;
	TCCR0A = 0 ;
	TCCR0B = 0 ;
	TCNT0 = 0 ;
	OCR0A = 124 ;
	TCCR0A |= (1<<WGM01) ;
	TCCR0B |= (1<<CS01) | (1<<CS00) ;
	TIMSK0 |= (1<<OCIE0A) ;
	sei() ;
}
void loop(void) {
	// fait quelque chose sans délai()
}
ISR(TIMER0_COMPA_vect) {
	statique boolean toggle = true ;
	toggle = !toggle ;
	digitalWrite(11, toggle ? HIGH : LOW) ;
}
				
			

Exemple pour Timer-1 1Hz

				
					void setup(void) {
	pinMode(11, OUTPUT) ;
	
	cli() ;
	TCCR1A = 0 ;
	TCCR1B = 0 ;
	TCNT1 = 0 ;
	OCR1A = 15624 ;
	TCCR1B |= (1<<WGM12) ;
	TCCR1B |= (1<>CS10) ;
	TIMSK1 |= (1<<OCIE1A) ;
	sei() ;
}
void loop(void) {
	// fait quelque chose sans délai()
}
ISR(TIMER1_COMPA_vect) {
	statique boolean toggle = true ;
	toggle = !toggle ;
	digitalWrite(11, toggle ? HIGH : LOW) ;
}
				
			

Exemple pour le Timer-2 8KHz

				
					void setup(void) {
	pinMode(11, OUTPUT) ;
	
	cli() ;
	TCCR2A = 0 ;
	TCCR2B = 0 ;
	TCNT2 = 0 ;
	OCR2A = 249 ;
	TCCR2A |= (1<<WGM21) ;
	TCCR2B |= (1<<CS21) ;
	TIMSK2 |= (1<<OCIE2A) ;
	sei() ;
}
void loop(void) {
	// fait quelque chose sans délai()
}
ISR(TIMER1_COMPA_vect) {
	statique boolean toggle = true ;
	toggle = !toggle ;
	digitalWrite(11, toggle ? HIGH : LOW) ;
}
				
			

Fin

A partir des trois exemples de programmes Timer, on peut voir que lorsque l'interruption Timer est activée, il n'est pas recommandé d'utiliser la fonction delay() parce qu'elle peut interférer avec toutes les activités Timer sur le microcontrôleur, surtout si la valeur de la fonction delay() dépasse la valeur du prescaler sur l'interruption Timer, et si votre programme vous oblige à utiliser la fonction delay(), alors utilisez la fonction millis() ou macros() sur votre Arduino, cependant, si la valeur de la fonction delay() ne dépasse pas la valeur du prescaler, alors cela peut être un peu tolérable, mais ce n'est pas un bon choix non plus, et si vous ne comprenez pas la fonction millis() ou macros(), nous pourrons en discuter une autre fois.

Et un petit ajout que j'ai peut-être oublié d'expliquer est la fonction cli() et la fonction sei().

La fonction cli() est utilisée pour désactiver les interruptions de la minuterie.

La fonction sei() est utilisée pour activer l'interruption de la minuterie.

C'est peut-être tout ce que nous pouvons partager avec vous, merci.

Voir aussi.

Blogs associés

Arduino UNO Interrupt Timer

Arduino UNO Interrupt Timer Le Timer est une fonction intégrée dans chaque microcontrôleur et a certaines fonctions concernant le passage du temps. La fonction Timer

Lire plus "

Nous serions ravis de vous entendre