Répondre à la discussion
Affichage des résultats 1 à 5 sur 5

Faire marcher le Timer0 sur pic 18F2550



  1. #1
    YohT

    Faire marcher le Timer0 sur pic 18F2550


    ------

    Bonjour à tous,

    Je souhaite utiliser un pic 18f2550 afin, entre autres, de surveiller le courant débité par une batterie - en gros, vérifier qu'il n'y a pas de court-circuit. Je programme le pic en langage C avec le compilateur XC8.

    Puisqu'il me faut garantir qu'un courant trop important puisse être détecté en moins de 500 µs, je souhaite utiliser l'interruption du TIMER0 pour acquérir à intervalles réguliers une tension, image du courant débité par la batterie.

    Mon programme compile, seulement une fois implémenté dans le PIC, on remarque que celui-ci ne rentre pas dans l'interruption, on reste dans la boucle infinie. Ci-dessous, vous pouvez voir mon code. J'ai regardé plusieurs sites traitant de la question, si bien que mon code est un conglomérat de solutions qui se rapprochent plus ou moins de ce dont j'ai besoin. Je vous ai enlevé les parties qui fonctionnent (bah oui, sinon ce n'est pas drôle) afin de l'alléger. Par exemple je ne maîtrise pas les lignes commençant par "pragma", mais le tout semble mieux marcher avec elles que sans...

    Mon erreur doit provenir des configurations choisies. Pour explication de ce qui suit : j'ai autorisé les interruptions à divers degrés de priorité et ai placé le TIMER0 à un degré haut. Mais ça ne fonctionne pas. Si quelqu'un avait une explication, je lui en serais grandement reconnaissant. Merci beaucoup !


    // Import de bibliothèques
    #include <stdio.h>
    #include <stdlib.h>
    #include <p18f2550.h>

    // Déclaration des fonctions
    void timer0_isr(void);
    void initPic(void);
    void initTimer0(void);

    // Mes excuses si l'anglais est approximatif !
    #pragma config PLLDIV = 4 // 16MHz internal oscillator
    #pragma config CPUDIV = OSC2_PLL3 // clock for low-speed USB based on the internal clock
    #pragma config FOSC = INTOSC_HS
    #pragma config WDT = OFF // disables Watchgod Timer
    #pragma config LVP = OFF // single-supply ICSP disabled (the microcontroller cannot be programmed without requiring high voltage being applied to the /MCRL, Vpp or RE3 pin
    #pragma config BOR = OFF // disables brownout reset, the microprocessor won't reset if there were a short interruption of power
    #pragma config MCLRE = ON // /MCLR pin enabled, RE3 input pin disabled
    #pragma config PWRT = ON // Power-up Timer provides a fixed delay on power-up in order to ensure that the device clock is stable before code is executed
    #pragma config PBADEN = OFF // enables the reset of PORTB pins by controlling how the bits in ANSELB are reset. ANSELB<5:0> resets to 1, PORTB<5:0> pins are configured as analog inputs on Reset


    #define led LATBbits.LATB4 // la seule sortie de ce programme

    #pragma code it=0x08
    void saut_vers_interruption(void) {
    asm("goto timer0_isr;");
    }
    #pragma code

    #pragma interrupt timer0_isr
    void timer0_isr(void){ // mon interruption
    led = !led; // c'est avec cette led que je vérifie si l'interruption s'est lancée
    INTCONbits.TMR0IF = 0; // remise du flag à 0
    }


    void InitPic(){
    TRISA = 0b11111111; // RA0 bis RA7 sind Eingaben
    TRISB = 0b00001111; // RB0 bis RB3 sind Eingaben, RB4 bis RB7 sind Ausgaben
    TRISC = 0b00111001;

    led = 0;
    }

    void InitTimer0() {
    T0CON = 0b11000111;
    /*folowing code is a detail of the previous one
    T0CONbits.TMR0ON = 1; // Timer0 ON
    T0CONbits.T08BIT = 1; // Timer0 is in 8-bits mode
    T0CONbits.PSA = 0; // enables prescaler of Timer0
    T0CONbits.T0PS0 = 1; T0CONbits.T0PS1 = 1; T0CONbits.T0PS2 = 1; // Prescaler is 256 */

    RCONbits.IPEN = 1; // Enables priority levels on interrupts

    INTCON = 0b10100000; // Interrupt control register
    /*folowing code is a detail of the previous one
    INTCONbits.GIEH = 1; // Global Interrupt Enable with high priority level
    INTCONbits.GIEL = 0; // Disables all low-priority Peripheral Interrupt
    INTCONbits.TMR0IF = 0; // Initialisation of the Timer0 Flag
    INTCONbits.TMR0IE = 1; // Timer0 interrupt enable */

    INTCON2bits.TMR0IP = 1; // Timer0 is at high priority-level
    }

    void main(void) {

    InitPic();
    InitTimer0();

    while(1) {
    asm("nop;");
    }
    }

    -----

  2. Publicité
  3. #2
    invite03481543

    Re : Faire marcher le Timer0 sur pic 18F2550

    Bonjour,

    Je n'aurai pas utilisé cette méthode mais pour répondre à votre problème actuel:

    votre timer0 déborde toutes les 16.3ms tel qu'il est configuré:

    Fosc=16MHz => F(tick)=4MHz

    Prescaler réglé à 256 et débordement du timer 0 à la 256eme impulsion => 4MHz/256/256=61Hz => 16.3ms (overflow)

    Essayez de modifier cela au niveau de la déclaration de votre routine d'interruption:
    Code:
    void interrupt isr(void)
    {
    led = !led;
    INTCONbits.TMR0IF=0;
    }
    Je n'utilise pas XC8, il vous faudra vérifier si c'est bien comme cela que ce déclare la routine d'interruption pour ce compilateur.
    @+
    Dernière modification par HULK28 ; 28/06/2014 à 07h31.

  4. #3
    invite03481543

    Re : Faire marcher le Timer0 sur pic 18F2550

    ou avec:

    Code:
    void interrupt it_gene(void)
    {
    if(INTCONbits.TMR0IF)
      {
      INTCONbits.TMR0IF = 0;
      led = !led;
      }
    }
    @+

  5. #4
    YohT

    Re : Faire marcher le Timer0 sur pic 18F2550

    Bonjour,

    effectivement, cela marche beaucoup mieux ainsi, et au moins maintenant je maîtrise la fréquence de contrôle du courant. Merci beaucoup, je vais pouvoir peaufiner tout ça tranquillement !

  6. A voir en vidéo sur Futura
  7. Comparatifs

    Gagnez du temps et de l'argent grâce à nos comparatifs de produits. Parmi nos sujets :
  8. #5
    YohT

    Re : Faire marcher le Timer0 sur pic 18F2550

    Pour les futurs visiteurs de ce topic, je me propose de poster ici la version finale de ce bout de code, qui comme on le constatera est sensiblement édulcoré à certains endroits (et c'est ainsi que ça marche le mieux). Le code suivant permet de faire clignoter une LED par interruption du Timer0 (à une fréquence cependant un peu trop élevée pour l’oeil) :



    Code:
    #include <stdio.h>          // Ein- und Ausgabeverwaltung
    #include <stdlib.h>         // Vermischte Standardfunktionen, u.a. Speicherverwaltung
    #include <p18f2550.h>   // Zur Programmierung des PICs 18F2550
    
    #pragma config PLLDIV = 12                 // 20MHz external oscillator
    #pragma config CPUDIV = OSC1_PLL2   // clock for high-speed USB based on the internal clock
    #pragma config FOSC   = INTOSC_HS   // HSPLL_HS   // For external source
    #pragma config USBDIV = 2               // from 96MHz, /2 = 48MHz for the USB
    #pragma config VREGEN = ON          // 3.3V supply  for the USB
    #pragma config WDT    = OFF         // disables Watchgod Timer
    #pragma config LVP    = ON           // single-supply ICSP disabled (the microcontroller cannot be programmed without requiring high voltage being applied to the /MCRL, Vpp or RE3 pin
    #pragma config BOR    = OFF        // disables brownout reset, the microprocessor won't reset if there were a short interruption of power
    #pragma config MCLRE  = OFF      // /MCLR pin enabled, RE3 input pin disabled
    #pragma config PWRT   = ON       // Power-up Timer provides a fixed delay on power-up in order to ensure that the device clock is stable before code is executed
    #pragma config PBADEN = OFF    // enables the reset of PORTB pins by controlling how the bits in ANSELB are reset. ANSELB<5:0> resets to 1, PORTB<5:0> pins are configured as analog inputs on Reset
    
    
    
    void InitInterrupt(){
        TMR0IE = 1; // Enable TMR0 Interrupt
        GIE = 1;      // Global Interrupt Enable
    }
    
    
    
    void InitTimer(){
        T0CON = 0b11000010;
        TMR0 = 10;             // preset for timer register
    }
    
    
    
    void interrupt ISR(){
        if(TMR0IF == 1){
            TMR0 = 10;
            TMR0IF = 0;
            led = !led;
        }
    }
    
    
    
    void main(void) {
        InitTimer();
        InitInterrupt();
        while(1);
    }

Discussions similaires

  1. Comment faire marcher ce code ??
    Par euphoury67 dans le forum Électronique
    Réponses: 4
    Dernier message: 26/06/2010, 14h32
  2. probleme infiltration d'eau : faire marcher l'assurance ?
    Par bbou dans le forum Habitat bioclimatique, isolation et chauffage
    Réponses: 1
    Dernier message: 27/01/2009, 16h56
  3. faire marcher et xp, et vista, via dde
    Par jyaim dans le forum Logiciel - Software - Open Source
    Réponses: 13
    Dernier message: 12/11/2007, 18h44
  4. comment faire marcher le moduleur
    Par electab dans le forum Électronique
    Réponses: 0
    Dernier message: 09/06/2004, 10h27
Découvrez nos comparatifs produits sur l'informatique et les technologies.