Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
adrienc45
Débutant
Débutant
Messages : 27
Enregistré en : octobre 2015

#11 Message par adrienc45 » ven. 23 oct. 2015 22:07

le problème c est que si je comprends bien , une interruption intervient suite a un événement qui se déroule ( ça dépend de la programmation que l on en fait )

donc sa veut dire que je vais avoir un calcul de ma période signal pour chaque période du signal par exemple ..alors que moi je veux effectuer ce calcul seulement lorsque j en ai besoin dans le programme , d ou l utilisation d un sous programme que j appelle quand je veux

c est pour ca que je me sers des flags des interruptions dans le sous programme qui me servira a calculer la période du signal et me retournera la valeur en sortie , seulement que j appellerais ce sous programme .



oui mais l' ensemble d' instructions as lieu âpres avoir stocke la variable timer0 et dep , donc le moment auquel je vais exécuter ce bloc d instructions n as pas d influence sur ma durée de période qui as été capturée ? non ?

j ai réussi a régler le problème d incertitude sur mes mesures , ayant observe un erreur relative de 2% sur la mesure de période j ai applique un coefficient correcteur de 0.98 sur ma période , de cette manière je n ai plus de problème de cette ordre la c est déjà un petit pas :)

pour 250 hz donné , donne 250 hz mesure
pour 10 hz donne , 10 hz mesure
entre 10 et 250 hz , pareil car la loi d Evolution étant une fonction linéaire

mais pourquoi une mesure impossible en dessous de 10 hz je ne comprends pas .. peut être que mes variables sont pas assez grandes pour stocker le nombre d incrémentations ( tout les 0.4 us ) qui est très grand pour une grande période mesure forcement ....


en ce qui concerne les variables utilises et leurs tailles respectives , j ai été au plus économique ...
que me conseillez vous en ce qui concerne ce point précis ?

voici mon code a l heure actuelle qui fonctionne donc , qui est précis ( relativement par rapport a l application que je compte en faire ) grâce au coefficient correcteur sur la valeur de période tire de mes observations et pour palier au problème d instructions qui allongent la valeur réelle de période

mais qui ne fonctionne toujours pas sous 10 hz ...je cherche pourtant ..

d ailleurs sa déconne aussi pour des très hautes fréquences mais ça c est due au fait que la simulation n est pas en capacité d être effectue correctement au vu des performances de mon pc portable ..... il me sort l erreur souvent quand je lui en demande trop humour!!

Code : Tout sélectionner

// CHAINE DE MESURE

 /*PROGRAMME qui as pour but de calculer la periode d ' un signal applique sur l entree int/rb0
  d ou l utilisation du timer0 pour calculer le temps entre deux fronts montant donc de la periode du signal envoyé en entrée  */
/* avec cette configuration prescaler a 1 pour wdt(  wdt pas utilisee ) donc 1:2 pour timer0 et horloge ext (20 mhz/4) pour timer0 , on aura temps entre deux
incrementations du timer0 = 0.4 microsecondes */

//
float per_tim0 0.0000004// temps entre deux incrementations du timer0 =  0.8 microsceondes ( fosc/4 plus prescaler 1:8 )(32 bit)
unsigned short int a=0;         //   variable qui sert de condition test sortie de boucle des que l on as acqui notre periode(8 bit)
unsigned long int dep;       // variable qui stocke le nombre de depassements ayant eue lieu durant le comptage durant une periode
unsigned short int timer0;    // variable qui stocke la valeur du registre tmr0 en sortie de la boucle de mesure de la periode ( 8 bit )
unsigned long int tempstotal// variable qui represente le nombre total de fois ou le registre tmr0 s est incrementé entre deux fronts montant sur rb0 (32 bit)
float periode;  // variable qui represente la periode du signal apres multiplication du nombvre d incrementations par le temps entre deux incrementatons d horloge(32 bit)
unsigned int frequence// frequence est l inverse de la periode(16 bit )

void main()           // boucle principal pour mesure periode signal sur rb0
{


      
ANSEL  0;  // I/O en digital.
      
ANSELH 0;  // I/O en digital.

      
TRISB.B0 =1;   // pin rb0/int est declare en entree pour l acquisition du signal

      
TRISC =0b00000000;  // portc decalre en sortie logique pour l affichage du resultat
      
TRISD =0b00000000;  // portd decalre en sortie logique pour l affichage du resultat

      
OPTION_REG 0xC0;  //bit7-> RBPU=1 (off), bit6 -> INTEDG=1 (front montant)
                         //bit5-> T0CS=0 (fosc/4), bit4-> TOSE=0
                         //bit3-> PSA=0 (prescaler timer0), bit<3:0> 000 -> timer0 rate 1:2
                         // => OPTION_REG=0b11000000=0xC0
      
GIE_bit 1;
      
INTE_bit 1;      // on va utiliser le drapeau qui signale l interruption a chaque front montant du signal appliqué sur int/rb0
      
T0IE_bit 1;      // on va utiliser le drapeau qui signale l interruption a chaque debordement du timer0 ( on les comptabilise dans le programme)
      
      
PORTC 0x00;   //  portc et portd parametres en sortie pour afficher nombre en binaire de la frequence trouvé en fin de programme
      
PORTD 0x00;   //



      
              
INTE_bit 0;     // autorisation de l utilisation de l interruption pour l evenement sur rb0/int
              
T0IE_bit 0;     // autorisation de l utilisation de l interruption pour l evenement depassement regsitre tmr0
              
T0IF_bit 0;     // initialisation du drapeau du depassement du regsitre TMR0

              
periode  tempstotal frequence dep 0// initialisation des variables de stockage avant le calcul

             
Delay_ms(5000);
             do          
// on reste dans cette boucle tant que l on as pas acquis le temps d une periode
             
{
                        if(
INTF_bit==0)
                        {
                                     
a=0;    // le comptage de la periode commance seulement des que l' on detecte le premier front montant si non on reboucle tant que
                        
}
                        if(
INTF_bit==1)      // le comptage de la periode peut commencer car on as detecte le premier front montant
                        
{
                                    
TMR0 0;
                                    
INTF_bit 0;
                                    do
                                    {

                                                 if(
T0IF_bit == 1)    //  boucle quidurant le comptage de la periode , comptabilise les debordement du timer0
                                                 
{
                                                          
dep=dep+1;
                                                          
T0IF_bit0;
                                                 }
                                                 
                                    }while(
INTF_bit == 0); // on sort des que l on capte le second front montant sur rb0 ; correspond a fin de mesure de periode
                                    
timer0 TMR0;
                                    
INTF_bit 0;
                                    
tempstotal dep 256 timer0;   // calcul nombres d incrementations en tout durant la periode , debordements multiples compris
                                    
periode tempstotal*per_tim0// calcul periode du signal en secondes
                                    
periode periode*0.98;
                                    
frequence periode;    // calcul frequance signal en hz
                                    
1// condition de sortie de la boucle de mesure
                         
}

              } while(
a==0);   // on sort de la boucle de mesure car on est parvenu a acquerir l info de frequence du signal sur rb0

             
PORTD frequence;         // On envoie les 8 bits de points faibles sur le port D
             
PORTC frequence >> 8;    // On fait un décalage des 8 bits de poids faibles pour faire apparaitre les 2 bits de poids fort restant sur le PORTC


Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#12 Message par paulfjujo » sam. 24 oct. 2015 11:03

bonjour,



Attention!! tu persistes à armer les interruptions alors que tu n'as pas de "Traitement d'interuption" !
On ne résoud pas un probleme avec un coefficient (0.98)...

et tu ne tiens pas compte des remarques que l'on te fait ..

donc exit
Aide toi, le ciel ou FantasPic t'aidera

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
adrienc45
Débutant
Débutant
Messages : 27
Enregistré en : octobre 2015

#13 Message par adrienc45 » sam. 24 oct. 2015 22:24

le problème c est que je ne comprends pas comment définir l action a réaliser en cas d interruption ...
et comment déclencher cette fameuse interruption( mon calcul de période ) quand je le veux et non pas quand le programme en as décide par lui même ...

si vous avez des docs a me conseiller pour éclaircir ce point j accepte volontiers :oops:

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
mazertoc
Passioné
Passioné
Messages : 201
Enregistré en : juillet 2015
Localisation : Auvernha

#14 Message par mazertoc » sam. 24 oct. 2015 23:15

adrienc45 a écrit :comment déclencher cette fameuse interruption( mon calcul de période ) quand je le veux et non pas quand le programme en as décide par lui même ...
si vous avez des docs a me conseiller pour éclaircir ce point j accepte volontiers :oops:

J'ai l'impression que tu ne comprend pas le fonctionnement des interruptions.
Commence à les utiliser dans un programme très simple (allumer une led par exemple).

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
adrienc45
Débutant
Débutant
Messages : 27
Enregistré en : octobre 2015

#15 Message par adrienc45 » dim. 25 oct. 2015 00:11

Je vais effectivement étudier cela d un peu plus prêt , vu que ce n est pas très clair exit

par contre , sa ne me dit toujours pas pourquoi mon programme fonctionne , mais refuse de mesurer des fréquences inférieures a 10hz :roll:

Sur ce , bonne soirée a vous ! Merci !

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#16 Message par Jérémy » dim. 25 oct. 2015 10:18

Hello adrien,

Je pense aussi que tu n'as pas tout compris sur les interruptions .

Une interruption se déclenche a tous moment dans un programme . Lis ou Relis le TUTO

Il y as plusieurs façon de calculer une fréquence . voila 2 pistes :

Tu détermine une plage de temps toit même genre pendant 1 seconde, je mesure le nombre de front montant. Etant donné que c'est toi qui fixe la plage de temps pas besoin de t’embêter avec le TMR0 ( sauf si tu t'en sert pour faire la base de temps d'une seconde , ce que je conseille).

Donc si pendant ta seconde tu as 10 fronts montants , il te reste simplement a en déterminer la fréquence. Avec cette méthode suivant la valeur de la frequence il peut y avoir des approximations . si part exemple la seconde débute juste après un front montant et s’arrête juste avant un front montant tu loupe deux fronts montants ( ou presque) . Donc tu peut tabler sur une approximation à deux fronts montant prêt ;si tu as 100000 fronts montants les deux erreurs seront transparentes, si tu en as 10 , elles seront bien visibles ! .

Je pense que cette méthode est la plus simple et fiable , mais plus approximative . Je te conseille de faire d'abord ce premier programme plutôt simple

La deuxième consiste a compter réellement le nombre d'instruction entre deux fronts montants.
Pour ce faire , je te propose ceci .

L’arrivée d'un front montant , remets à zéro le TMR0. Je rappelle que le timer0 compte en permanence le nombre d'instructions.

L'arrivée d'un deuxième front montant . enregistre la valeur du TMR0. Le nombre d’instructions sera égale à
(Valeur TMR0 à l'arrivée) - (Valeur TMR0 au départ) = Nombre d'instructions

Comme on avait remis à 0 le TMR0. la valeur du TMR0 sera = aux nombres d'instruction.

Suivant la fréquence de ton programme, tu connais le temps d'une instruction que tu multiplie par le nombre d'insrcutionet tu obtiens le temps entre deux fronts montants et Donc ta période .
Image


A toi de jouer !!! Bip nous si tu as des questions !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#17 Message par paulfjujo » dim. 25 oct. 2015 16:01

adrienc45 a écrit :Source du message quand je le veux et non pas quand le programme en as décide par lui même ...


:roll: tu as trop regardé Terminator .. et la guerre des machines .

Le programme c'est quand meme TOI qui le fait .. et il fera ce que TU lui dit de faire .
Et quand bien meme il ferait (ton sous programme d'interruption) le boulot d'une maniere quasi autonome et ransparente,
c'est bien toi qui decidera d'afficher ou pas ce resultat.
Aide toi, le ciel ou FantasPic t'aidera

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
adrienc45
Débutant
Débutant
Messages : 27
Enregistré en : octobre 2015

#18 Message par adrienc45 » dim. 25 oct. 2015 19:54

La deuxième consiste a compter réellement le nombre d'instruction entre deux fronts montants.
Pour ce faire , je te propose ceci .

L’arrivée d'un front montant , remets à zéro le TMR0. Je rappelle que le timer0 compte en permanence le nombre d'instructions.

L'arrivée d'un deuxième front montant . enregistre la valeur du TMR0. Le nombre d’instructions sera égale à
(Valeur TMR0 à l'arrivée) - (Valeur TMR0 au départ) = Nombre d'instructions

Comme on avait remis à 0 le TMR0. la valeur du TMR0 sera = aux nombres d'instruction.

Suivant la fréquence de ton programme, tu connais le temps d'une instruction que tu multiplie par le nombre d'insrcutionet tu obtiens le temps entre deux fronts montants et Donc ta période

Bonjour

Merci de vos réponses .

la seconde maniere de faire , c est la même procédure que mon programme a moi , mais en utilisant la " vrai " utilité des interruptions et non pas en faisant du pooling sur les drapeaux d interruptions , méthode grossière que j ai utilise moi si je comprends bien ?

la première méthode citée me permettra d avoir un rafraîchissement sur la valeur de période mesure au plus faible de 1 seconde ( largeur de la " fenêtre de mesure ") , cela ne me convient pas car trop long pour l utilité que je vais en avoir , mais rien ne m empêche de mettre en oeuvre l exercice effectivement .

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
adrienc45
Débutant
Débutant
Messages : 27
Enregistré en : octobre 2015

#19 Message par adrienc45 » dim. 25 oct. 2015 20:29

adrienc45 a écrit :Je vais effectivement étudier cela d un peu plus prêt , vu que ce n est pas très clair exit

par contre , sa ne me dit toujours pas pourquoi mon programme fonctionne , mais refuse de mesurer des fréquences inférieures a 10hz :roll:

Sur ce , bonne soirée a vous ! Merci !



A titre d inforamtion si je pouvais avoir une reponse a cela quand meme ;)

merci

Calcul période signal créneau (amplitude 0-5v) avec pic 16f887
adrienc45
Débutant
Débutant
Messages : 27
Enregistré en : octobre 2015

#20 Message par adrienc45 » dim. 25 oct. 2015 21:06

je commence a saisir doucement l utilisation de l interruption

comme vous me l avez conseille j ai commencé par un truc simple pour mettre en oeuvre les interruptions , le clignotement d une LED

j ai donc réussi a faire clignoter une sortie du uc en changeant son état a chaque front montant sur rbo/int

voir fichier proteus et mikro c en pj ;)

que en pensez vous ?

je sais sa parait surement idiot pour vous mais moi je suis heureux :mrgreen:

en attente de vos réponses a mes messages , je vous remercie

bonne soirée

Adrien

tentat.rar
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 44 invités