18Fxx interruption Timer0
Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

18Fxx interruption Timer0



  1. #1
    amoniaque

    18Fxx interruption Timer0


    ------

    Bonjour,

    J'utilise un 18F14K50 programmé sous C18.
    Il est cadencé à 12MHz et je souhaite utiliser le Timer0 en interruption toutes les 50µs.

    Voici mon code :
    Code:
    //Include
    #include <p18F14K50.h>
    
    #define USE_AND_MASK
    #include <timers.h>
    
    #include <main_header.h>	//Configuration des fusibles
    
    //Prototypes
    void high_isr (void);
    void InterruptTimer0(void);
    	
    //Define
    #define MoteurGauche LATCbits.LATC4
    	
    void main ()
    {
    	TRISC  =0x00;	//portC en sorties
    	
    	OpenTimer0( TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_1);	//timer0 en interruption toutes les 50µs
    	WriteTimer0(106);	//8^2- [50E-6/(4*1/12E6)]
    
    	INTCONbits.TMR0IF = 0;	//flag timer0
    	INTCONbits.GIE = 1;	//enable global interrupt
    
    	while (1)
    	{
    	} //while
    }//main
    
    
    //********************************************************************************************************************************************
    //Gestion des interruptions
    
    
    //Lors d'un interruption haute priorité, rediriger vers "high_isr" (l'adresse pour les basse priorité est 0x18)
    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
    	_asm GOTO high_isr _endasm
    }
    #pragma code /* return to the default code section */
    
    
    // Fonction des interruptions hautes
    #pragma interrupt high_isr
    void high_isr (void)
    {
    	if (INTCONbits.TMR0IF == 1)	//Si interruption venant du timer0
    	{
    		WriteTimer0(186);
    		INTCONbits.TMR0IF = 0;	
    		InterruptTimer0();
    	}
    }
    
    void InterruptTimer0(void)
    {
    	/*
    	code gérant mes E/S
    	*/
    }
    J'ai rencontré deux problèmes :
    1. théoriquement pour avoir (environ) 50µs je dois écrire 106 dans le registre du timer car : 256 - 50E-6 / (4*1/12E6) = 106. Sauf que dès que je teste, la valeur doit être d'environ 186;
    1. si je rempli la fonction "InterruptTimer0()" alors dans ce cas l'interruption ne se fait plus du tout à 50µs et je dois à nouveau changer la valeur dans le registre du timer pour atteindre à nouveau le temps désiré ...

    J'ai du mal à comprendre comment ça se fait... J'ai l'impression que le timer arrête de compter dès que l'interruption s'est produite.

    Merci par avance.

    -----

  2. #2
    RISC

    Re : 18Fxx interruption Timer0

    Salut,

    Quelle version du compilateur C18 utilises-tu ?
    Peux-tu faire voir ton fichier "main_header.h" qui contient les fusibles ?
    Quel oscillateur utilises-tu (interne, externe) quartz,... ?

    a+

  3. #3
    amoniaque

    Re : 18Fxx interruption Timer0

    Alors c'est C18 3.36 avec MPLAB8.56.
    L'oscillateur est un quartz en 12MHz (avec ses deux petites capa' de 22pF comme il faut).

    Voici les fusibles utilisés :

    Code:
    #ifndef __MAINHEADER_H
    #define __MAINHEADER_H
    
    
    //configuration du PIC (aller dans "help/Topics/PIC18 config settings/"
    #pragma config CPUDIV = NOCLKDIV, USBDIV = OFF	// CONFIG1L
    #pragma config FOSC = HS, PLLEN=OFF, PCLKEN = ON, FCMEN = OFF, IESO = OFF	// CONFIG1H
    #pragma config PWRTEN = OFF, BOREN = OFF, BORV = 30					// CONFIG2L
    #pragma config WDTEN = OFF, WDTPS = 32768                                     // CONFIG2H
    #pragma config MCLRE = OFF, HFOFST = OFF				        // CONFIG3H
    #pragma config STVREN = ON, LVP = OFF, BBSIZ=OFF, XINST = OFF	// CONFIG4L
    #pragma config CP0 = OFF, CP1 = OFF						                    // CONFIG5L
    #pragma config CPB = OFF, CPD = OFF                                    			    // CONFIG5H
    #pragma config WRT0 = OFF, WRT1 = OFF						                // CONFIG6L
    //#pragma config WRTB = ON, WRTC = OFF                            			// CONFIG6H
    // Disabled WRTB for debugging.  Reenable for real.
    #pragma config WRTB = OFF, WRTC = OFF                            			// CONFIG6H
    
    #pragma config EBTR0 = OFF, EBTR1 = OFF							           	// CONFIG7L
    #pragma config EBTRB = OFF                                                  // CONFIG7H
    
    #endif

  4. #4
    herrmattoon

    Re : 18Fxx interruption Timer0

    Salut,
    En ce qui concerne le point 1) je pense que le traitement de l'interruption prend du temps (20 instructions à 1 / 4Tck (?)) et le timer est à nouveau chargé avec la bonne valeur un peu trop tard.
    Sinon, je n'en suis pas sûr, mais je pense que ce serait bien de ne pas appeler de fonction dans la routine d'interruption. Il faudrait qu'elle soit le plus court possible. Tu peux mettre un flag pour le traiter dans la boucle principale ou alors tout écrire dans la routine... Si timer sur 8 bits -> tmrif = 0 tmrl = valeur, flag_tm_occurs =1 et le tour est joué! Ca évite de charger une adresse pour passer dans la fonction en sauvegardant l'adresse de retour, puis ensuite retourner finalement de l'interruption...
    Dans le main tu fais un test de flag_tm_occurs et si à 1 : tu appelles la fonction ENORME qui traite les entrées sorties, puis à son retour, si le uC doit faire dodo tu le mets en IDLE et un nouveau cycle recommencera plus tard...

    Ma réponse n'est peut-être pas en phase avec ton projet, mais j'aurais essayé

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

    Re : 18Fxx interruption Timer0

    Salut,

    En ce qui concerne le point 1) je pense que le traitement de l'interruption prend du temps (20 instructions à 1 / 4Tck (?)) et le timer est à nouveau chargé avec la bonne valeur un peu trop tard.
    En effet le traitement de l'interruption prend du temps mais ce temps est fixe. Tout comme l'écriture dans le registre du timer (ceci prend exactement 2instructions) donc lorsque j'écris dans mon timer je devrais ajouter quelques TCY en plus ...

    Sinon, je n'en suis pas sûr, mais je pense que ce serait bien de ne pas appeler de fonction dans la routine d'interruption.
    J'ai mis directement mon code dans la routine d'interruption et ça ne change rien, plus ce code sera grand, plus le décalage au niveau du temps du timer sera long ...

    Dans le main tu fais un test de flag_tm_occurs et si à 1 : tu appelles la fonction ENORME qui traite les entrées sorties
    Il y a de l'idée mais dans ce cas je ne vois pas du tout l'intérêt d'utiliser une interruption. Mon but est d'avoir une base de temps fixe, régulièrement appelée et garder mon Main() pour les autres fonctions moins prioritaires.

    Merci

  7. #6
    amoniaque

    Re : 18Fxx interruption Timer0

    C'est bon j'ai trouvé l'erreur !

    J'ai simplement remplacé le "WriteTimer0(106);" par un "TMR0L = 106;" et miracle ça fonctionne !

    D'ailleurs, si des fois une personne est amenée à chercher, je suis passé au mode 16bits après et pour qu'il fonctionne correctement, il faut écrire TMR0H avant TMR0L ... Je n'ai pas compris pourquoi mais ça fonctionne ! D'ailleurs si quelqu'un a la réponse je suis preneur ...

    Bonne nuit !

  8. #7
    Forhorse

    Re : 18Fxx interruption Timer0

    Citation Envoyé par amoniaque Voir le message
    D'ailleurs, si des fois une personne est amenée à chercher, je suis passé au mode 16bits après et pour qu'il fonctionne correctement, il faut écrire TMR0H avant TMR0L ... Je n'ai pas compris pourquoi mais ça fonctionne ! D'ailleurs si quelqu'un a la réponse je suis preneur ...

    Bonne nuit !
    C'est simple, ça vient du mode d'écriture dans les registres du timer. Contrairement au pic 16F ou l'on accedait directement au timer, sur le 18F l'écriture dans le registre de poid fort passe par un buffer, qui est chargé dans le registre réel du timer en même temps que l'instruction d'écriture dans le registre de poids faible.
    ça evite les "glitchs" où le timer pouvait deborder entre les deux instructions d'écriture.

  9. #8
    amoniaque

    Re : 18Fxx interruption Timer0

    C'est simple, ça vient du mode d'écriture dans les registres du timer. Contrairement au pic 16F ou l'on accedait directement au timer, sur le 18F l'écriture dans le registre de poid fort passe par un buffer, qui est chargé dans le registre réel du timer en même temps que l'instruction d'écriture dans le registre de poids faible.
    ça evite les "glitchs" où le timer pouvait deborder entre les deux instructions d'écriture.
    Ok, c'est pour ça qu'il y a une porte qui commande dans un sens ou dans l'autre TMR0H vers/venant du mot haut de timer0 ... Je me demandais à quoi ça servait.

    Merci!

Discussions similaires

  1. interruption sur TIMER0 ....HELP !!
    Par inviteb26dc581 dans le forum Électronique
    Réponses: 16
    Dernier message: 04/05/2010, 10h59
  2. timer0 pic18f4550
    Par titoff dans le forum Électronique
    Réponses: 20
    Dernier message: 26/08/2009, 21h47
  3. Timer0
    Par invite8dac0c00 dans le forum Électronique
    Réponses: 6
    Dernier message: 08/06/2009, 18h16
  4. Interruption Timer0 PIC16F628 et CCS
    Par invite70684c77 dans le forum Électronique
    Réponses: 1
    Dernier message: 15/05/2009, 16h56
  5. Timer1 et timer0
    Par guifou dans le forum Électronique
    Réponses: 4
    Dernier message: 18/01/2009, 05h16
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...