Fréquencemètre avec un pic18f - Page 2
Répondre à la discussion
Page 2 sur 2 PremièrePremière 2
Affichage des résultats 31 à 40 sur 40

Fréquencemètre avec un pic18f



  1. #31
    invitee3a9db1e

    Re : Fréquencemètre avec un pic18f


    ------

    Apparemment, Fosc=64MHz maintenant ! J'ai rajouté OSCTUNEbits.PLLEN = 1;

    PLLEN: Frequency Multiplier 4xPLL for HFINTOSC Enable bit(1)
    1 = PLL enabled
    0 = PLL disabled

    Je pensais que #pragma config PLLCFG = ON ferait pareil...

    Maintenant lorsque je calcule le nombre de périodes avec mon module CCP,
    je calcule 64MHz environ lorsque je choisis "Timer1/3/5 clock source is system clock (FOSC)".
    mais je n'ai toujours rien lorsque je choisis "External clock from TxCKI pin (on the rising edge)".

    Encore et toujours le même soucis, quelque soit la fréquence de mon oscillateur interne.......

    Merci pour votre aide

    Jean

    -----

  2. #32
    invitee3a9db1e

    Re : Fréquencemètre avec un pic18f

    Nom : timer1.JPG
Affichages : 94
Taille : 74,8 Ko

    Le problème est quand même dingue!
    Voici le diagramme du Timer1. J'ai tout paramétré et quand je mets TMR1CS<1:0> = 01 je récupère bien Fosc dans TMR1H et TMR1L.
    Si je fais TMR1CS<1:0> = 10 ça marche plus!

    Mais si la boucle fonctionne pour l'un, expliquez moi pourquoi ça marche plus pour l'autre, c'est dingue !
    Je deviens fou avec cette histoire... La merde...

  3. #33
    paulfjujo

    Re : Fréquencemètre avec un pic18f

    bonsoir,

    j'ai testé ton programme sur un 18F46K22 , c'est itou ! et cela me parait normal

    si tu mets TMR1CS= 10, c'est soit le signal qui entre sur la pin T1CKI qui est selectionné
    via T1SOSCEN=0
    il n' y a que la config
    TMR1CS= 00 (Fosc/4)
    ou effectivement TRM1CS=01 (FOSC)
    qui devrait alimenter en impulsions le timer 1

    Ton signal à mesurer rentre-t-il bien sur RC2 ?
    pour faire une mesure de periode entre les 2 fronts montants?

    car j'obtiens n'importe quoi avec un signal d'entree de 25Kz TTL sur RC2
    comment fais-tu pour lire Fosc dans le timer1 ?


    nb_periodes : <0>13150<0> nb_impulsion_PPS : <0>33125<0> nb_overflow : <0>14141<0> TOTAL : <0>27814<0>INTERRUPTION OK!
    nb_periodes : <0>58960<0> nb_impulsion_PPS : <0>37992<0> nb_overflow : <0>14332<0> TOTAL : <0>24597<0>INTERRUPTION OK!
    nb_periodes : <0>39450<0> nb_impulsion_PPS : <0>42859<0> nb_overflow : <0>14523<0> TOTAL : <0>22107<0>INTERRUPTION OK!
    nb_periodes : <0>20140<0> nb_impulsion_PPS : <0>47726<0> nb_overflow : <0>14714<0> TOTAL : <0>20122<0>INTERRUPTION OK!

  4. #34
    invitee3a9db1e

    Re : Fréquencemètre avec un pic18f

    Citation Envoyé par paulfjujo Voir le message
    si tu mets TMR1CS= 10, c'est soit le signal qui entre sur la pin T1CKI qui est selectionné via T1SOSCEN=0
    il n' y a que la config TMR1CS= 00 (Fosc/4)
    ou effectivement TRM1CS=01 (FOSC)
    qui devrait alimenter en impulsions le timer 1
    Pourquoi il n'y aurait que TRM1CS = 01 et TRM1CS = 00 qui alimenterait le Timer1 ? Je ne comprends pas.

    Si on met TRM1CS = 10, on compte les fronts montants du signal sur la pin T1CKI, non ?


    Citation Envoyé par paulfjujo Voir le message
    Ton signal à mesurer rentre-t-il bien sur RC2 ?
    pour faire une mesure de periode entre les 2 fronts montants?

    car j'obtiens n'importe quoi avec un signal d'entree de 25Kz TTL sur RC2
    comment fais-tu pour lire Fosc dans le timer1 ?
    Mon signal permettant de cadencer les interruptions du module CCP1 arrive sur RC2, à savoir un pulse toutes les secondes.
    Par contre, mon signal à mesurer rentre sur RC0, qui correspond à T1CKI.
    Ce n'est pas comme cela qu'il faut câbler ?

    Pour lire Fosc dans le timer1, je paramètre TRM1CS=01 et je récupère ainsi le nombre de périodes de Fosc dans TMR1H et TMR1L.
    Ce n'est pas la méthode ?

    Merci pour tes critiques, j'espère m'être trompé, ça me donnerait une bonne raison de me tirer les cheveux depuis quelques jours !

  5. #35
    paulfjujo

    Re : Fréquencemètre avec un pic18f

    bonsoir,

    Citation Envoyé par jean_23 Voir le message
    Pourquoi il n'y aurait que TRM1CS = 01 et TRM1CS = 00 qui alimenterait le Timer1 ? Je ne comprends pas.
    Si on met TRM1CS = 10, on compte les fronts montants du signal sur la pin T1CKI, non ?
    Oui, si le signal rentre sur T1CKI ..

    C'est bien pour cela que je posais la question de savoir ou rentrait ton signal..
    Il te faut donc un signal annexe en RC2 pour compter sur T1CKI ...

    Par contre je n'ai pas utilisé le mode CCP1 ainsi
    puisque je rentre directement le signal à mesurer en RC2 et utilise FOSC pour alimenter le Timer1.
    Apres plusieurs essais je n'ai pu avoir un resutat honorable, mais qu'avec un Quartz
    trop de dispertion de mesures avec l'oscillateur Interne.
    Et de plus avec PLL OFF , FOSC/4 , et IT CPP1 tous les 16 fronts.
    Testé en BF de 4.88 Hz à 25000Hz.
    dont J'ai mis le source ci-joint


    Ce n'est pas la méthode ?
    JE pense qu'il doit y avoir plusieurs methodes, mais
    celle ci je ne la connais pas et donc jamais testée.

    d'ou ma question : comment est geré (d'ou provient) la source d'impulsion arrivant sur T1CKI ?


    Dans cette methode, et vu la duree d'execution de la boucle principale
    je ne vois pas bien comment est borné la fenetre de capture .. sans bloquer quelque part les interruptions
    pour pouvoir afficher tranquilement les resultats et eviter des debordements de compteurs .
    Je suis donc tres ineressé aussi par ton probleme.
    Fichiers attachés Fichiers attachés

  6. #36
    paulfjujo

    Re : Fréquencemètre avec un pic18f

    bonsoir,


    J'ai retesté la version originale de jean_23
    donc en utilisant RC2 avec une horloge de 1Hz ( issue de Timer3 -> RA4 -- relié à RC2)
    et la frequence du signal à mesurer entrant dans RC0 ..
    rien sur Timer1...

    En voulant me servir du Timer3 , j'avais une erreur de compil sur
    T3CONbits.T3SYNC;
    alors que
    T1CONbits.T1SYNC; est OK !
    j'ai cherché dans le 18F46K22.H
    et là : difference !
    les 3 premiers bits de la structure n'on pas d'homologue comme pour Timer1 T1
    je me suis donc ajusté une autre version de 18F46K22_.H

    le probleme est en fait, indirectement ici :
    Pas vraiment un probleme ; mais vraiment une designation equivoque des bits du registre
    le meme bit est declaré en T1SYNC ou NOT_T1SYNC là, est la question ?
    sur le schema on voit bien la barre au dessus du sigle T1SYNC
    donc pour avoir un 1 il faut mettre un 0
    en mettant T1SYNC à 0 au lieu de 1 ..le signal T1CKI passe bien dans le Timer1

    Code:
    extern volatile near union {
      struct {
        unsigned TMR1ON:1;
        unsigned T1RD16:1;
        unsigned NOT_T1SYNC:1;
        unsigned T1SOSCEN:1;
        unsigned T1CKPS:2;
        unsigned TMR1CS:2;
      };
      struct {
        unsigned :1;
        unsigned RD16:1;
        unsigned T1SYNC:1;
        unsigned T1OSCEN:1;
        unsigned T1CKPS0:1;
        unsigned T1CKPS1:1;
        unsigned TMR1CS0:1;
        unsigned TMR1CS1:1;
      };
    } T1CONbits;
    à noter : la résolution avec ce mode est de +-1Hz seulement

    voir fig jointe

    la soluce precedente est bien plus precise dans le domaine des basses frequences..
    Pour les frequences plus haute , je ne vois donc pas l'interet du mode capture ..
    à moins que quelqu'un puisse me montrer /prouver le contraire
    par rapport à un mode simple comptage avec des timers.
    frequencemetre up 50Mhz.
    Images attachées Images attachées  

  7. #37
    invitee3a9db1e

    Re : Fréquencemètre avec un pic18f

    Bonjour et merci pour tes mesures.

    J'utilise un boitier GPS du commerce qui sort un signal PPS très précis. J'ai donc une impulsion toutes les secondes +/- 25ns.
    J'ai donc une fenêtre de comptage de 1s +/- 50ns (en prenant une erreur max)
    Du coup, pour un signal ne dépassant pas 20Mhz (50ns de période), je ne devrais pas être dérangé par ce PPS en terme de précision de comptage.

    Pour remettre toutes les choses au clair depuis le début de cette discussion :
    Je travaille avec le module capture CCP1 et le Timer1.
    Le Timer1 sert de compteur à chaque front montant de l'horloge (en ce moment 10MHz pour test) sur RC0.
    Le module CCP1 est interrompu chaque seconde par un PPS(cf. ci-dessus) sur RC2 et fait une recopie des registres du Timer1 vers ses propres registres CCPR1H et CCPR1L.

    Citation Envoyé par paulfjujo Voir le message
    Dans cette methode, et vu la duree d'execution de la boucle principale
    je ne vois pas bien comment est borné la fenetre de capture .. sans bloquer quelque part les interruptions
    pour pouvoir afficher tranquilement les resultats et eviter des debordements de compteurs .
    Je suis donc tres interessé aussi par ton probleme.
    Ca ne fait pas longtemps que je fais des petits projets sur PIC et je t'avouerai que c'est un challenge perso de réussir à faire fonctionner ce foutu module CCP1!
    Du coup, j'essaie tant bien que mal de caractériser la temps d'exécution de mon compteur et de programme principal, mais j'ai encore du mal à tout cerner.

    Pour moi, le Timer1 est capable de fonctionner en tache de fond et je pensais donc que mon affichage n'interagissait pas avec le bon fonctionnement du comptage. Vrai ?
    Dans quelle partie de mon programme, selon toi, je suis susceptible de perturber mon comptage, et donc de perdre en précision ?

    Voici mon programme dernièrement mis à jour :
    Code:
    /**********************************/
    /************* HEADERS ************/
    /**********************************/
    #define USE_OR_MASKS
    #include <stdio.h>
    #include <stdlib.h>
    #include <p18f24k22.h>
    #include <usart.h>
    #include <timers.h>
    #include <capture.h>
    #include <EEP.h>
    #include <delays.h>
    
    
    /**********************************/
    /********* CONFIG SYSTEM **********/
    /**********************************/
    #pragma config FOSC 	= INTIO7	// Internal oscillator block clock out on OSC2 for debug the clock speed
    #pragma config STVREN	= OFF
    #pragma config WDTEN 	= OFF
    #pragma config BOREN	= OFF
    #pragma config PWRTEN 	= ON
    
    
    /***********************************************/
    /**********	    VARIABLES GLOBALES 	  **********/
    /***********************************************/
    unsigned char 		it_OK				= 0;		// (8bits) Passe à 1 lors d'une interruption
    unsigned char 		start				= 0;
    
    
    unsigned int 		nb_periodes		= 0;		// (16bits) Variable pour mémoriser le nb de periodes entre 2 fronts montants de PPS
    unsigned int		nb_overflow		= 0;		// (16bits) Variable pour stocker le nombre de débordement du Timer1 
    unsigned int		nb_impulsion_PPS	= 0;		// (16bits) Compteur pour sauvegarder le nb d'impulsion du PPS entre 2 corrections
    unsigned long int	nb_total			= 0;		// (32bits) Fréquence exprimée en hexa
    
    unsigned char 		debut[]			= "DEBUT DU MAIN \r\n";
    unsigned char 		periodes[] 			= "INTERRUPTION OK!\r\n nb_periodes : ";
    unsigned char 		PPS[] 			= " nb_impulsion_PPS : ";
    unsigned char		overflow[]			= " nb_overflow : ";
    unsigned char 		total[]			= " TOTAL : ";
    
    
    /***********************************************/
    /**********     S/P d'INTERRUPTION    **********/
    /***********************************************/
    #pragma interrupt it_PPS
    void it_PPS( void) 
    {
    	if(PIR1bits.CCP1IF) 	// flag déclenché par un front montant du PPS
    	{
    		if(start == 0) {
    			nb_periodes		= CCPR1;	// copie du registre CCPR qui contient la valeur du Timer1	
                            nb_impulsion_PPS++;			// on incrémente le nb de pulse de PPS
    			it_OK 			= 1;
    			
    		} else {
                            T1CONbits.TMR1ON 	= 1;
    			start 				= 1;
    		}
    	PIR1bits.CCP1IF = 0;	// flag remis à 0
    	}
    
    	if(PIR1bits.TMR1IF)		// flag déclenché par un débordement du Timer1
    	{
    		nb_overflow++;
    		PIR1bits.TMR1IF = 0;
    	}
    
    }
    
    #pragma code interruption=0x8
    void it_prioritaire( void)
    {
    	_asm goto it_PPS _endasm
    }
    #pragma code
    
    
    
    /***********************************************/
    /***********************************************/
    /**********	       	   MAIN       	  **********/
    /***********************************************/
    /***********************************************/
    void main(void) {
    
    	// Oscillateur à 16MHz
    	OSCCONbits.IRCF		= 7;     // 16MHz
            OSCCON2                          = 0;
            OSCTUNEbits.PLLEN           = 1;     // PLL x4
    
    	// Configuration de l'USART
    	SPBRG1 			= 103;	// 9600 baud @16MHz
            SPBRG1                    = 207;       // 19200 baud @64MHz
    	TXSTA 			= 0x24;	// Config TX
    	RCSTA 			= 0x90;	// Config RX	
    	TRISCbits.TRISC7 	= 1;	// RS232_RX_10MHZ as input
    	TRISCbits.TRISC6	= 0;	// RS232_TX_10MHZ as output
    	INTCON 			|= 0xC8;
    	INTCON2 			|= 0b10000001;
    	PIE1bits.RC1IE 		= 1;	// Enabled USART interrupts
    	PIR1bits.RC1IF 		= 0;
    
    	// Timer1 configuration
    	TRISCbits.TRISC0	= 1;	// Configure RC0 (clk_PIC) as an input
    	T1CONbits.RD16		= 1;	// Timer mode 16 bits
    	T1CONbits.T1CKPS1	= 0;	// 1:1 prescale value
    	T1CONbits.T1CKPS0	= 0;
    	T1CONbits.T1SOSCEN = 0;  	// secondary oscillator disabled
    	T1CONbits.T1SYNC	= 0;	// external clk input synchronized
    	T1CONbits.TMR1CS1 	= 1;	// clk source : external clock from T1CKI pin
    	T1CONbits.TMR1CS0	= 0;
    	T1CONbits.TMR1ON	= 0;
    	IPR1bits.TMR1IP		= 1;
    	WriteTimer1(0);
    	INTCONbits.PEIE		= 1;	
    	PIE1bits.TMR1IE		= 1;
    	INTCONbits.GIE		= 0;
    	INTCONbits.GIEL		= 0;
    	CCPTMRS0bits.C1TSEL = 0;
    
    	// Capture Mode configuration
    	TRISCbits.TRISC2 	= 1;	// Configure RC2 (CCP1) as an input
    	ANSELCbits.ANSC2	= 0;	// RC2 defined as digital
    	CCP1CONbits.CCP1M3	= 0;	// Capture mode  : every rising edge <3:0> = 0101
    	CCP1CONbits.CCP1M2	= 1;
    	CCP1CONbits.CCP1M1	= 0;
    	CCP1CONbits.CCP1M0 = 1;
    	CCPR1H = 0;
    	CCPR1L = 0;
    	PIR1bits.CCP1IF		= 0;	// flag cleared			
    	PIE1bits.CCP1IE		= 1;	// enable CCP1 interrupts
    
    	RCONbits.IPEN 		= 1;
    	INTCONbits.GIE		= 1;
    
    	PIR1bits.CCP1IF 	= 0;
    	PIE1bits.CCP1IE 	= 1;
    	
    	// AFFICHAGE "DEBUT DU MAIN"
    	while(!TXSTA1bits.TRMT);
    	puts1USART((char*)debut);
    
    
    	while(1) {
    		if(it_OK)
    		{
    			while(!TXSTA1bits.TRMT);
    			puts1USART((char*)periodes);
    			affiche(nb_periodes); // personnal function, which works correctly  
    				
    			while(!TXSTA1bits.TRMT);
    			puts1USART((char*)PPS);
    			affiche(nb_impulsion_PPS); 
    				
    			while(!TXSTA1bits.TRMT);
    			puts1USART((char*)overflow);
    			affiche(nb_overflow); 
    
    			nb_total = 65536*(long int)nb_overflow + (long int)nb_periode_10MHz - 1;
    			nb_total = nb_total/((long int)nb_impulsion_PPS); 
    				
    			while(!TXSTA1bits.TRMT);
    			puts1USART((char*)total);
    			affiche(nb_total);
    
    			it_OK = 0;
    		}		
    	}
    }
    J'ai fait des mesures avec mon programme d'un côté et avec un fréquencemètre d'un autre côté. Je trouve un écart moyen de 63Hz entre les 2.
    C'est énorme je trouve. Quelles pourraient être les causes de ce biais ?

    Merci à tous pour votre aide.

    Jean

  8. #38
    paulfjujo

    Re : Fréquencemètre avec un pic18f

    bonsoir,

    Je n'ai pas testée cette derniere version
    mais je suppose que cela ne peux pas tourner.. car je ne vois pas comment "start" peut etre mis à 1
    car absent dans la boucle principale du main..

    Concernant le traitement du front montant dans l'interrupt
    AVANT de recuperer le contenu du timer1..
    je mettrais celui ci sur oFF et bloquerais les IT Timer1

    T1CONbits.TMR1ON = 0; // ne plus perturber le contenu du timer1
    PIE1bits.TMR1IE = 0;
    nb_periodes = CCPR1; // recupere tranquilement le contenu

    car ensuite, (dans le traitement des IT) il pourrait tres bien arriver une IT timer1 par le simple
    rajout des cycles de traitement de l'IT CCP qui est en cours.

    d'autant qu'en langage C , il faudrait verifier le detail de la compilation resultante..
    Pour moi il n'y a que l'ASM qui peut etre au maximum rigoureux dans les timmings...
    car là on peut compter les cycles machine de chaque instruction.

    de meme initialiser le timer1 à 0, avant de l'autoriser à compter
    WriteTimer1(0);
    T1CONbits.TMR1ON = 1;

  9. #39
    RISC

    Re : Fréquencemètre avec un pic18f

    Salut,

    Plusieurs choses à améliorer :

    1/ Variables globales modifiées dans le interruptions
    Il faut ABSOLUMENT les déclarer en "volatile" sans quoi tu vas avoir de très gros PB...

    Code:
    volatile unsigned char 		it_OK				= 0;		// (8bits) Passe à 1 lors d'une interruption
    volatile unsigned char 		start				= 0;
    ....
    volatile unsigned int 		nb_periodes	= 0;	// (16bits) Variable pour mémoriser le nb de periodes entre 2 fronts montants de PPS
    volatile unsigned int		nb_overflow	= 0;	// (16bits) Variable pour stocker le nombre de débordement du Timer1 
    volatile unsigned int		nb_impulsion_PPS= 0;	// (16bits) Compteur pour sauvegarder le nb d'impulsion du PPS entre 2 corrections
    2/ Interruption
    Code:
    #pragma interrupt it_PPS
    void it_PPS( void) 
    {
    	if(PIR1bits.CCP1IF && PIE1bits.CCP1IE) 	// flag déclenché par un front montant du PPS
    	{
    		if(start == 0) {
    			nb_periodes		= CCPR1;	// copie du registre CCPR qui contient la valeur du Timer1	
                            nb_impulsion_PPS++;			// on incrémente le nb de pulse de PPS
    			it_OK 			= 1;
    			
    		} else {
    		        PIR1bits.TMR1IF = 0;                             // il est recommandé avant de lancer le timer de clearer le flag correspondant
                            T1CONbits.TMR1ON 	= 1;        
    			start 				= 1;
    		}
    	PIR1bits.CCP1IF = 0;	// flag remis à 0
    	}
    
    	if(PIR1bits.TMR1IF && PIE1bits.TMR1IE)		// flag déclenché par un débordement du Timer1
    	{
    		nb_overflow++;
    		PIR1bits.TMR1IF = 0;
    	}
    
    }
    3/ Calculs "complexes"
    Il faut éviter de multiplier ou diviser par des puissances de 2 quand on peut faire un décalage (c'est beaucoup plus rapide...
    Code:
    			nb_total = 65536*(long int)nb_overflow + (long int)nb_periode_10MHz - 1;
    peut se faire :
    Code:
    			nb_total = ((long int)nb_overflow << 16 )+ (long int)nb_periode_10MHz - 1;
    4/ MODE CAPTURE
    Si tu veux à la fois avoir de la dynamique ET de la résolution, il faut dédier le TIMER à la capture ET le laisser tourner.
    Si le temps entre 2 fronts peut être supérieur à la dynamique du TIMER (65536), il faut compter les interruptions car cela ajoute des "digits" à gauche de la valeur mesurées :
    période mesurée = (NB INT TIMER << 16) + différence (capture actuelle - capture ancienne)

    Le sujet de la mesure de période ou de la capture sur PIC18 a été traité de très nombreuses fois sur ce forum. Si tu fais une recherche tu trouveras de nombreux exemples ;=)

    a+

  10. #40
    invitee3a9db1e

    Re : Fréquencemètre avec un pic18f

    Salut,

    Merci pour ces précieuses recommandations.

    Avec ces modifications, j'ai un biais de 4Hz avec un fréquencemètre classique précis à 10e-10.
    Je vais analyser mon algo pour trouver où est-ce que je pourrais perdre ces quelques périodes.

    Merci beaucoup

    Jean

Page 2 sur 2 PremièrePremière 2

Discussions similaires

  1. frequencemetre avec les bascules
    Par invite8cfb2c49 dans le forum Électronique
    Réponses: 4
    Dernier message: 25/12/2012, 16h56
  2. Fréquencemètre avec Pic 18f4520
    Par invite20f901d9 dans le forum Électronique
    Réponses: 3
    Dernier message: 18/07/2011, 11h56
  3. Fréquencemetre avec un Atmega32
    Par invite6d67225b dans le forum Électronique
    Réponses: 15
    Dernier message: 01/06/2011, 22h53
  4. fréquencemètre précis avec communication sans fil
    Par invite99aaa6a7 dans le forum Électronique
    Réponses: 12
    Dernier message: 25/03/2010, 16h12
  5. réalisation d'un capteur de température avec un fréquencemètre
    Par inviteed63aef3 dans le forum Électronique
    Réponses: 3
    Dernier message: 25/04/2007, 11h40
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...