IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Interruption timer 1 sur nano v3


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2012
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 114
    Par défaut Interruption timer 1 sur nano v3
    Bien le bonjour,

    je galère sérieux avec le timer 1 d'une carte nano.
    Voici mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <TimerOne.h>
    //#include <avr/interrupt.h> 
    unsigned int cpt = 0;
    unsigned int cptIt = 0;
    void setup() 
    {
      pinMode(6, OUTPUT);
     
      Timer1.attachInterrupt(timerIsr);
      TCCR1A = 0;
      TCCR1B = 0;
      TCCR1B |= (1<<WGM12);// ctc 4, clear tcnt at top
      TCCR1B |= (1<<CS12); //   /256
      OCR1A = 200;
      TIMSK1 =0;
      TIMSK1 |= (1<<OCIE0A); //output compare A Match Interrupt Enable
      TIFR1 |= OCF0A;//output compare A Match Flag
    }
    //***************** 
    void loop()
    {
     
    }
     
    //*****************
    void timerIsr()
    {
      digitalWrite( 6, 1);
      digitalWrite( 6, 0);
    }
    je suis censé rentré dans timerIsr() de façon périodique (stable).
    Je surveille à l'analyseur logique sur mon port USB de PC.
    quand je mets OCR1A = 200; la période de rentrée dans l'isr est 57.35 ms !! Je m'attendais plutôt à 256*200*1/16 000 000 soit 3.2ms
    quand je mets autre chose que 200, c à d 100, 190, 400, ... peu importe, ça devient carrément non périodique !!
    Pour 400 par exemple, les timing entre interruption sont des multiples de 6.354ms (soit environ la période attendue)
    Pour 100, ils sont des multiples de 1.5885 (soit environ la période attendue)

    Quelqu'un gère-t-il le timer 1 sans aucun soucis? Peut m'aider?

    Mon objectif sera, à partir d'un événement gpio (probablement géré aussi en interruption) de programmer le timer pour qu'il positionne une autre broche à 1, puis l'arréter, et ainsi de suite. Je ne veux pas entendre parler de delay() ou autres fonctions bloquantes.

    bonne journée

  2. #2
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 282
    Par défaut
    Bonsoir Nico

    Ton impulsion est très courte, juste 1/16ème de µs si le compilateur fait bien son travail. Es-tu certain de ne pas louper des impulsions? Quelle est la résolution temporel de ton analyseur logique?

    Pour fiabiliser ce test, tu devrais inverser l'état de la sortie à chaque interruption. Cela peut être fait simplement avec l'instruction PIND = (1<<6); (fonction hardware de l'ATMega328, mais non reprise dans la doc Arduino).

    Après je ne dis pas que ton code est faux ou pas, je ne l'ai pas analysé.

    Delias

  3. #3
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Salut,
    Les Timers de chez Atmel peuvent faire tellement de choses que c'est délicat de les régler.

    Je revérifie juste ce que tu configures

    Tu mets TCCRA à 0 (vu la condition de démarrage tu peux te passer de cette ligne)
    Nom : Capture10.PNG
Affichages : 1218
Taille : 20,2 Ko

    Tu mets TCCRB à 0 (vu la condition de démarrage tu peux te passer de cette ligne) puis tu mets les bits WGM12 et CS12 à 1 ce qui donne bien la config Clear Timer on Compare (pour toujours comparer avec la valeur de OCR1A) et tu divises l'horloge de 16MHz du Nano par 256.
    Nom : Capture11.PNG
Affichages : 1212
Taille : 21,2 Ko

    Nom : Capture12.PNG
Affichages : 1184
Taille : 23,7 Ko

    Nom : Capture13.PNG
Affichages : 1183
Taille : 28,3 Ko

    Ensuite tu choisies de déclencher une interruption des que le Timer1 arrive à la valeur dans OCR1A et tu effaces le flag pour démarrer sereinement.
    Nom : Capture14.PNG
Affichages : 1291
Taille : 119,0 Ko


    C'est là où c'est curieux car effectivement ça devrait fonctionner, le timer devrait s'incrémenter toutes les 16µs * 200 = interruption toutes les 3.2ms
    Je sais que Arduino kidnappe le Timer0 pour la fonction delay mais normalement ça ne devrait pas influencer à ce point les interruptions du Timer1, je vais regarder ça ce soir en programmant un UNO. Le quartz est de 20MHz mais ce n'est pas grave on se projettera sur le Nano.

    A toute à l'heure (normalement)

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Re,
    Pour le moment j'arrive a me servir du Timer1, de mon Arduino Uno, par débordement. Je mets une valeur dans le registre TNCT1 et dès qu'il déborde j'allume une LED sur mon Arduino puis je recharge TNCT1 ainsi de suite. Je n'ai pas beaucoup pratiqué sur Atmel.

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    /* crystal = 20MHz
     * prescaler = 256
     * timer increment = 12.8us
     */
     
     
    ISR (TIMER1_OVF_vect)
    {
    	PORTB ^= 0x20;
    	TCNT1 = (65535-100);   // for 1.28ms @ 20MHz
    }
     
     
    int main()
    {
    	DDRB |= 0x20;
     
    	TCNT1 = (65535-100);   // for 1.28ms @ 20MHz
     
    	TCCR1A = 0x00;
    	TCCR1B = (1<<CS12);  // Timer mode with 256 prescler
    	TIMSK1 = (1 << TOIE1) ;   // Enable timer1 overflow interrupt(TOIE1)
    	sei();        
     
    	while(1)
    	{
     
    	}
    }

    On note une petite différence entre mes calculs 1.28ms et la réalité 1.58ms (300us seconde d'écart il faudrait regarder combien de temps dure l'allumage d'une LED + chargement de TNCT1 + sortir et entrer dans l'interruption)

    Nom : Capture du 2018-06-06 11-11-52.png
Affichages : 1191
Taille : 15,6 Ko

    Quoi qu'il en soit, il faut adapter cet exemple qui fonctionne avec ce que tu souhaites faire.
    J’essaierai demain si je trouve un peu de temps.

    A+

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2012
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 114
    Par défaut
    j'ai tout refait le code, ça me gonflait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    unsigned int itTimer1 = 0;
    unsigned int itCible1 = 0;
     
    #define pi(v) Serial.print("Ligne_") ; Serial.print(__LINE__) ; Serial.print(" "); Serial.print(#v) ;Serial.print(" = ") ; Serial.println((v)) ;
     
    void setup()
    {
      Serial.begin(57600);
      Serial.println(__FILE__); Serial.println(__DATE__); Serial.println(__TIME__);
      DDRB |= B00100000;  // set pin13 to output without affecting other pins
      cli();
      attachInterrupt(0, isrCible1, FALLING);
      TCCR1A = 0;
      TCCR1B = 0;
      OCR1A = 100;  //
      TCCR1B |= (1 << WGM12);// CTC mode on
      TCCR1B |= (1 << CS10);
      TCCR1B |= (1 << CS11);
      TIFR1 = 0;
      TIMSK1 |= (1 << OCIE1A);// timer compare intrupt
      sei();
    }
     
    void loop()
    {
      if (itCible1){
        TCNT1 = 0;
        //TCCR1B |= (1 << CS11);
        //TCCR1B |= (1 << CS10);
        itCible1 = 0;
      }
     
    }
    void isrCible1(void){
      itCible1 = 1;
    }
     
    ISR(TIMER1_COMPA_vect)
    {
      digitalWrite(6,1);
      digitalWrite(6,0);
    }
    voilà qui fonctionne bien, pour OCCR1A de 100 (0.4ms) à 7000 (28....ms)
    avec resynchro sur it gpio2

    je ne vais pas chercher plus longtemps ce qui ne marchait pas sur l'autre code.
    Merci pour vos contributions.

    bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Interruption Timer 2 pour PIC18
    Par MITCH23 dans le forum C
    Réponses: 0
    Dernier message: 01/10/2014, 09h33
  2. gestion d'un timer basé sur l'heure serveur
    Par pppplus dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 17/07/2011, 15h16
  3. Timer prioritaire sur tout le reste
    Par lbar012001 dans le forum VBA Access
    Réponses: 3
    Dernier message: 28/06/2011, 11h21
  4. Interruption Timer sous Borland C
    Par Spacy_green dans le forum C
    Réponses: 3
    Dernier message: 20/06/2006, 23h40
  5. interruption du programme sur erreur
    Par cdelamarre dans le forum C++Builder
    Réponses: 5
    Dernier message: 30/11/2005, 15h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo