Articles

Faire clignoter une LED

Vous n'êtes pas authentifié. Si vous apparaissez connecté sur la page d'accueil, veuillez-vous déconnecter puis vous reconnecter.
Pour que vos résultats soient conservés, il est nécessaire de vous inscrire sur le site et de vous authentifier.
Votre note : 0/

1. Introduction

Pour faire clignoter une LED, on peut utiliser différentes approches, plus ou moins complexes, dont certaines seront adaptées à toutes les situations et d'autres pas.

Note : par la suite, on considère que l'horloge du microcontrôleur est précise et exactement de 16MHz.

2. Une méthode simple mais limitée

Commençons par un premier exemple correspondant à ce qui a été vu au moment d'étudier les entrées / sorties tout ou rien.

Pour rappel, voici une portion du code du programme blinkingALed_V1.c tel qu'il a été réalisé précédemment :

int main(void)
{
	// Initialisation
	initSwitchesButtons();
	initLEDs();

	// Boucle principale
    while(1)
    {
		setLED(RED, ON);
		_delay_ms(1000);

		setLED(RED, OFF);
		_delay_ms(1000);
    }
}

2.1. Le temps séparant les changements d'état de la LED rouge est-il exactement de 1 seconde ?

  • Valider vos choix
  • Tout effacer
  • 0 ptsPoint(s) obtenu(s)
    • Bonne réponse : 2 pt(s). Mauvaise réponse : -1 pt(s). Pas de réponse : 0 pt

    Correction

    Puisqu'on demande à la fonction de délai d'attendre 1 seconde, il faut également du temps pour exécuter les instructions associées aux changements d'état de la LED. Donc non, le temps séparant chaque changement ne sera pas de 1s.

    2.2. Comment fonctionne la fonction _delay_ms() ?

  • Valider vos choix
  • Tout effacer
  • 0 ptsPoint(s) obtenu(s)
    • Bonne réponse : 2 pt(s). Mauvaise réponse : -1 pt(s). Pas de réponse : 0 pt

    Correction

    Ne rien faire, lorsqu'on parle d'un processeur n'a de sens que si il est en veille. Tant qu'un signal d'horloge rythme son fonctionnement et qu'il n'est pas en vieille, le processeur exécute les instructions présentes dans le programme.

    La fonction _delay_ms() pourrait effectivement programmer le mise en veille du processeur en configurant un périphérique pour le réveiller au moment opportun (un circuit intégré d'horloge temps réel par exemple). C'est une approche complexe qui n'est pas exploité ici.

    La fonction _delay_ms() est en réalité une boucle dont le nombre d'itérations est calculé à partir du délai spécifié par le programmeur comme argument de la fonction _delay_ms(). Pour être plus précis, lorsque vous écrivez une boucle en C, la phase d'initialisation de la boucle prend un certain temps dépendant directement du nombre d'instructions du processeur utilisées pour cela. Il en va de même pour la séquence d'itération de la boucle ainsi que la condition d'évolution. Le temps imparti pour chacune des étapes peut être connus précisément et on peut donc facilement calculer le nombre d'itérations à réaliser pour fixer la durée complète d'une boucle.

    2.3. Bilan sur cette approche

    Puisque toutes les ressources du processeur sont utilisées pour faire une boucle vide dont la durée est fixée, on ne peut rien lui faire faire d'autre pendant ce temps. On dit que la fonction _delay_ms() est une fonction bloquante puisque l'exécution de la boucle principale du programme ne peut se poursuivre que lorsque la fonction _delay_ms() se termine.

    Pour de très faibles délais, quelques microsecondes, cela ne peut aucune problème. Au delà, on comprend aisément qu'il va être difficile de faire faire autre chose à notre programme s'il faut chaque fois attendre une ou plusieurs secondes pour la tâche soit effectuée.

    Pour illustrer cela, considérons le programme suivant dans lequel on souhaite faire clignoter la LED rouge avec une périodicité de 2s et, dans le même temps, on veut que la LED orange recopie l'état du bouton poussoir SW2.

    		// Boucle principale
        while(1)
        {
    			// Clignotement de la LED rouge
    			setLED(RED, ON);
    			_delay_ms(1000);
    
    			setLED(RED, OFF);
    			_delay_ms(1000);
    
    			// Recopie de l'état du bouton poussoir SW2 sur la LED ORANGE
    			if (getSwitchButton(SW2) == PRESSED) setLED(ORANGE, ON); else setLED(ORANGE, OFF);
        }

    Que se passe-il lorsqu'on appuie sur SW2 ? On doit attendre que les instructions liées au clignotement de la LED rouge aient été exécutées ! Par conséquent, le test de l'état du bouton poussoir SW2 n'aura lieu que toutes les 2s environ.

    Conclusion : dès qu'on veut réaliser plusieurs choses dans notre boucle principale, on ne peut pas avoir de dispositifs bloquants dont la durée peuvent excède quelques microsecondes et peut nuire à la réactivité du système.