Bonjour,
Je suis entrain de fabriquer un fréquencemètre avec un Pic 18f4520 sur une carte Picdem2+, programmé en C sous Mplab.
Un petit montage avec un ne555 me permet d'obtenir un signal carré, que j'envoie sur la patte RC2 du Pic.
Pour mon application, je doit avoir une plage de fréquences comprise entre 15 KHz et 25 KHz, de forme carré, entre 0V et 5V.
Jusqu'ici tout va bien, avec RC2 en interruption, le Pic "receuille" le signal carré du ne555 et arrive à calculer sa fréquence.
Voici un petit aperçu (RS232):
#########################
Image hébergée sur serveur externe supprimée
Merci de suivre ces consignes
Le problème me diriez-vous ? C'est que je m'attendais en fait à avoir une meilleure résolution.
En effet quand je tourne le potentiomètre (ne555) pour modifier la fréquence, j'obtiens ceci :
#########################
Comme vous pouvez le constater, la précision est d'environ 2000 Hz, ce que je trouve beaucoup.
Voici le code :
Code:// mesure de période sur CCP1 (RC2) (TIMER1 et fonction capture) #include <stdlib.h> #include <delays.h> #include <USART.h> #include "ftoa.c" unsigned int duree=5555; // représente le comptage entre 2 fronts (5555) char maj=1; // indique qu'une nouvelle mesure est prête char chaine[6]; // pour itoa float freq; // sous programme d'interruption #pragma interrupt itcomp void itcomp(void) { unsigned static int ancien; if(PIR1bits.CCP1IF) // l'IT provient d'une capture sur RC2 { duree=CCPR1-ancien; // comptage entre les deux front ancien=CCPR1; // mémorise le CCPR1 actuel maj=1; // nouvelle mesure pr^te } PIR1bits.CCP1IF=0; //efface le drapeau d'IT } #pragma code interruption=0x08 void fontion (void) { _asm goto itcomp _endasm } #pragma code /* PROGRAMME DE SAUT DE LIGNE */ void Saut(void) // Programme de saut et retour de ligne { while(BusyUSART()); WriteUSART(0x0D); // Carriage Return while(BusyUSART()); WriteUSART(0x0A); // New Ligne } void main(void) { OpenUSART( USART_TX_INT_OFF & // Initialisation de l'USART (RS232) USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH,25); // configure PORTC CCP1 DDRCbits.RC2=1; // RC2/CCP1 en entree // configure le TIMER1 T1CONbits.RD16=0; // TMR1 mode simple (pas de RW) T1CONbits.TMR1CS=0; // compte les impulsions sur internal clock T1CONbits.T1CKPS1=1; // prédiviseur =1/8 periode sortie = 8uS T1CONbits.T1CKPS0=1; T1CONbits.T1SYNC=1; // pas de synchronisation sur sleep/Reset T1CONbits.TMR1ON=1; // TMR1 Activé // configure le mode capture sur le TIMER1 avec IT sur CCP1 T3CONbits.T3CCP2=0; // mode comparaison entre TMR1 et CCPR1 CCP1CON=0x05; // capture mode sur fronts montants PIE1bits.CCP1IE=1; // active IT sur mode capture/comparaison CCP1 RCONbits.IPEN=1; // Interruption prioritaires activées INTCONbits.GIE=1; // Toutes les IT démasquées autorisées while(1) { if (maj) { freq=1.0/(duree*8e-6); itoa(freq,chaine); Delay10KTCYx(1); putsUSART(chaine); // affiche duree putrsUSART(" Hz"); Saut(); maj=0; } } }
Ce code ne m'appartient pas, je l'ai modifié pour l'adapter à mon application.
Est il donc possible d'avoir une meilleure précision que cela et comment y remédier dans le code ?
Merci par avance de votre aide.
-----