Mesure de fréquence avec ECCP1 sur PIC
Répondre à la discussion
Affichage des résultats 1 à 7 sur 7

Mesure de fréquence avec ECCP1 sur PIC



  1. #1
    cubitus_54

    Mesure de fréquence avec ECCP1 sur PIC


    ------

    Bonjour,

    Je viens de tester pour la première fois la mesure de période/fréquence grâce à l'ECCP
    La fréquence à mesurer provient d'un capteur de luminosité TSL235

    Pour tester, j'utilise un PIC 18F26K20
    La fréquence est fournie par un générateur de fonctions.
    Pour visualiser le résultat, j’envoie avec le programme deux mots en SPI que je visualise à l'oscilloscope.

    Mon problème actuel est que le mot de poids faible est bon, par contre le mot de poids fort affiche soit 0 soit 255

    Sur la photo d'écran on voit, la fréquence à 56K (D2)
    la valeur haute 0
    la valeur basse 1E
    Normalement je devrais avoir 11E soit 286*0.0625µs= 17.8µs soit 55,9kHz

    Pourquoi je n'arrive pas à obtenir la valeur haute ?

    Merci

    Code:
    void itcomp()
    {
    	PERIODE=ccpr1-ANCIEN;
    	ANCIEN=ccpr1;
    	MAJ=1;
    
    }
    
    void main()
    {
    ansel = 0x00;
    anselh = 0x00;
    
    	osccon=0xf0;
    	osctune=0x40;
    	SPI_Legacy0_SPI_Init();
    
    	//Interruption 1 période sur eccp1
    	st_bit(intcon, GIE);
    	t1con.RD16=0;	
    	t1con.TMR1CS=0;
    	t1con.T1CKPS1=0;
    	t1con.T1CKPS0=0;
    	t1con.T1SYNC=1;		
    	t1con.TMR1ON=1;
    	t3con.T3CCP2=0;	
    	ccp1con=0x05;	
    	pie1.CCP1IE=1;
    	rcon.IPEN=1;	
    	tmr1h=0;
    	tmr1l=0;
    
    	//Boucle
    	while (1)
    	{
    		if (MAJ == 1)
    		{
    			//Interruption
    			cr_bit(pie1, TMR1IE);
    			//MSB
    			SPI_Legacy0_SPI_Send_Char(PERIODE >> 8);
    			//LSB
    			SPI_Legacy0_SPI_Send_Char(PERIODE);
    			MAJ = 0;
    
    			//Pause
    			delay_ms(10);
    		}
    	}
    	mainendloop: goto mainendloop;
    }
    
    void INTERRUPT_MACRO(void)
    {
    	//Handler code for [ECCP]
    	if(pir1.CCP1IF)	
    	{						
    	itcomp(); 
    	clear_bit(pir1, CCP1IF); // supprimer l'interruption
    	}
    }
    Nom : MSO4014_20140429-174900.png
Affichages : 100
Taille : 21,0 Ko

    -----

  2. #2
    RISC

    Re : Mesure de fréquence avec ECCP1 sur PIC

    Salut,

    Je n'utilises pas le compilateur que tu utilises (apparemment CCS).
    A ta place je ferai très attention à la lecture du registre CCPR1 qui est sur 16 bits...
    N'oublie pas que le PIC18 lis seulement 8 bits à la fois...
    Normalement le plus sur est de lire CCPR1L et ensuite de lire CCPR1H que tu shiftes de 8 bits à gauche pour l'ajouter.

    Vérifies que quand tu écris ccpr1, ton compilo lis bien les 2 registres et multiplies la partie haute par 256 avant de les ajouter...

    Essayes de passer par les registres 8 bits pour voir s'il y a une différence.

    a+

    PS : dans l'interruption il est recommandé de faire :
    Code:
    if(pir1.CCP1IF && pie1.CCP1IE)

  3. #3
    cubitus_54

    Re : Mesure de fréquence avec ECCP1 sur PIC

    Bonjour RISC,

    L'idée du registre m'avait effleuré l'esprit, mais je m'étais dit que si le compilateur l’acceptait ce devait être bon...

    Code:
    void FCM_itcomp()
    {
    	PERIODEL=ccpr1l;
    	PERIODEH=ccpr1h;
    	ANCIENL=PERIODEL;
    	ANCIENH=PERIODEH;
    	PERIODE=((PERIODEH<<8)|PERIODEL)-ANCIEN;
    	ANCIEN=(ANCIENH<<8)|ANCIENL;
    	SYNCHO=1;
    }
    Ca semble bien fonctionner
    Merci RISC

    On peut simplifier le code ?
    Comment est-ce que l'on gère le cas où on dépasse 65535 ?

  4. #4
    RISC

    Re : Mesure de fréquence avec ECCP1 sur PIC

    Salut,

    Il faut faire très très attention aux accès 16 bits sur les micro 8bits quand le compilateur gère cela pour toi.
    Le meilleur exemple est le cas des TIMER 16 bits (Timer1) :
    * en lecture, il faut lire l'octet de poids faible TMR1L AVANT de lire TMR1H.
    * en ecriture, il faut écrire TMR1H AVANT d'écrire TMR1L

    Je ne vois comment un compilateur peut deviner cela en ayant un seul registre d'accès 16bits...Il faudrait 2 registres d'accès 16bits : un qui accède la partie haute puis partie basse et un autre qui fait l'inverse ;=)

    SIMPLIFICATION DU CODE
    Je pense que le code que tu as est très court. (A combien fonctionne ton PIC ? 16 MIPS ?)
    J'ai une idée mais je ne suis pas sur que le code sera plus court / plus rapide.
    Tu déclares une union qui définit à la fois ta variable ANCIEN en accès 8 et en accès 16bits.

    DEPASSEMENT
    Pour gérer les dépassements il suffit d'activer les interruptions TIMER et de mémoriser le Nombre de dépassements. Cela revient à ajouter un digit à gauche de ta valeur pour augmenter la dynamique

    a+
    Dernière modification par RISC ; 30/04/2014 à 22h20.

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

    Re : Mesure de fréquence avec ECCP1 sur PIC

    Pour le registre de 16 bits, c'est curieux...
    Doc du 18F26K20
    bit 7 RD16: 16-bit Read/Write Mode Enable bit
    1 = Enables register read/write of TImer1 in one 16-bit operation
    0 = Enables register read/write of Timer1 in two 8-bit operations
    Même en position 1 j'ai le même défaut, bref ce n’est pas grave.

    J'ai un peu avancé sur mon truc :
    Le but est de lire la fréquence d'un capteur de lumière STL235 qui génère une fréquence de 1Hz à 800kHz

    Le programme ci-dessus finalement ne convient pas bien :
    Pour la fréquence basse (quasi-obscurité), il faudrait gérer le débordement comme tu l'as cité.
    Pour les hautes fréquences, quand la période du signal est plus courte que la réponse à l’interruption ça affiche des trucs incohérents... La limite haute se situe à 300kHZ avec un PIC à 64Mhz et donc une fréquence sur le timer1 de 16MHz.

    Finalement je viens d'avoir l’idée de faire fonctionner le montage en compteur asynchrone

    J'initialise le timer à 0, je lance un délai de 10ms par exemple, et à la fin je récupère la valeur je multiplie par 100 et j'ai la fréquence.
    J'ai fait le truc un peu en tâtonnant.

    Ce qui l'embête est que l'entrée du compteur se fait sur RC0 (External clock from pin RC0/T1OSO/T13CKI (on the rising edge))
    et normalement est prévu sur cette broche le quartz de l'oscillateur (qui n'est pas utilisé ici (oscillateur interne))

    On peut sans doute améliorer les choses (trucs inutiles ou mal placés ?
    Merci de votre aide.

    Code:
    void main()
    {
    	ansel = 0x00;
    anselh = 0x00;
    	osccon=0xf0;
    	osctune=0x40;
    	FCD_SPI_Legacy0_SPI_Init();
    
    	while (1)
    	{
    		t1con.TMR1ON=0;// TMR1 désactivé
    		tmr1h=0;
    		tmr1l=0;
    		// configure le TIMER1
    		t1con.RD16=1;  //lecture mode lecture 2x8 bits
    		t1con.T1CKPS1=0;/
    		t1con.T1CKPS0=0;
    		t1con.T1SYNC=1;	// pas de synchronisation sur sleep/Reset	
    		t1con.TMR1CS=1;// compte les impulsions sur internal clock
    		t1con.TMR1ON=1;// TMR1 Activé
    		ccp1con=0x05;	// capture mode sur fronts montants
    		tmr1h=0;
    		tmr1l=0;
    
    		delay_ms(10);
    
    		PERIODEL=tmr1l;
    		PERIODEH=tmr1h;
    
    		PERIODE = (PERIODEH << 8) + PERIODEL;

  7. #6
    RISC

    Re : Mesure de fréquence avec ECCP1 sur PIC

    Salut,

    MODE 16 BITS
    Mon explication pour le TIMER1 en mode 16 bits est correcte, c'est justement comme cela que ca marche quand tu choisis RD16 = 1.
    Si tu ne choisis pas le mode 16 bits seul TMR1L ou TMR1H est lu donc si tu le fais l'un après l'autre tu as le risque de te faire pieger par un debordement entre les 2 : exemple le TIMER1 est a FFFF, tu lis TMR1L et tu obtiens FF, ensuite le TIMER1 s'incremente juste au milieu de tes lectures et devient 0000 et quand tu lis TMR1H tu lis 00. Resultat : tu as 00FF (c'est peut être ce qui t'es arrivé avant).

    FREQUENCE MAX
    J'ai écris un petit morceau de code base sur ton interruption modifiée suivant mon explication (FCM_ITCOMP) et la version desassemblee donne environ 90 cycles (Fcy) + 10 cycles pour la latence HW. Donc d'après mes calculs environ 100 x Tcy = 625ns. Tout cela en mode non optimisé du compilo C18
    Tu devrais donc être en mesure de mesurer un signal jusqu'à 800kHz (1,25us). Je ne sais pas ce que tu fai d'autre dans le main mais si cette interruption est récurrente cela pourrait être un peu chaud puisque la charge de l'interruption sera de près de 50% sur le processeur.

    Pour arriver a faire cela, il faut connaitre le compilo :
    * Mettre ton interruption en mode haute priorité
    * forcer toutes les variables utilisees dans l'interruption dans la zone "ACCESS" cela evite les changements de banque

    J'ai remarque que tes operations dans l'interruption pénalisent pas mal (notamment le décalage de 8bits).

    a+
    Dernière modification par RISC ; 01/05/2014 à 22h42.

  8. #7
    cubitus_54

    Re : Mesure de fréquence avec ECCP1 sur PIC

    Bonjour,

    J'avais aussi remarqué que lorsque la fréquence augmentait, le temps entre l'affichage de la partie haute et basse augmentait très fortement autour des 200kHZ (proche de la fréquence maxi).

    Finalement c'est tout bon, comme je l'avais dit précédemment j'ai laissé tombée l'interruption au profit du comptage. Finalement il n'y avait aucun problème puisque l'entrée de comptage est la broche T1OSO, l'oscillateur à quartz est sur les broches OSC1 OSC2.

    l'éclairement en lux = f/100, comme je mesure durant 10ms, je n'ai même pas à faire la division, la valeur est direct
    Je mesure de 1 à 8000 lux ce qui me convient parfaitement

    A+

Discussions similaires

  1. Mesure d'une fréquence
    Par invite94160da0 dans le forum Électronique
    Réponses: 3
    Dernier message: 30/09/2012, 16h05
  2. mesure de fréquence avec dsPIC
    Par invitef3ff390d dans le forum Électronique
    Réponses: 11
    Dernier message: 14/06/2012, 09h52
  3. mesure de frequence avec precision de 40ppm
    Par invite6fddc075 dans le forum Électronique
    Réponses: 0
    Dernier message: 23/04/2011, 10h53
  4. mesure de fréquence avec µC
    Par invitef56a0982 dans le forum Électronique
    Réponses: 5
    Dernier message: 06/03/2009, 08h21
  5. [PIC] Mesure d'une fréquence
    Par invite91ed4b59 dans le forum Électronique
    Réponses: 8
    Dernier message: 18/02/2007, 22h31
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...