Problème Timer0 PIC18f458 pour compte à rebours
Répondre à la discussion
Affichage des résultats 1 à 11 sur 11

Problème Timer0 PIC18f458 pour compte à rebours



  1. #1
    invite7aefe76b

    Problème Timer0 PIC18f458 pour compte à rebours


    ------

    Bonjour à tous

    Je viens de m’inscrire sur votre forum, pour demander votre aide, car je tourne en rond depuis presque 2 jours sur un problème de programmation de TIMER0 du pic 18f458.

    Explication du projet :

    Je souhaite faire un compte à rebours a durée programmable via clavier avec buzzer lorsque le temps programmer est écoulé, pour mes séances d’étirements après une bonne dose de nage.

    Pour la partie affichage, ce sont 3 afficheurs 7 segments (temps max 9min et 59 sec), un convertisseur BCD 7 segments MC14543B, et des transistors pour acheminer le courant nécessaire au led (Iled =20ma, Ibcd = 10ma) qui sont utilisés

    Le tous est multiplexé sur le PORTB du pic 18f458. Pin 7, 5, 4 du port B utilisé pour la sélection d’un afficheur, Pin 3, 2, 1, 0 pour commander l’entrée du BCD.

    Après documentation sur le net, pour une bonne précision temporelle, l’utilisation des TIMER est la bonne solution à la stabilité temporelle .
    Je me suis donc plongé dans la data sheet du pic 18F458 pour essaie de comprendre et de codé le fonctionnement du timer 0


    J’ai choisie le mode 16bit du timer 0, et une fréquence d’interruption de 10ms, pour un bon multiplexage des afficheurs.
    Ce qui me donne après le petit calcul de la fréquence de mon quartz qui est de 10Mhz, que le registre T0CON dois être configuré en : 00000010 (timer off, 16bit, clk interne, comptage sur front descendant, prescaler ON configuré en 1 :8).
    Pour arriver à 10ms un offset de 62411 est requis, ce qui me donne les valeurs suivantes dans les registres :
    - TMROH = F3
    - TMROL = CB

    Suivant mon interprétation de la data sheet et du calcul, le Timer compte 3125 cycle pour arrivé à la valeur max de 2 registre TMROH et TMROL, puis passe le bit TMR0IF à 1, si le bit TMR0IE (qui autorise les interruptions) l’est aussi.

    Avec toutes ces données, je me suis lancé dans la programmation avec la denière version deMBLAP et la toolsuite C18., et la bonjours les problèmes, entre les build qui passe pas à cause de point virgule qui manquaient, les accolades des boucles etc… bref vous l’avez compris je suis encore loin d’être un as dans la programmation en C, je dirais même un début débutant 
    Après moult essaie sans succès, je me tourne vers vous pour essaie de solutionné mon problème de timer.

    Donc voici mon code (Pour l’instant c’est juste un code de test pour voir si le timer fonctionne correctement)

    Code PHP:
        #include <p18f458.h>
    #pragma config OSC = HS

    int temps;



    void main (void)
    {
    TRISB 0x00// Port B toutes les I/O en sortie 

    //-------------------------------------------------
    PORTBbits.RB3=0;
    PORTBbits.RB2=0;  // Sortie vers convetiseur BCD 7 segment
    PORTBbits.RB1=1;  // pour affichage du nombre 8 (test en dur)     
    PORTBbits.RB0=0;
    //-------------------------------------------------
    INTCON =0x00;    // Mis à zéros du registre INTCON
    T0CON0b00000010;   // Configuration du timer Off, 16bit, internal CLK, prescaler On 1 :8
    TMR0H =0xF3;    // Mis en place de l'offset à 62411
    TMR0L =0xCB;    
    // Ce qui nous donne avec cette configuration une interruption toutes les 10ms

    INTCONbits.TMR0IF 0// Mis a zéros du flag d'interruption 
    INTCONbits.TMR0IE 1// Autorisation de l'interruption

    T0CONbits.TMR0ON =1// activation du timer 
    PORTBbits.RB7=0// Mis à zéros du Pin 7 du port B
    temps=0;  // Mis à zéros de la variable temps 

    while (1)
    {
    if(
    INTCONbits.TMR0IF ==1){temps++;PORTBbits.RB7=1;INTCONbits.TMR0IF 0;}
    // si interruption TMROIF == 1, alors incrémentation de la valeur de temps 
    // Mis à 1 du pin 7 du port B 
    // Remise a zéros de TMROIF
    if(temps>=10) {PORTBbits.RB5=1;}
    // si temps est supérieure ou égale a 10 pin 5 Port B à 1
    }

    Mais ceci ne fonctionne pas, le PORTBbits.RB7 ce met à 1 seulement il le reste 2 sec, puis bascule à 0 pendant environ 10ms
    Quand a cette ligne
    Code PHP:
    if(temps>=10) {PORTBbits.RB5=1;} 
    elle ne fonctionne même pas, j’ai beau attendre 20 sec et plus le
    Code PHP:
    PORTBbits.RB5 
    ne passe pas à 1.

    Ce que je comprends pas c’est pourquoi le PORTBbits.RB7 reste actif pendant 2 sec, puis a un temps de repos de 10ms qui est le temps cherché. Ni pourquoi la boucle
    Code PHP:
    if (temps>=10) {PORTBbits.RB5=1;} 
    ne fonctionne pas. J’ai beau me cassé le crâne sur le clavier je trouve plus de solution

    Merci d'avance à tous ceux qui vont m'aider dans mon problème

    -----

  2. #2
    RISC

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    Salut,

    Quelle carte utilises-tu ?
    Tout d'abord, tu pourrais faire fonctionner ton PIC beaucoup plus vite en activant la PLL. Il faut également désactiver le mode LVP :

    Code:
    #pragma config OSC=HSPLL, LVP = OFF

    Pour ce qui est des sorties tu vas avoir des problèmes si tu utilises les PORTx ligne après ligne...
    Pour les sorties et uniquement les sorties, prend l'habitude sur tous les PIC d'utiliser LATx plutôt que PORTx :

    Code:
    LATBbits.LATB3=0;
    LATBbits.LATB2=0;  // Sortie vers convetiseur BCD 7 segment
    LATBbits.LATB1=1;  // pour affichage du nombre 8 (test en dur)     
    LATBbits.LATB0=0;
    Je te déconseille très très fortement d'utiliser les broches RB6 et RB7 car elles servent pour l'ICSP et sont inutilisables en mode debug...

    Tu trouveras d'excellents tutoriels ici :
    * http://public.iutenligne.net/etudes_...eur/index.html
    * http://www.aix-mrs.iufm.fr/formation...indexPIC_C.htm

    NB : Pourquoi utilises-tu un si vieux PIC (PIC18F458) ??? Il a été remplacé par le PIC18F4580 lui-même remplacé par le PIC18F45K80...

    a+

  3. #3
    invite7aefe76b

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    J'utilise une carte fait maison, un support zif soudé sur un veroboard, avec des tulipe pour branché les câbles sur les port du pic, et un quartz. Pour la programmation j'utilise un programmateur GQ-4x

    Ok pour les sortie mais pourquoi LATx plutôt que PORTx ?

    J'ai utilisé les broches RB7, RB6 par flemmardise, car seul les broches du Port B on une résistance de tirage au +5

    Pour ce qui est du choix du pic, c'est assez simple, c'est le seul pic encore disponible dans mon entreprise, que j'ai gentillement sortie du stock .

    Pour ce qui est des tuto, j'ai pu voir celui http://www.aix-mrs.iufm.fr/formation...indexPIC_C.htm, sur les timers, mais je comprend pas tous le programme. surtout cette partie

    Code PHP:
    void traiteIT(void)        
    {
        if(
    INTCONbits.TMR0IF)            //vérifie un débordement sur TMR0 
                
    {                        
                
    INTCONbits.TMR0IF 0;    //efface le drapeau d'IT
                
    surveille();            // surveille VDD 
                
    if (!S2PORTB=0;        // eteind les LEDs
                
    }
    }

    void main(void)
    {
            
    ADCON0=1;        // CAN on. CLOCK=FOSC/2. CANAL0 (RA)
                
    ADCON1=0x8E;
            
    TRISB=0xF0;        // PRB0-PRB3 en sortie
            
    PORTB=0;        // LED eteintent
            
    TRISA=0xFF;        // PORTA en entree
            
    T0CON 0b10000011;            //Active le TIMER0 - prescaler 1:16
            
    INTCONbits.TMR0IE 1;        //Autorise interruption sur TMR0 
            
    INTCONbits.GIE 1;            //autorise toutes les IT démasquées
            
    while(1);        

    Comment fait le programme main, pour voir si
    Code PHP:
    INTCONbits.TMR0IF 1
    ???

  4. #4
    invite0e5af214

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    Salut,

    Tu as également un problème avec les interruptions à résoudre : Tu configures ton PIC pour partir en interruption (TMR0IE), ca signifie qu'au moment ou ton timer va déborder, ton PIC va arrêter d'exécuter ta fonction 'main' et exécuter un autre code, qui doit se situer à une adresse bien précise (la routine d'interruption)

    Or, dans ton cas, un tel code n'existe pas.
    Donc ton PIC se met certainement à exécuter n'importe quoi.

    Tu peux, dans un premier temps, ne pas activer l'interruption, donc laisser TMR0IE à 0.
    TMMR0IF passeras toujours à 1, mais au moins le PIC restera dans le code que tu as écrit.

    Bon courage

    PS : j'ai posté avant de vor ton message précedent, mais ca confirme ce que je dis, il te manque un poil de compréhension des interruptions
    Ca va v'nir

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

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    tu initialise bien TMR0H et TMR0L , mais tu ne remet pas cette valeur a chaque interruption !
    Alors le compte suivant sera de 0xFFFF ...

  7. #6
    invite7aefe76b

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    j'ai posté avant de vor ton message précedent, mais ca confirme ce que je dis, il te manque un poil de compréhension des interruptions
    Ca va v'nir
    Tu as vu juste, c'est la 1er fois que j'utilise les timer sur Pic et ça me rend fou.

    A ce que j'ai compris tu code trouvé dans le tuto

    Code PHP:
    #pragma code it=0x08        // le vecteur d'IT prioritaire envoie à l'adresse 8
    void saut_sur_spIT(void)    
    {
    _asm
        
    goto traiteIT            // saut écrit en assembleur sur la fonction de traitement d'IT
    _endasm
    }
    #pragma code 
    Est l'endroit ou ce trouve l'interruption a effectuer qui est codé juste après sous la forme de

    Code PHP:
    #pragma interrupt traiteIT    // SP d'IT 
    void traiteIT(void)        
    {
        if(
    INTCONbits.TMR0IF)            //vérifie un débordement sur TMR0 
                
    {                        
                
    INTCONbits.TMR0IF 0;    //efface le drapeau d'IT
                
    surveille();            // surveille VDD 
                
    if (!S2PORTB=0;        // eteind les LEDs
                

    Est a ce que j'ai compris, le pic rentre dans le programme main
    Code PHP:
    void main(void)
    {
            
    ADCON0=1;        // CAN on. CLOCK=FOSC/2. CANAL0 (RA)
                
    ADCON1=0x8E;
            
    TRISB=0xF0;        // PRB0-PRB3 en sortie
            
    PORTB=0;        // LED eteintent
            
    TRISA=0xFF;        // PORTA en entree
            
    T0CON 0b10000011;            //Active le TIMER0 - prescaler 1:16
            
    INTCONbits.TMR0IE 1;        //Autorise interruption sur TMR0 
            
    INTCONbits.GIE 1;            //autorise toutes les IT démasquées
            
    while(1);        

    et une fois que le Timer balance son interruption d'overflow, le programme rentre dans le sous programme void traiteIT(void).

    j'ai juste ou pas juste ?

    Merci déjà pour toute vos réponses, je progresse doucement mais surent.

  8. #7
    invitef86a6203

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    Code:
    #pragma interrupt traiteIT    // SP d'IT 
    void traiteIT(void)        
    {
        if(INTCONbits.TMR0IF)            //vérifie un débordement sur TMR0 
                {                        
    		TMR0H =0xF3;    // Mis en place de l'offset à 62411
    		TMR0L =0xCB;    
         
           INTCONbits.TMR0IF = 0;    //efface le drapeau d'IT
                surveille();            // surveille VDD 
                if (!S2) PORTB=0;        // eteind les LEDs
                }

  9. #8
    invite0e5af214

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    Citation Envoyé par shindra Voir le message
    j'ai juste ou pas juste ?
    Oui c'est juste !

    Les #pragma sont très important pour des raisons un peu plus complexes à expliquer, donc n'essais pas de t'en débarasser

  10. #9
    invite5bc96a17

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    Salut Shindra,

    Premièrement je te conseil de mettre chaque instruction à la ligne suivante, je ne sais pas si ça fonctionne comme tu l'as fait mais sait-on jamais. Ensuite comme l'a dit freepicbasic, tu ne recharge jamais la valeur de ton timer. Je te conseil de mettre TMR0ON à 0 (pour qu'il s'arrête de compter lorsque tu exécute du code dans ta boucle d'interruption) ensuite tu fais ce que tu veux faire, tu recharge le timer avec la valeur que tu as calculé, tu met TMR0IF à 0 et tu réenclenche le timer (TMR0ON à 1).

    Ensuite dans ton autre condition j'ai remarqué que tu ne remets jamais temps à 0. Est-ce voulu?

    Mets bien tes instructions l'une après l'autre comme tu l'as fait pour configurer ton timer. En suite, lance le programme en mode debugger. Ca te permettra de voir un peu ou va ton programme et ce qu'il fait.

    a+ ^^

  11. #10
    invite7aefe76b

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    Merci pour vos réponses aussi rapide, je suis entrain de modifier le programme avec toute les données que vous venez de me transmettre. Ma vision sur les timer est déjà plus claire qu'elle ne l'était en début d'aprem.

    je reviens vers vous ce soir après mon entrainement pour vous donnez des nouvelles de mon aventure dans la programmation en C

    Merci encore

  12. #11
    invite7aefe76b

    Re : Problème Timer0 PIC18f458 pour compte à rebours

    Avec vos conseil le timer fonctionne, et la partie multiplexage est opérationnelle

    voici le code

    Code PHP:
    include <p18f458.h>
    #pragma config OSC=HSPLL, LVP = OFF


    int temps;
    void traiteIT(void);

    void multiplexage (void)
    {
        if (
    temps==1)
            {
            
    LATBbits.LATB7=1;
            }
        if (
    temps==2)
            {
            
    LATBbits.LATB7=0;
            
    LATBbits.LATB5=1;
            }
        if (
    temps>=3)
            {
            
    LATBbits.LATB5=0;
            
    LATBbits.LATB4=1;
            }
        if (
    temps==4)
            {
            
    LATBbits.LATB7=0;
            
    LATBbits.LATB5=0;
            
    LATBbits.LATB4=0;    
            
    temps=0;
            }
        
            
            
            
                 
    }
    #pragma code it=0x08        
    void saut_sur_spIT(void)    
    {
    _asm
        
    goto traiteIT        
    _endasm
    }
    #pragma code                

    #pragma interrupt traiteIT    // SP d'IT 
    void traiteIT(void)        
    {
        if(
    INTCONbits.TMR0IF)        
                {
                
    T0CONbits.TMR0ON 0;                        
                
    temps++;
                
    INTCONbits.TMR0IF 0;
                
    TMR0H =0xF3;    
                
    TMR0L =0xCB;
                 
                
    T0CONbits.TMR0ON 1
                
                }            
                                            
                
    }


    void main (void)
    {


    temps=0;
    TRISB 0x00;
    LATBbits.LATB4=0;
    LATBbits.LATB7=0;
    LATBbits.LATB5=0;
    LATBbits.LATB4=0;
    PORTBbits.RB3=0;
    PORTBbits.RB2=0;  
    PORTBbits.RB1=1;      
    PORTBbits.RB0=0;


    T0CON0b00000010;   // Configuration du timer Off, 16bit, internal CLK, prescaler OFF
    TMR0H =0xF3;    // Mis en place de l'offset à 40536
    TMR0L =0xCB
    INTCONbits.TMR0IE 1;
    INTCONbits.GIE 1;        //Autorise interruption sur TMR0         INTCONbits.GIE = 1;    
    T0CONbits.TMR0ON =1// activation du timer 
    while(1)
    {
    multiplexage();
    }

    Reste plus qu'a programmé la partie compte a rebours et le clavier.

    Mais ça c'est au programme de demain.

    Merci a vous

Discussions similaires

  1. Compte à rebours pour IE6
    Par yoda1234 dans le forum Actualités
    Réponses: 7
    Dernier message: 09/03/2011, 12h46
  2. compte a rebours sonore ou led ? (pour les nuls)
    Par invite02732e6d dans le forum Électronique
    Réponses: 1
    Dernier message: 10/06/2008, 17h09
  3. Compte a rebours pour débutant
    Par inviteafcd52df dans le forum Électronique
    Réponses: 3
    Dernier message: 10/04/2008, 17h49
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...