[Programmation] Timer1 dans Programmation C
Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

Timer1 dans Programmation C



  1. #1
    invitec9a558b8

    Timer1 dans Programmation C


    ------

    Bonjour,

    Je m’appelle Guylllaume et je suis actuellement dans les systèmes numériques.

    j'ai donc un projet de fin d'étude qui consiste à lire une broche analogique,

    pour ainsi faire commuter ou non un relai,

    J'utilise pour ceci un potentiomètre pour simuler un capteur de pression et un relais ( j'ai aussi une led que j'active en même temps que le relais pour un contrôle visuel, celle ci s'active à l'état bas ).

    j'ai pour le traitement un PIC 18F26K40 : http://ww1.microchip.com/downloads/e...S40001816F.pdf (doc technique)

    suite à ceci j'ai déjà réalisé quelques tests:

    la led peut clignoter (ici PIN_A0) , le relai commute aussi (PIN_C0), et la broche analogique (PIN_A1).

    Le but étant de faire commuter le relai quand le Capteur (PIN_A1) dépasse un seuil (4.5V)

    le relais doit rester commuté pendant 2 mins

    Le processus de commutation ne doit pas occupé le microcontrôleur, donc l'utilisation de timer me semble obligatoire.

    voici le code testé dernièrement mais qui ne fonctionne pas :



    Code:
    #include <18F26K40.h>
    #device ADC=10
     
    #FUSES NOWDT                    //No Watch Dog Timer
     
    #use delay(internal=4MHz)
    #use FIXED_IO(C_outputs=PIN_C0)
    #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
     
     
    #define DELAY 2000
    #define MPX5004 PIN_A1
    #define Relai PIN_C0
    #define LED PIN_A0
     
    int compteur;
    int16 lecturempx;
     
    void  timer1_isr(void)
    {
     
      compteur=compteur++;                  
       
      if (  > 3436 )
      {
       output_low(Relai);   //relai non commuté
       output_high(LED);    //LED éteinte
     
       disable_interrupts(INT_TIMER1);
       disable_interrupts(GLOBAL);    
       compteur=0;  
      }
    }
     
    void main(void)
    {
       setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);   // 1us overflow
       enable_interrupts(GLOBAL);         
       setup_adc_ports(sAN3);
       setup_adc(ADC_CLOCK_INTERNAL);
       output_low(Relai);
       output_high(LED);
     
       while(TRUE)
       {
                 
           setup_adc_ports(sAN1);
           lecturempx = read_adc();  
     
           if (lecturempx > 920 )  
           {
     
            output_high(Relai);
            output_low(LED);
            enable_Interrupts(INT_TIMER1); 
             
           }
     
          delay_ms(DELAY);  
       }
    }

    J'ai aussi besoin de la conversion ADC pour pouvoir faire une comparaison.

    je ne pense pas que le problème vienne de la convertion mais plutôt du timer.

    J'en viens à vous demander votre aide puisque voilà maintenant 2 semaines que je suis bloqué.

    -----
    Dernière modification par Antoane ; 23/04/2018 à 13h56. Motif: Ajout balises code et remplacement de la pj externe par un lien vers la datasheet

  2. #2
    Seb.26

    Re : Timer1 dans Programmation C

    c'est censé faire quoi "if ( > 3436 )" ??

    PS: ton timer sert à rien, vire ton delay et plus besoin ... c'est codé à la Arduino-Tuto

    Dernière modification par Seb.26 ; 23/04/2018 à 15h25.
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  3. #3
    invited14ca340

    Re : Timer1 dans Programmation C

    Bonjour,
    Une interruption du timer à 1µs, il y a un intérêt précis? il serait plus judicieux de la faire à 1ms.

    Dans l'ISR, il faut faire le moins de chose possible, donc incrémenter une variable et donner une condition c'est la meilleure solution :
    Code:
    // Defines
    #define MY_DELAY 2000 // 2000 ms delay
    #define USE_MS_DELAY
    
    // Global variables
    volatile unsigned int timer_us; // timer microsecond accumulator, automatically cleared when reach.
    volatile unsigned int timer_ms; // timer millisecond accumulator, automatic clear.
    volatile unsigned int timer_s; // timer second accumulator
    bool elapsedTimeout = FALSE; // is true when 2000 ms are elapsed, manual clear.
    
    void  timer1_isr(void) // interrupt every 1 us
    {
      clear_Timer1_interrupt();                  
      timer_us+=1;
      if(timer_us>=1000)
      {
        timer_ms+=1; // 1ms elapsed
        timer_us=0; // reset timer_us accumalator
      }
    #ifdef USE_MS_DELAY
      if(timer_ms>=MY_DELAY)
      {
        elapsedTimeout = TRUE; // 2000 ms delay is reached
        timer_ms=0; // reset timer_ms accumalator
      }
    #else
      if(timer_ms>=1000)
      {
        timer_s+=1; // 1s elapsed
        timer_ms=0; // reset timer_ms accumalator
      }
    #endif
    }
    
    void main(void)
    {
       // Initialization
       setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);   // 1us overflow
       enable_interrupts(GLOBAL);         
       setup_adc_ports(sAN3);
       setup_adc(ADC_CLOCK_INTERNAL);
       output_low(Relai);
       output_high(LED);
     // Enter infinite loop
       while(1)
       {
        if(elapsedTimeout == TRUE) // 2000 ms delay elapsed
        {
          elapsedTimeout = FALSE; // clear timeout condition
          /* TO DO */ // Add functions to do periodically (2000 ms period)
        }
      }

  4. #4
    sandrecarpe

    Re : Timer1 dans Programmation C

    Salut,
    Pourquoi un timer ?
    Ton micro possède des comparateurs. Règle ton seuil par une réf externe si tu n'arrives pas à avoir de 4.5V autrement que par le micro, et génère une interruption.

    Ou alors, règle ton adc pour qu'il te génère une interruption à la fin de chaque conversion et suivant la valeur lue, agit en conséquence.

    De ces façons là ton micro n'est quasi pas sollicité

  5. A voir en vidéo sur Futura
  6. #5
    invite5a48ffd1

    Re : Timer1 dans Programmation C

    Citation Envoyé par naru2to Voir le message
    Bonjour,
    Une interruption du timer à 1µs, il y a un intérêt précis? il serait plus judicieux de la faire à 1ms.
    Bonsoir,

    voir à 100ms, vu qu'il n'est pas précisé le temps de réaction.

    Gérer par interruption, timer ou événements, est une bonne solution à condition d'avoir des bonnes raisons de le faire.
    Vu comment est codé votre programme je vous conseillerai de passer par une étape de flowchart, ça aide à poser les choses de manière organisée.
    Ensuite le code sera plus simple à écrire.
    En général on commence par une séquence d'initialisation du PIC (ports, registre timer, ADC, etc) puis le main() doit contenir la boucle principale d'activité qui dans votre cas ne va pas puisqu'on y retrouve des initilaisations du timer, de l'adc, qui n'ont strictement rien à faire là... tout cela doit se trouver dans une fonction que vous pouvez appeler Init_PIC(), ce sera bien plus lisible lorsque votre programme va s'étoffer.

  7. #6
    invited14ca340

    Re : Timer1 dans Programmation C

    Vu comment est codé votre programme je vous conseillerai de passer par une étape de flowchart, ça aide à poser les choses de manière organisée.
    Ensuite le code sera plus simple à écrire.
    En général on commence par une séquence d'initialisation du PIC (ports, registre timer, ADC, etc) puis le main()...
    La gestion des différentes étapes peut se faire dans une machine à états, autrement dit par switch case en langage C. Cela facilite la lecture même pour des programmes complexes, On peut assez facilement ajouter ou enlever des étapes, et cela permet également de mieux gérer les erreurs.
    Code:
    enum stateMachine {
        MCU_INITIALIZATION_STATE= 0,
        MCU_INITIALIZATION_ERROR_STATE,
        HARDWARE_INITIALIZATION_STATE,
        HARDWARE_ERROR_STATE,
        SYSTEM_INITIALIZATION_STATE,
        SYSTEM_INITIALIZATION_ERROR_STATE,
        SYSTEM_RUNNING_STATE,
        SYSTEM_ERROR_STATE,
    };
    
    extern enum stateMachine currentState;
    
    void runProcess(void);
    Code:
    enum stateMachine currentState=MCU_INITIALIZATION_STATE;
    int status = 0;
    
    void runProcess(void)
    {
      switch(currentState)
      {
        case MCU_INITIALIZATION_STATE:
        status |= mcuInitialization(); // MCU initialization : Oscillator/PLL, GPIO, Timers, ADC/DAC, SPI/I²C/UART and all other MCU peripherals.
        if(status == 0)
          currentState=HARDWARE_INITIALIZATION_STATE;
        else
          currentState=MCU_INITIALIZATION_ERROR_STATE;
        break;
    
        case MCU_INITIALIZATION_ERROR_STATE:
        /* MCU failure : Wrong fuses configuration, wrong oscillator/PLL configuration, crystal not running, etc.
         * Check returned error number */
        break;
    
        case HARDWARE_INITIALIZATION_STATE:
        status |= hardwareInitialization(); // External components initialization : EEPROM, LCD, external ADC/DAC, etc.
        if(status == 0)
          currentState=SYSTEM_INITIALIZATION_STATE;
        else
          currentState=HARDWARE_ERROR_STATE;
        break;
    
        case HARDWARE_ERROR_STATE:
        /* Hardware failure : One or more devices couldn't be initialized
         * Check returned error number */
        break;
    
        case SYSTEM_INITIALIZATION_STATE:
        status |= systemInitialization(); // System initialization : read system parameters from EEPROM, diplay a message on LCD, etc.
        if(status == 0)
          currentState=SYSTEM_RUNNING_STATE;
        else
          currentState=SYSTEM_INITIALIZATION_ERROR_STATE;
        break;
    
        case SYSTEM_INITIALIZATION_ERROR_STATE:
        /* System Failure
         * Check returned error number */
        break;
    
        case SYSTEM_RUNNING_STATE:
        /* Add periodical functions to do there.
         * Check status to ensure system is running properly (status = 0)
         * If status < 0 goto SYSTEM_ERROR_STATE */
        break;
    
        case SYSTEM_ERROR_STATE:
        /* System Failure
         * Check returned error number
         * If error can be corrected, correct it and goto SYSTEM_RUNNING_STATE (diplay a warning message)
         * If not, restart system or add another decision (display an error message) */
        break;
      }
    }
    Code:
    // Fonction main
    int main(void)
    {
      while (1) 
        {
          runProcess();
        }
    }

  8. #7
    invite5a48ffd1

    Re : Timer1 dans Programmation C

    C'est en effet comme cela qu'il faut faire

  9. #8
    Jack
    Modérateur

    Re : Timer1 dans Programmation C

    Quelques messages ont été masqués en attendant que Guylllaume se mette en accord avec la charte en revenant à l'usage de son pseudo d'origine.

Discussions similaires

  1. timer1
    Par invite6737e865 dans le forum Électronique
    Réponses: 0
    Dernier message: 31/05/2012, 14h49
  2. Timer1 programmation en c18
    Par inviteb2b48352 dans le forum Électronique
    Réponses: 3
    Dernier message: 30/04/2010, 11h31
  3. Problème TIMER1 PIC
    Par invite3d4f2ff3 dans le forum Électronique
    Réponses: 5
    Dernier message: 27/04/2010, 18h00
  4. Timer1
    Par invite91183f95 dans le forum Électronique
    Réponses: 2
    Dernier message: 26/04/2007, 16h10
  5. PB de timer1 sur pic
    Par invitebf62768c dans le forum Électronique
    Réponses: 3
    Dernier message: 01/03/2004, 14h11
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...