LOCODUINO

Les Timers

Les Timers (II)

Les interruptions

.
Par : Christian

DIFFICULTÉ :

Dans l’article précédent « Les Timers (I) », nous avons étudié quelques généralités sur les timers et nous avons insisté sur le fait qu’il est primordial de bien connaître les registres de contrôle associés aux timers et de bien comprendre leur utilisation. Nous avons réalisé un premier programme faisant clignoter la DEL du module Arduino Uno grâce au timer 2, en surveillant son débordement un certain nombre de fois pour agir sur la DEL.

La surveillance du débordement du timer revient à surveiller le flag TOV2 , ce qui prend du temps et interfère avec le déroulement du programme principal. Afin de libérer le programme de cette tâche de surveillance, nous allons faire appel aujourd’hui aux interruptions commandées par les timers. Une fois de plus, nous utiliserons le timer 2, mais ce que nous allons faire peut aussi se concevoir pour les autres timers du microcontrôleur.

Qu’est-ce qu’une interruption ?

C’est ce qui nous arrive à tous dans notre vie de tous les jours. Imaginez que vous soyez au téléphone et que l’on sonne à votre porte. Vous demandez à votre interlocuteur de patienter, vous posez votre téléphone puis vous allez ouvrir. C’est le facteur qui vous apporte un colis. Une fois celui-ci réceptionné et la porte refermée, vous retournez prendre votre téléphone pour continuer votre conversation. L’interruption (sonnerie) vous a fait vous détourner de votre programme principal (conversation téléphonique) pour aller réaliser un sous-programme (ouvrir la porte) puis vous avez repris votre programme principal là où vous l’aviez laissé (si vous n’avez pas perdu le fil de votre conversation !).

Un microcontrôleur fonctionne de la même façon : un événement interne (timer) ou bien externe (broche) demande une interruption au microcontrôleur (voir aussi « Les interruptions (1) »). Celui-ci va s’interrompre dans son programme principal, puis va exécuter un sous-programme (on parle de routine d’interruption). Une fois que cette routine est exécutée, le microcontrôleur reprend son programme principal, là où il s’était arrêté, et continue son exécution. Pour cela, il a fallu que le microcontrôleur sauve différents registres sur une pile et les rétablisse en fin de routine d’interruption. Il faut aussi que le programmeur ait autorisé les interruptions ; si le programme doit réaliser une tâche selon une chronologie très rigoureuse, il peut être nécessaire de ne pas les autoriser pour ne pas déranger le microcontrôleur et c’est donc au programmeur de décider d’autoriser ou non les interruptions. La fonction sei() permet d’autoriser les interruptions alors que la fonction cli() permet de les ignorer ; on peut aussi utiliser les fonctions interrupts() et noInterrupts() du langage Arduino.

L’interruption du timer 2

Toutes les demandes d’interruption arrivent sur une porte OU et sont éventuellement bloquées par le signal GIE (Global Interrupt Enable) activé par la fonction sei(). La figure suivante nous permet de comprendre comment le timer 2 peut faire une demande d’interruption.

Architecture de pilotage d'un timer
Architecture de pilotage d’un timer
Ce circuit se trouve à l’intérieur du microcontrôleur qui équipe le module Arduino Uno.

La figure se lit de la droite vers la gauche : le signal d’horloge de 16 MHz arrive au prédiviseur qui divise la fréquence en fonction des bits 0 à 2 du registre TCCR2B (voir la première partie de l’article). Le timer TCNT compte ainsi moins rapidement. Lorsqu’il déborde, une bascule est positionnée à 1 : c’est le flag TOV2 que l’on retrouve dans le bit 0 du registre TIFR2. Pour autoriser une interruption par le timer, il faut que le flag TOIE2 (Timer/Counter2 Overflow Interrupt Enable) qui est le bit 0 du registre TIMSK2 (Timer/Counter2 Interrupt Mask Register), soit à 1 ; c’est ce qu’on appelle une autorisation d’interruption locale. Pour que notre timer déclenche une interruption, il faut qu’il y soit autorisé ( TOIE2 à 1) ET qu’il déborde ( TOV2 à 1), ces deux conditions arrivant sur une porte ET en amont de la porte OU. Mais comme on l’a dit plus haut, il faut aussi que les interruptions soient autorisées de façon générale : c’est le rôle du flag GIE , le bit 7 du registre SREG (Status Register) qui alimente une porte ET en aval de la porte OU.

Si toutes les conditions que nous venons de voir sont réunies, l’interruption arrive au microcontrôleur qui va donc interrompre son programme principal pour aller exécuter sa routine d’interruption (ISR pour Interrupt Routine Service). Le système Arduino a prévu une routine au nom réservé qu’il suffit de compléter : celle-ci commence par ISR(TIMER2_OVF_vect) signifiant qu’il s’agit d’une routine d’interruption déclenchée par le vecteur d’overflow du timer 2. Cette routine remet automatiquement à 0 le flag TOV2 , ce qu’il fallait faire soi-même lorsqu’on surveillait le flag sans faire appel aux interruptions (programme de la première partie de l’article).

Programme par interruption

Nous allons donc modifier le programme vu dans la première partie pour que l’inversion de la DEL se fasse par une interruption provenant du timer 2. Les autres conditions restent identiques : initialisation, réglage du prédiviseur (voir le précédent programme). La boucle principale peut accueillir le programme de l’utilisateur ; à titre d’exemple, nous avons mis un programme très classique faisant clignoter une autre DEL (branchée sur la broche 5 d’Arduino) en utilisant la fonction delay(). Bien que cette fonction soit bloquante, cela n’empêche pas la DEL reliée à la broche 13 de clignoter.

// Clignotement d'une LED (mot anglais pour DEL) à 1 Hz par une 
// interruption en provenance du timer 2,
// pendant que le programme principal fait
// clignoter une autre LED (période 10s)
  
const byte Led = 13; // Pour utiliser la LED du module
const byte Led2 = 5; // Led clignotante du programme principal
#define LedToggle digitalWrite (Led, !digitalRead(Led))
#define Led2Toggle digitalWrite (Led2, !digitalRead(Led2))
  
void setup () {
  pinMode (Led, OUTPUT);
  pinMode (Led2, OUTPUT);
  cli(); // Désactive l'interruption globale
  bitClear (TCCR2A, WGM20); // WGM20 = 0
  bitClear (TCCR2A, WGM21); // WGM21 = 0 
  TCCR2B = 0b00000110; // Clock / 256 soit 16 micro-s et WGM22 = 0
  TIMSK2 = 0b00000001; // Interruption locale autorisée par TOIE2
  sei(); // Active l'interruption globale
}
  
byte varCompteur = 0; // La variable compteur
  
// Routine d'interruption
ISR(TIMER2_OVF_vect) {
  TCNT2 = 256 - 250; // 250 x 16 µS = 4 ms
  if (varCompteur++ > 125) { // 125 * 4 ms = 500 ms (demi-période)
    varCompteur = 0;
    LedToggle;
  }
}
  
void loop () {
  // Mettre ici le programme. Exemple :
  Led2Toggle;
  delay (5000); // Demi-période de la deuxième LED
}

Si vous avez bien compris le premier programme, donné dans l’article Les Timers (I), il n’y a aucune difficulté à comprendre celui-ci.

Conclusion

Utiliser les interruptions générées par les timers permet de laisser le programme principal s’occuper d’une autre tâche. Il faut bien sûr autoriser les interruptions d’une façon générale en positionnant à 1 le flag GIE (bit 7 du registre SREG) par la fonction sei() par exemple. Il faut également autoriser les interruptions en provenance du timer (flag TOIE du registre TMSK). Lorsque le timer déborde, le timer génère l’interruption et le programme exécute la routine d’interruption liée à ce débordement. Le flag TOV est alors automatiquement remis à 0 et il suffit alors de réinitialiser le timer avec la valeur adéquate pour son comptage. Le compilateur de l’environnement de développement d’Arduino connaît le nom des routines d’interruptions, ainsi que le nom des registres et des différents flags, ce qui simplifie bien le travail du programmeur. Dans un prochain article, nous verrons comment utiliser d’autres registres liés aux timers.

28 Messages

  • Les Timers (II) 9 avril 2017 18:02, par PIVAR

    J’ai bien mijoté timer 1 et 2 ; bon ,je connais des basics et je commence en arduino (du C ?), mais j’ai remarqué les lignes :"#define LedToggle digitalWrite (Led, !digitalRead(Led))" ; et l’on peut appeler LedToggle comme si c’était une fonction ! ; là , je reste pantois..
    Un petit truc , en ligne 14 on désactive les interruptions pour les réactiver en ligne 19 ; est-ce pour prendre en compte la nouvelle interruption ?

    Répondre

    • Les Timers (II) 10 avril 2017 01:16, par Christian Bézanger

      Le #define permet de dire au préprocesseur de remplacer l’expression de gauche (inconnue dans le monde Arduino) par celle de droite (fonctions classiques).
      Ici, LedToggle permet d’inverser l’état d’une LED : le préprocesseur remplacera ce terme par digitalWrite(Led, !digitalRead(Led)) c’est-à-dire écrire sur la sortie reliée à la LED l’inverse de ce qu’on peut y lire (si la sortie est à HIGH, on l’écrira à LOW et réciproquement).
      Avec #define, j’ai écrit le programme Blink tout en français, ce qui n’a pas d’autre intérêt que de faire taire les détracteurs d’Arduino sous prétexte qu’il faudrait parler anglais...
      Pour déclarer des numéros de broches, on peut utiliser #define mais il est conseillé de préférer des ’const int’.
      Dominique a parfaitement répondu à la question suivante.
      Enfin, nul besoin d’apprendre le C pour Arduino : les fonctions de base sont bien suffisantes pour débuter (voir page Reference du site arduino.cc). Avec le temps et l’expérience, des bases de C++ permettent de faire des choses bien plus puissantes.

      Répondre

      • Les Timers (II) 10 avril 2017 11:04, par PIVAR

        Merci à Christian et Dominique ; pour le #define , c’est une commodité d’écriture ; bon au cas ou , l’expression de droite doit tenir sur une ligne ou peut-elle se prolonger ?
        De mon coté , pour mon appli , je trouve sur votre site pas mal d’infos il est aussi vrai qu’il y a pas mal de similitudes entre les séquences pour trains et celles d’un appareil pour labo ; mon appli sera en 2 parties :l’une sur le pc pour une belle interface graphique et des enregitrements(b4j compilé java) et l’autre sur arduino en C pour une gestion nette et synchrone des stepper , pin entrées sorties ; cela va causer au travers du serial ...mais , je sais , c’est hors sujet
        Bonne journée

        Répondre

        • Les Timers (II) 10 avril 2017 12:02, par Christian Bézanger

          Nous trouvons très bien que des gens qui s’intéressent à la robotique ou bien à la domotique ou encore à d’autres domaines viennent consulter notre site pour y trouver des informations ou des astuces dont ils pourront s’inspirer.
          Néanmoins, nous serions débordés si nous devions répondre à toutes les questions de ces gens, c’est pourquoi nous nous limitons au train miniature et nous renvoyons ces personnes vers d’autres sites spécialisés dans les autres domaines.
          Dans le #define, une expression de droite trop longue n’aurait aucun sens car cela diminuerait la lisibilité du code. Il vaut mieux dans ce cas recourir aux fonctions.

          Répondre

        • Les Timers (II) 10 avril 2017 12:06, par Jean-Luc

          Bonjour,

          L’expression doit tenir sur une ligne mais on peut utiliser le \ en fin de ligne pour faire en sorte que le préprocesseur ignore cette fin de ligne. Par exemple :

          #define uneMacroCompliquee    \
          if (val == 0) {               \
              val = 1;                  \
          }

          Attention, il ne doit pas y avoir de caractères, notamment des espaces, entre le \ et la fin de ligne

          On peut également faire des macros avec des arguments. Christian aurait pu écrire :

          #define pinToggle(aPin)     digitalWrite(aPin, !digitalRead(aPin))

          Répondre

          • Les Timers (II) 10 avril 2017 15:52, par PIVAR

            Merci , je ne veux pas gêner , mais on apprend vite avec vous ; dans la doc arduino ,pour define il est dit que cela sert à définir des constantes , vous êtes mieux que la doc !
            et ce que j’interprète de ce qu’aurait pu Christian :la fonction pinToggle à qui on a transmis la valeur aPin , ecrit à aPin le not de ce qu’on peut lire à aPin (surement que l’on peut mieux dire)
            Je suis curieux et je vais aussi acheter une Wemos mini pro qui se programme sous IDE arduino (7€),moins d’entrées sorties , avec un wifi intégré ..mais pour les timer , je me demande , très peu d’infos

            Répondre

            • Les Timers (II) 10 avril 2017 19:04, par Christian Bézanger

              Pour avoir de la documentation sur les timers, c’est très simple : il suffit de se référer à la datasheet du constructeur du microcontrôleur qui équipe la carte. C’est en anglais et ça ne se comprend pas forcément à la première lecture ; il faut s’accrocher, mais il n’y a que là qu’on trouve ce dont on a besoin.

              Répondre

              • Les Timers (II) 11 avril 2017 10:34

                Merci , c’est en effet en passant par le microcontroleur que l’on trouve des infos , pas par la datasheet qui est en chinois mais sur le web , d’autres se sont déjà posé les questions et se sont répandus ; bon , je ne polluerais plus votre site (bien tenu)
                D.P.

                Répondre

  • Les Timers (II) 9 avril 2017 22:47, par Dominique

    "Un petit truc , en ligne 14 on désactive les interruptions pour les réactiver en ligne 19 ; est-ce pour prendre en compte la nouvelle interruption ?"
    Non c’est pour éviter qu’une interruption arrive pendant la manipulation des registres, ce qui ficherait la pagaille !

    Répondre

  • Les Timers (II) mnemoniques des ISR 17 avril 2017 18:37, par Michel Jevaud

    J’ai cherché sur le web les mnémoniques arduino pour les interrupts : par exemple, vous avez trouvé la mnémonique ISR(TIMER2_OVF_vect) pour le débordement du Timer Counter n°2 (déjà, comment avez vous trouvé cette mnémonique ?), mais pour toutes les autres interrupts possibles ?
    Bon, on trouve à droite à gauche des exemples, par exemple heureusement pour le port série on a la routine serialEvent(), mais existe-t-il une liste officielle Arduino de ces mnémoniques ?
    un grand merci pour votre site, il est très clair

    Répondre

    • Les Timers (II) mnemoniques des ISR 17 avril 2017 19:45, par christian

      Tout cela est décrit dans la datasheet du microcontroleur ATmega328P qui peut être téléchargée sur le site Atmel.
      Quand on veut travailler avec les entrailles d’un microcontroleur, il faut toujours s’y référer.
      Pour le Timers 1, cela aurait été ISR(TIMER1_OVF_vect) : tout cela est donc assez logique et facile à manipuler. De la même façon, les noms des registres sont connus du compilateur.

      Répondre

  • Les Timers (II) 9 juillet 2020 11:30, par Schweitzer

    Bonjour , je suis en train de réaliser un programme avec les timer pour lire a toute les interruptions un signal analogiques cependant je ne sais pas pas ou est mon problème de compréhension. J’
    Je souhaite lire un signal de 50hz par exemple. Je sais que la fonction analogread doit prendre 116 us pour chaque lecture.

    /* Programme viisant a determiner la frequence et l'amplitude d'un signal simple compris entre 0/5V
     * pour un frequence de (50Hz , tension entre 0/5V
     * Soit une periode de 20ms , nous prendrons toute les 0.1 ms
     * 
     * Nous uiliserons le TIMER2 de l'arduino Mega2560;
     * 
    */
    
    /*** Signal SBT1************** ***********************************************/
    void Signal_SBT1(float Tension_SBT1_instant);
    
    #define S_SBT1 A0
    #define Val_SBT1 500 //Nombre de valeur souhaté (je devrais obtenir 2 periode de mon signal)
    
    int i=0;
    
    boolean var=0;
    
    float Tension_SBT1_instant;
    float Tension_SBT1_Tab[Val_SBT1]; 
    
    int   Nbr_x_0=0;
    
    boolean x=1;
    /******************************************************************************************/
    
    void setup()
     {  
      pinMode(S_SBT1,INPUT);
     
      cli();
      bitClear (TCCR2A, WGM20); // WGM20 = 0
      bitClear (TCCR2A, WGM21); // WGM21 = 0 
      
      TCCR2B = 0b00000010; // Clock /8 soit 0.1ms  
      TIMSK2 = 0b00000001; // Interruption locale autorisée par TOIE2
      sei();
      Serial.begin(9600);
    
     }
    
    byte flag=0;
    
    ISR (TIMER2_OVF_vect)
     {
        TCNT2=96;   
        
       if(flag++ >= 1) // toute les 0.1ms
       {
        flag=0;
        
       }
     }
    
    void loop() 
    {   
    
        if(flag==0)  // on verifie l'etat du compteur 
        {
        Tension_SBT1_instant=(analogRead(S_SBT1)*(5.000/1023));
        Signal_SBT1(Tension_SBT1_instant)
      
        }
    }
    
    
    
    void Signal_SBT1(float Tension_SBT1_instant)
    {
    
        if((Tension_SBT1_instant==0) && x==1)  //fonction permettant de debuter l'acquisition a 0; 
            {  
              Serial.println("debut de l'acquisition");
               var=1;
               x=0;
               i=0;
            }
            
            if(var == 1)
            { 
               Tension_SBT1_Tab[i]= Tension_SBT1_instant; 
               
               
               if(i==Val_SBT1)
               {
                Serial.println("********NOUS REGARDONS LES  VALEURS********");
                 for(i=0;i<=Val_SBT1;i++)   //analyse complet du tabeleau obtenu a
                 {
                   Serial.println();
                   Serial.print("Pour la valeurs : ");
                   Serial.print(i) ;
                   Serial.print("du tableau, nous observons une tension de: ");
                   Serial.println(Tension_SBT1_Tab[i]) ;
                   Serial.print("  Volt");
                   Serial.println();
                        
                 }
              
                  
                  
              
                i=0; // on remet i a 0;
                var=0; /on remet var a 0 qui permet de s'assurer du debut de l'acquisiton 0
                x=1; // Variable qui assure le fait que l'on entre qu'un seul fois dans la fonction (acquisition a 0 ) 
               }
              i++; // on incremente 
             }
      
    }

    Répondre

    • Les Timers (II) 9 juillet 2020 12:30, par Christian

      Juste une question : quelle est l’application au modélisme ferroviaire de ce que vous cherchez à faire ?
      En effet, nous ne répondons qu’aux questions qui ont un intérêt pour le modélisme ferroviaire afin d’en faire profiter toute la communauté. Selon votre domaine d’application, nous serons peut-être amenés à vous rediriger vers d’autres sites ou forum plus spécialisés, mais si cela a un intérêt pour l’ensemble de nos lecteurs, alors nous ferons tout notre possible pour vous aider.
      Bien cordialement.

      Répondre

      • Les Timers (II) 9 juillet 2020 13:39, par Schweitzer

        c’est un programme pour apprendre a utiliser arduino. en Application ferroviaire ou autre. Dans le future j’aimerai etre capable d’analyser des singaux simples , carré , continues , sinusoidale etc etc....

        J’ai vu des programme faisant des teste avec le theoreme de fourrier discret mais ce n’est pas encore dans mon niveau.
        En se qui concerne le ferroviaire il serait par exemple utile pour déterminer ou se situe un problème de réseau électrique. par exemple un problème d’alimentation .

        Répondre

        • Les Timers (II) 10 juillet 2020 10:45, par Christian

          Apprendre à utiliser Arduino est tout à fait louable et nous espérons que LOCODUINO aide le lecteur dans ce sens.
          Lorsque je parle d’application au modélisme ferroviaire, je pense plutôt à ce qui peut se passer sur un réseau de trains miniatures et surveiller une alimentation électrique est plutôt un problème d’électronique.
          Pour trouver de l’aide, le mieux serait pour vous d’ouvrir un fil sur notre forum dès maintenant, et comme les gens sont déjà en vacances, revenir à la charge à la rentrée.
          Enfin, puisque votre but est d’analyser des signaux avec Arduino, vous pouvez essayer de voir les différents articles et projets qui ont été écrits pour utiliser Arduino en tant qu’oscilloscope. Commencez votre recherche directement sur le site www.arduino.cc et ensuite, faites une recherche avec le moteur de recherche de votre navigateur.
          Je pense que cette façon de faire sera beaucoup plus efficace car votre domaine d’application n’est pas vraiment notre spécialité.

          Répondre

    • Les Timers (II) 9 juillet 2020 18:59, par Jean-Luc

      Bonsoir. Si analogRead prend 116 microsecondes comment peut on l’appeler toutes les 100 microsecondes ?

      Répondre

      • Les Timers (II) 10 juillet 2020 08:53, par Schweitzer

        C’etait un programme test car le probleme est que sur mon traceur séries , le signal s’affichait tout aussi bien que lorsque je mettais du 0.2ms et plus.
        _Le but de mettre du 0.1ms est la confirmation qu’il y a une erreur dans mon programme car si avec du 0.1 j’obtiens le meme résultats qu’avec du 0.3ms ou plus c’est que mon Timer ne fonctionne pas comme il devrait. Le probleme maitenant est de savoir ou .

        Répondre

        • Les Timers (II) 10 juillet 2020 10:51, par Jean-Luc

          Bonjour,

          C’est assez simple à comprendre : si le temps d’exécution du code entre 2 tops du timer est supérieur à la période du timer alors la période sera déterminée par le temps d’exécution et pas par le timer dont une partie des interruptions partira dans les choux car le programme n’a pas le temps de les traiter. Autrement dit, vous demandez au CPU de travailler à plus de 100% ce qu’il ne peut évidemment pas faire. (Sans parler des Serial.print dont le temps d’exécution dépend de la vitesse de la ligne série dès que le tampon d’émission est plein. Et à 9600 bauds ca va venir vite).

          Vous pouvez verifier que votre timer fonctionne à la période que vous souhaitez en mettant seulement l’incrémentation d’une variable dans la routine d’interruption et en affichant cette variable toutes les secondes dans loop.

          Répondre

  • Les Timers (II) 12 octobre 2020 16:54, par YOU Anthony

    Bonjour,
    Je suis en train de faire des essais pour monter autour des 400khz avec les interruptions.
    Celles ci semblent bloquées à 80khz, impossible de monté plus haut, est-ce normal ?
    Cordialement.

    Répondre

    • Les Timers (II) 12 octobre 2020 19:25, par Christian

      Je pense que la lecture de l’article suivant "Les Timers (III)" vous permettra de trouver une solution pour atteindre les 400 kHz.
      Vous avez un exemple avec des valeurs différentes qu’il suffira d’adapter.

      Répondre

      • Les Timers (II) 12 octobre 2020 20:24, par YOU Anthony

        J’ai effectué un essai avec le timer1 de la page suivante.
        J’ai mis le prescaler sur 1 et OCR1A à 80. En théorie, je devrais avoir une fréquence de 100KHz (puisque c’est un toggle).
        Pourtant j’ai un signal de sortie a 35.5KHz.

        Répondre

        • Les Timers (II) 12 octobre 2020 21:58, par YOU Anthony

          Je viens de me rendre compte qu’il y a une limite du à l’utilisation de digitalWrite et digitalRead.
          si je fais une boucle avec juste digitalwrite low puis high et ça me fait un signal a 127khz.

          Répondre

          • Les Timers (II) 13 octobre 2020 09:43, par Christian

            Effectivement, les fonctions d’Arduino comme digitalRead ou digitalWrite prennent du temps pour être exécutées, et forcément cela va ralentir l’exécution de votre programme donc la création d’un signal à 400 kHz, voire moins comme dans cet essai.
            C’est le revers de la médaille, d’un côté on nous propose des fonctions simples à utiliser, mais d’un autre côté ces fonctions ne sont pas optimum dans certains cas.
            La solution, c’est de se rapprocher du microcontrôleur et donc de le programmer d’une autre façon, plus rapide. Pour inverser l’état de la LED, il faut directement intervenir sur le port de sortie (donc écrire sur ce port) de la même façon que vous savez écrire dans les registres du microcontrôleur.
            Si vous n’êtes pas familier, je vous conseille de regarder le chapitre 28 de mon cours d’électronique (article démarrer en électronique, dans la rubrique composants électroniques) qui s’appelle : La face cachée des fonctions pinMode, digitalWrite et digitalRead.
            Cela devrait résoudre votre problème puisque écrire directement dans le port ne prendra que quelques cycles d’horloge (à 16 MHz, un cycle dure 62,5 nanosecondes) et cela ne devrait pas perturber (ou très peu) un signal de 400 kHz).

            Répondre

  • Les Timers (II) 13 octobre 2020 11:15, par YOU Anthony

    Je pense que je vais me replonger dans mes vieux cours et le programmer directement. ça m’amusera plus et fera remonter de bons souvenirs :)

    Répondre

    • Les Timers (II) 13 octobre 2020 11:32, par Christian

      Ecrire directement dans le port peut améliorer l’obtention du signal.
      Mais dans certain cas, il est nécessaire de programmer directement le microcontrôleur en langage machine et donc utiliser l’assembleur. L’IDE permet de le faire mais quelle galère ! Je l’ai fait une fois avec le programme Blink et effectivement, mon code était plus concis qu’avec la compilation classique.
      Mais si on doit se lancer dans cette aventure, il vaut mieux se procurer les bons outils et donc un vrai programme d’assemblage.
      Après, il faut aussi pouvoir déboguer : en assembleur, c’est aussi une autre histoire !
      C’est pourquoi, sur ce site qui est fait surtout pour des amateurs (et souvent débutants), nous restons fidèles au bon vieux IDE qui utilise gcc.
      Allez voir l’article de Thierry https://www.locoduino.org/spip.php?...;: ce sera aussi un bon début pour vous y remettre.

      Répondre

      • Les Timers (II) 13 octobre 2020 11:47, par Thierry

        Une autre possibilité est d’utiliser une bibliothèque comme DIO2 (chercher dans l’IDE ou prendre là : https://github.com/Locoduino/DIO2) qui permet de réduire fortement la latence générée par digitalWrite et Read. Cette bibliothèque fournit de nouvelles fonctions digitalWrite2 et digitalRead2 bien plus proches du matériel et donc plus rapides.

        Répondre

  • Les Timers (II) 2 décembre 2021 19:35, par tribion

    Bonjour, je m’arrache les cheveux depuis plusieurs jours, je dois mal m’y prendre.
    J’ai une ILS sous une rame qui est sur l’interrupt 0 (pin2), cela fonctionne parfaitement.
    cependant j’aimerais que l’orsque cette interruption a lieu, sa lance le timer2 afin d’avoir une temporisation non bloquante car actuellement elle me fige le programme.
    Merci

    Répondre

    • Les Timers (II) 2 décembre 2021 20:34, par Christian

      Il suffit de mettre le code d’utilisation du timer2 dans l’ISR liée à l’interruption 0 (celle de la pin 2).
      Lorsque le timer2 débordera, il exécutera une autre ISR dans laquelle vous mettrez le traitement à exécuter.
      L’espace en fin d’articles est plutôt réservé aux questions sur l’article lui-même ; pour des problèmes techniques, utilisez plutôt notre forum où beaucoup plus de monde pourra vous aider.

      Répondre

Réagissez à « Les Timers (II) »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Programmation »

Les derniers articles

Les articles les plus lus