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

MPLAB Discussion :

Timer TMR1 pour clignotement LED


Sujet :

MPLAB

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 11
    Points : 5
    Points
    5
    Par défaut Timer TMR1 pour clignotement LED
    Bonjour à tous !

    Je viens de débuter la programmation sur microcontroleur, j'utilise un PIC32MZ2064DAG169.
    Le premier objectif que je me suis fixé et le clignotement de la LED1. J'ai déjà réussi à faire clignoter les 3 leds l'une après l'autre cependant j'ai un peu "triché" en utilisant des boucles for qui ne permettent évidemment pas une bonne gestion de la fréquence de clignotement.

    Je sais qu'il faut se baser sur l'utilisation d'un timer. J'ai donc créé un Timer TMR1 à l'aide de MHC (Harmony v3) visible sur la capture suivante:

    Nom : TMR1.png
Affichages : 940
Taille : 149,1 Ko

    Voici mon code actuel:

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    /*******************************************************************************
      Main Source File
     
      Company:
        Microchip Technology Inc.
     
      File Name:
        main.c
     
      Summary:
        This file contains the "main" function for a project.
     
      Description:
        This file contains the "main" function for a project.  The
        "main" function calls the "SYS_Initialize" function to initialize the state
        machines of all modules in the system
     *******************************************************************************/
     
    // *****************************************************************************
    // *****************************************************************************
    // Section: Included Files
    // *****************************************************************************
    // *****************************************************************************
     
    #include <stddef.h>                     // Defines NULL
    #include <stdbool.h>                    // Defines true
    #include <stdlib.h>                     // Defines EXIT_FAILURE
    #include "definitions.h"                // SYS function prototypes
     
     
    // *****************************************************************************
    // *****************************************************************************
    // Section: Main Entry Point
    // *****************************************************************************
    // *****************************************************************************
     
    int main ( void )
    {
        /* Initialize all modules */
        SYS_Initialize ( NULL );
        TMR1_Start();
     
        while ( true )
        {
     
            if (TMR1_CounterGet()==PR1)
            {
                LED1_Toggle();
     
            }
     
        }
     
        /* Execution should not come here during normal operation */
     
        return ( EXIT_FAILURE );
    }
     
     
    /*******************************************************************************
     End of File
    */

    L'idée ici c'est que je souhaite du coup vérifier où en est le compteur du TIMER et quand celui-ci atteint la valeur d'une période on change alors l'état de la led. En faite je veux que chaque passage d'une période à une autre du Timer déclenche le changement d'état de la led.
    Le code se compile sans problème, mais aucun clignotement n'a lieu, j'ai essayé pas mal d'autre choses et fais pas mal de recherches sur les timer, notamment sur le site de Microchip, mais sans succès, j'espère que vous saurez m'aider et vous remercie d'avance !

  2. #2
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 166
    Points
    53 166
    Par défaut
    Voici comment faire avec un PIC24F (MCC):
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        while (1) {
            if (TMR1_Counter16BitGet() == TMR1_Period16BitGet()) {
                TMR1_Counter16BitSet(0);
                LED1_Toggle();
            }
        }
    Si ça ne fonctionne pas, montre nous le contenu du fichier tmr1.c

    Au passage, tu peux désactiver l'interruption du timer puisque tu fais du polling.
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bonjour et merci pour la réponse !

    Alors j'ai essayé ce que tu (je peux te tutoyer ?) m'as proposé, il n'y a pas de fonction CounterSet initialement dans mon plib_tmr1.h j'en ai donc créé une:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void TMR1_CounterSet(uint16_t counter)
    {
        TMR1=counter;
    }

    Le code se compile mais la led ne clignote pas, j'ai donc essayé d'autres méthodes similaire, mais aucune ne marche:

    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
    int main ( void )
    {
        /* Initialize all modules */
        SYS_Initialize ( NULL );
        TMR1_Start();
     
        while ( true )
        {
     
            if (TMR1_CounterGet()==TMR1_PeriodGet())
            {
                TMR1_CounterSet(0); //TMR1=0x0; //TMR1=0; // TMR1_Initialize();
                LED1_Toggle();
            }
     
     
        }

    Du coup voici le contenu de mon plib_tmr1.c:


    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    #include "device.h"
    #include "plib_tmr1.h"
     
    static TMR1_TIMER_OBJECT tmr1Obj;
     
    void TMR1_Initialize(void)
    {
        /* Disable Timer */
        T1CONCLR = _T1CON_ON_MASK;
     
        /*
        SIDL = 0
        TWDIS = 0
        TECS = 1
        TGATE = 0
        TCKPS = 1
        TSYNC = 0
        TCS = 1
        */
        T1CONSET = 0x112;
     
        /* Clear counter */
        TMR1 = 0x0;
     
        /*Set period */
        PR1 = 2047;
     
        /* Setup TMR1 Interrupt */
        TMR1_InterruptDisable();  /* disable interrupt on the way out */
     
    }
     
     
     
    void TMR1_Start (void)
    {
        T1CONSET = _T1CON_ON_MASK;
    }
     
     
    void TMR1_Stop (void)
    {
        T1CONCLR = _T1CON_ON_MASK;
    }
     
     
    void TMR1_PeriodSet(uint16_t period)
    {
        PR1 = period;
    }
     
    void TMR1_CounterSet(uint16_t counter)
    {
        TMR1=counter;
    }
     
    uint16_t TMR1_PeriodGet(void)
    {
        return (uint16_t)PR1;
    }
     
     
    uint16_t TMR1_CounterGet(void)
    {
        return(TMR1);
    }
     
    uint32_t TMR1_FrequencyGet(void)
    {
        return (4096);
    }
     
    void TIMER_1_InterruptHandler (void)
    {
        uint32_t status = IFS0bits.T1IF;
        IFS0CLR = _IFS0_T1IF_MASK;
     
        if((tmr1Obj.callback_fn != NULL))
        {
            tmr1Obj.callback_fn(status, tmr1Obj.context);
        }
    }
     
     
    void TMR1_InterruptEnable(void)
    {
        IEC0SET = _IEC0_T1IE_MASK;
    }
     
     
    void TMR1_InterruptDisable(void)
    {
        IEC0CLR = _IEC0_T1IE_MASK;
    }
     
     
    void TMR1_CallbackRegister( TMR1_CALLBACK callback_fn, uintptr_t context )
    {
        /* - Save callback_fn and context in local memory */
        tmr1Obj.callback_fn = callback_fn;
        tmr1Obj.context = context;
    }


    Si je trouve une solution entretemps je vous tiens au courant

    Sinon j'ai entendu parlé de la gestion des événements du timer à l'aide de "flags" ça pourrait certainement aussi fonctionné non ?
    En tout cas merci de me répondre

    EDIT: Je crois qu'en fait la condition du If n'est jamais réalisée.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Je me demande si le problème n'est pas le fait que TMR1 est initialisé en TMR1=0x0. Dans ce cas de figure comment se déroule son évolution ?
    J'imagine que ce n'est pas TMR1=1,=2,=3,...,=Période. La période quant à elle est un entier, peut-être est-ce pour cela que la condition sur le if n'est jamais remplie ?

  5. #5
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 166
    Points
    53 166
    Par défaut
    Un timer est en fait un compteur d'entiers sur 16 bits. Le pas du timer est donc l'intervalle de temps est divisé par le nombre max d'entiers.

    Tu initialises le compteur TMR1 à 0 (ou n'importe quelle autre valeur), tu le démarres et après le compteur s'incrémente automatiquement de 1 en 1 selon la fréquence définie.

    Ensuite, deux possibilités :

    1. En polling, tu tests quand tu as TMR1==PR1 => temps prévu écoulé => action
    2. Par interruption, quand TMR1==PR1 => l'interruption se déclenche => action


    Donc ne pas oublier de remettre le compteur à 0 => TMR1=0

    Essaie de mettre le toggle de la LED dans l'interruption :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void TIMER_1_InterruptHandler (void)
    {
        uint32_t status = IFS0bits.T1IF;
        IFS0CLR = _IFS0_T1IF_MASK;
     
        LED1_Toggle();
     
        if((tmr1Obj.callback_fn != NULL))
        {
            tmr1Obj.callback_fn(status, tmr1Obj.context);
        }
    }
    Il faut aussi activer l'interruption dans le code principal :
    Sinon, juste pour être sûr, tu as bien vérifié que la LED est sur la bonne broche ?

    Et pourquoi utilises-tu une horloge externe comme source pour le timer ? As-tu essayé avec une des horloges interne du microcontrôleur ?
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    J'ai déjà réussi à faire clignoter les 3 leds à l'aide de fonctions "delay_ms" donc normalement pas de problème de broche.
    Mais je ne comprends pas pourquoi je ne rentrais pas dans le if, comme je l'avais écrit cela signifie que TMR1 n'atteint jamais PR1 ?

    J'essaie demain avec le toggle de l'interruption et je te tiens au courant, merci encore

Discussions similaires

  1. [PowerShell] Timer Powershell pour MAJ
    Par SPRITZGEBACK dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 23/10/2015, 10h42
  2. Interruption Timer 2 pour PIC18
    Par MITCH23 dans le forum C
    Réponses: 0
    Dernier message: 01/10/2014, 09h33
  3. clignotement Leds, Timer
    Par faycal91 dans le forum Autres architectures
    Réponses: 0
    Dernier message: 10/01/2011, 20h12
  4. [C++ Builder 6] Timer de précision pour chronomètre
    Par doudoustephane dans le forum C++Builder
    Réponses: 9
    Dernier message: 27/09/2005, 10h45
  5. [C#] Quel controle pour le dessin + eviter clignotement
    Par JEG dans le forum Windows Forms
    Réponses: 10
    Dernier message: 08/10/2004, 11h28

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