Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From French to

Threaded View
Bonjour

Quelqu'un a t'il un bout de code pour un PIC pour mesurer la valeur de
l'impulsion issu d'une voie (récepteur de radiocommande) afin de
réaliser un asservissement perso.
Je vois un peu comment faire (sur interruption, mesure à l'aide du
timer de la largeur de l'impulsion ; je sais qu'il faut autoriser les
interruptions et peut être utiliser le prescaler ; je suppose qu'il
faut voir du coté des registres Intcon et Option_reg) , mais je
n'arrive pas  à traduire ça en  code. (je suis débutant total dans les
pics)

De préférence en C (pas d'ASM) ; ça serait pour un 16F628 et juste le
code pour mesurer cette impulsion, le reste, je m'en débrouille.

Merci.



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

4a243f0a$0$17749$ snipped-for-privacy@news.orange.fr...
Quoted text here. Click to load it
========
/* principe fonction   pour  mesure impulsion basse */
byte pulse_low() {   // fonction  retournant une valeur
  while(input(IRin));   // boucle d'attente tant que niveau haut
  set_rtcc(0);            //  debut niveau bas, compteur à zero
  delay_us(3);
  while(!input(IRin));   // boucle d'attente tant que niveau bas
 return(get_rtcc());    //  fin niveau bas  return resultat  du comptage
  }
L'armemnt  du timer0 (RTCC) depend du type du compilateur , voir ta notice
Bonne nuit



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

4a243f0a$0$17749$ snipped-for-privacy@news.orange.fr...
Quoted text here. Click to load it
en C on utilise le mot cle "interrupt" ce mot cle genere un rti au lieu d'un
rts, et il ne sert qu'a cela.
ne pas oublier de declarer les variables utilisees pour le traitement (fin
d'interruption, par ex, ou it traitee) en tant que "volatile"
ceci oblige le soft qui tourne (en dehors du traitement de l'it) de relire
cette variable.
le traitement de l'it doit etre le plus court possible, l'idee serait donc
de mettre une variable globale a 0 sur un front montant de l'it, de lancer
un timer, et une autre it sur le front descendant, qui lit la valeur du
timer, a voir suivant le pic, et le compilateur utilise.



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC
Il faudrait connaitre l'ordre de gandeur de la duree de cette
impulsion :
plutot de l'ordre de la microseconde, de la milliseconde, ou au-dela ?
Quand au code, ca depend du compilateur C que tu utilises, c'est
lequel ?
Certains compilateurs ont des macros qui rendent l'init des
interruptions
tres facile a ecrire, mais qui cachent les details d'initialisation
des registres,
et ce code n'est pas portable d'un compilo a l'autre et pas bon pour
apprendre.

Je ne connais pas le 16F628 mais le principe reste le meme pour les
uC.
Tu valides l'interruption d'overflow d'un timer ininterruptible,
dans cette interruption tu incrementes juste une variable
qui indiquera le nombre d'overflows eventuels que le timer a fait.
Le prediviseur de ce timer est a choisir en fonction de la duree de
l'impulsion que tu vas mesurer : plus l'impulsion sera courte, plus
le diviseur sera petit pour garder un increment faible, et
inversement.

Tu valides une interruption qui se declenche lors d'un changement
d'etat sur l'entree du PIC qui recoit l'impulsion :
quand cette impulsion se declenche sur le front montant,
tu mets a zero le compteur du timer ainsi que la variable associee.

Lors de la seconde interruption (front descendant) tu lis la valeur du
timer
(et de la variable) qui te donnent la duree de l'impulsion avec une
precision
de l'ordre de celle de ton quartz multipliee par les pre-diviseurs.

Le code pour la mesure (a traduire pour ton PIC) avec un timer 16
bits :


//-------------------------------------------------------

// definition de l'entree qui recoit le signal
#define ENTREE BIT_RB0 // exemple avec RB zero

// constantes
#define FQUARTZ  20000000 // frequence du quartz (ex: 20 MHz)
#define DIVISEUR 16 // pre-diviseur du timer (exemple)

// variables globales
unsigned long uTimer=0, uOverflow=0; // compteurs timer
float fValeur = 0.0; // valeur du timer
unsigned char flag=0; // flag de fin de mesure


// interruption du timer ---------------------------------
void interrupt timer(void)
{
   ++uOverflow; // increment du compteur d'overflows
}


// interruption de changement d'etat ---------------------
void interrupt change(void)
{
// etat logique de l'entree a cet instant
 if ( ENTREE ) // front montant
 {
   TIMER = 0; // reset du compteur du timer
   start_timer();  // demarrage de l'interruption du timer
 }
 else // front descendant
 {
   uTimer = TIMER; // lecture de la valeur actuelle du timer
   stop_timer(0);  // arret de l'interruption du timer
   flag = 1;       // mesure terminee
 }
}

// programme de fond -----------------------------------

void main(void)
{

 // inits
 preset_timer(DIVISEUR); // initialise les pre-diviseurs du timer

 while ( 1 ) // boucle principale
 {
   // inits
   uTimer = uOverflow = 0;  // remise a zero des compteurs
   flag = 0; // reset du flag de fin de mesure

   // mesure
   while( ENTREE ) ; // attend la fin de l'etat "un" sur l'entree
   start_change(); // demarrage de l'interruption de changement d'etat
   while( !flag ) ; // attend la fin de la mesure
   stop_change(); // arret de l'interruption de changement d'etat

   // affichage
   fValeur = (float)uTimer + (float)uOverflow * 65536.0; // valeur de
comptage
   fValeur *= (DIVISEUR / FQUARTZ); // conversion en secondes (ou ms,
ou us)
   print( "%f\n", fValeur ); // affichage de la valeur
   delay( ? ); // attente eventuelle pour l'affichage
 }

}


Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC
Réponse à tous.

D'abord merci d'avoir répondu.

Le PIC utilisé est un 16F628A (j'ai aussi un 16F877A)
J'utilise MikroC pour compiler (ai-je fais le bon choix ???)
J'ai sous la main la doc MikroC et les datasheets des composants cités.
La valeur à mesurer est comprise entre 0,8 ms et 2,2 ms.
Fréquence OSC = 4Mhz
Donc avec un timer sur 8 bits, il me faut utilser le préscaler (/8)
(sinon, il déborde à 255 µs ; OK ?
Avec un timer sur 16 bits, pas besoin du préscaler ; OK ?

Ma seule expérience avec les PIC en C et d'avoir fait jou jou avec des
leds et des boutons ainsi que la mise oeuvre d'un afficheur LCD (j'ai
démarré avec des exemples fonctionnels et j'ai modifié les programmes
afin d'obtenir des résultats plus "évolués"

Voilà.



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it

Ils se valent, a quelques subtilites pres, differences de facilite
d'utilisation, possibilite de cross-linker differents codes objets,
bonnes librairies, interface intuitive, etc ...
il n'y a pas de bon ou mauvais choix *a mon avis*
mais plutot des preferences personnelles.


Quoted text here. Click to load it

Oui, il deborde a 0xFF 3D% 255, mais ce ne sont pas des microsecondes,
parce-que l'increment temporel est (Freq_Osc / prescaler),
dans ton cas ca fait 4 MHz / 8 3D% 500 KHz 3D%> 2 uS par increment,
et multiplie par 256, le debordement se produira a 512 uS.


Quoted text here. Click to load it

Oui: 2,2 ms / 2 uS 3D% 1100 et dans ce cas tu pourras mesurer
des durees jusqu'a 131 ms, avec une precision de 2 uS.
Toujours sur 16 bits mais avec un prescaler de 1,
la precision sera de 250 nS et la mesure maxi de 16 mS.

Plus la valeur du prescaler sera petite,
plus la precision de la mesure sera grande.


Quoted text here. Click to load it

Alors tu as toutes les billes pour cette manip !

L'ideal serait de faire des tests avec un generateur de signaux
rectangulaires dont tu connais precisement les durees des crenaux,
comme ca tu peux valider les mesures faites par ton programme.

Ca pourrait meme etre une sortie du PIC que tu
reboucles physiquement sur l'entree de mesure.

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC
Jean-Christophe a émis l'idée suivante :

Quoted text here. Click to load it

Otez-moi d'un doute ; il y a bien un seul langage C pour les PIC
contrairement au basic où il y en a plusieurs ???



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it

La reponse a ta question est OUI, mais il faut
bien differencier les differents niveaux de code :

Le seul language que connaisse un uC ou un uP, c'est le code binaire
de ses instructions machine (qu'on ecrit en mnemoniques assembleur)
Le PIC ne connait pas le C, ni le Basic, ni aucun autre language
evolue,
c'est le travail du compilateur que de "traduire" le C en code ASM.

Pour ce qui est des compilateurs C, ils ont tous en commun de
reconnaitre et respecter les structures standard du C, donc un
programme ecrit en C sera plus portable qu'un programme ecrit en
Basic.

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it


... ou plus exactement en une suite d'octets que l'on représente
généralement sous la forme hexadécimale?
A moins qu'il existe des PICs a qui on peut faire ingérer directement de  
l'ASM?
(connais pas encore ces bestioles, mais ça m'intéresse)


Quoted text here. Click to load it

Absolument, et c'est ce qui rend ce langage intéressant.
Mais pour ma part, je n'ai jamais réussi à digérer la syntaxe très  
particulière du C.
Ce qui fait que, par fénéantise, je ne programme qu'en BASIC (BBC BASIC et  
HPBASIC).
A tort, puisque je ne peux pas vraiment "porter" mes applications vres la
plateforme wintel par exemple...


JLuc

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it


Ca c'est plutot le travail de l'assembleur.
Le compilateur transcrit le C en ASM (mnE9%moniques des instructions)
ensuite le programme d'assemblage transcrit l'ASM en code machine.


Quoted text here. Click to load it

Il y a eu le projet de realiser un microprocesseur dont les
instructions machine seraient directement du bytecode Java.
(chez Sun MicroSystems) Je ne sais pas si cela a ete fait.


Quoted text here. Click to load it

C'est pourtant un langage tres concis et puissant,
et la pratique d'un langage est juste une question d'habitude.
( ca fait un peu mal au debut, mais apres c'est bien ;-)

Par exemple, pour copier une chaine de caracteres, la fonction
strcpy() est implementee comme ceci:  while( *d++  3D%  *s++ );
On peut difficilement faire plus simple et plus concis !
Et il y a bien plus imbitable que le C, tu as deja
vu un programme ecrit en Pearl, en Teco ou en Lisp ?


Quoted text here. Click to load it

Basic 3D% "Beginner's All-purpose Symbolic Instruction Code",
ce qui montre qu'il s'agit d'un language assimilable tres
vite, ce qui est ideal quand on debute en programmation.
Mais ca reste un langage de debutant, et une fois qu'on
a bien digere les principes de base, pour aller plus
loin c'est tres sain de pratiquer d'autres langages.


Quoted text here. Click to load it

Quand tu concois un programme, tu as en tete son algorithme,
et c'est bien ca le plus important : l'algo est independant
du langage dans lequel tu l'implementes, tu peux donc
le transposer dans n'importe quel langage de ton choix.

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it
==========
Il n'y a pas qu'un seul langage C pour pic
Leur particularité commune est  que l'architecture générale du code source
est celle du "C" crée autrefois pour programmer simplement les ordinateurs.
Il sont tous différents , plus ou moins performants dans leur travail de
traduction en code exécutable par le PIC , plus ou moins onéreux .
Par exemple un compilateur C à plus de 4500 euros ht sera sans doute plus
performant que le MiKroC à 150 euros.




Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it


Il n'existe qu'un seul language C,
celui defini par Kernighan & Ritchie,
et dont l'evolution en C ANSI est duement
standardisee depuis 1988 par une norme ISO.


Quoted text here. Click to load it

Il s'agit donc toujours de C dans tous les cas,
alors d'ou sors-tu ces differents languages C ?


Quoted text here. Click to load it

Les performances d'un compilateur pour un language donne,
sont independantes de la structure du language lui-meme !

Tu confonds "language C" avec "compilateur C".

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC
Bonjour,

Cette manière de procéder me paraît un peu bizarre (certains diraient
bien moderne) !  Dans le cadre d'un développement, j'aurais tout
simplement connecté un oscilloscope pour observer le signal. N'importe
quel modèle bas de gamme ou d'occasion à trois sous convient pour cet usage.
Le signal issu de la voie est peut être plus complexe que ce vous pensez
et avec une "mesure" par PIC vous prenez le risque de grossières erreurs
d'interprétation.

Bonnes manips


Jean-François FOURCADIER


------------------------------------

HITS a écrit :
Quoted text here. Click to load it

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC
J.F. FOURCADIER a exposé le 03/06/2009 :
Quoted text here. Click to load it

Je ne comprend pas bien votre remarque, pourquoi cette manière de
proceder est t'elle bizzare ???

Quant au signal de sortie , je le connais parfaitement ; c'est un
signal variant de 1ms à 2ms avec une période de 20ms.
Pouvez-vous m'aider pour le bout de programme ? (en MikroC)

Cordialement.
Pat.



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC
Excusez moi, j'ai mal compris la question posée. J'ai été abusé par le
terme "mesure". Je comprends maintenant que vous voulez faire une
acquisition de la durée des impulsions pour un traitement.

cordialement,



HITS a écrit :
Quoted text here. Click to load it

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it

Je t'ai deja donne du code qui fait la mesure par interruption, mais
voici du code plus simple qui fait la mesure sans utiliser
d'interruption.

Ce code est compilable avec MikroC, puisque c'est du C !

Tu dois juste adapter ceci: (voir la doc du PIC et la doc MikroC)
1) Le (#define ENTREE) pour le port sur lequel tu entres le signal.
2) La fonction  init_timer()  que je ne connais pas sur ton PIC.
3) La fonction  printf()  pour l'affichage du resultat sur ton LCD





/************************************************
 Horloge OSC = 4 MHz
 Timer = 16 bits
 Prescaler = 1
 Le timer va s'incrementer toutes les 250 ns
 La duree mini de mesure sera de 250 ns
 et la duree maxi sera de 16,383 ms
************************************************/

// constantes
#define ENTREE     RA0    // signal sur le bit zero du port A
#define FACTEUR  4000    // 4000 fois 250 ns font 1 ms

// variables
unsigned long uDebut, uFin; // valeur du timer en debut et fin de
mesure
float fDuree; // variable flottante pour l'affichage en ms avec
decimales

// programme
void main(void)
{
  // initialisation
  init_timer(1); // initialise le timer 16 bits avec prescaler = 1

  // boucle principale
  while(1)
  {
    // mesure de l'impulsion
    while( !ENTREE ) ; // attend le debut de l'impulsion
    uDebut = TIMER;    // lit la valeur du timer au debut de
l'impulsion
    while(  ENTREE ) ; // attend la fin de l'impulsion
    uFin   = TIMER;    // lit la valeur du timer a la fin de
l'impulsion

    // calcul de la duree et conversion en millisecondes
    fDuree = (float)(uFin - uDebut) * FACTEUR;

    // affichage du resultat de la mesure
    printf( " duree = %f ms \n " , fDuree );

    delayMs(1000); // on attend une seconde pour lire l'affichage

 } // boucle principale

} // fonction main


Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

snipped-for-privacy@d31g2000vbm.googlegroups.com...
Quoted text here. Click to load it


et si le timer a fait un tour ?



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it

Et si tu lisais les specifications qu'il a donne ?

- Frequence OSC = 4 Mhz
- Valeur a mesurer de 0,8 ms a 2,2 ms.

Sur 16 bits a 4 Mhz on va au-dela de 16 ms,
le timer ne fera donc pas un tour complet.

J'ai aussi donne du code avec une variable 16 bits
incrementee par l'interruption d'overflow du timer.
Ca donne 32 bits qui couvrent plus de 17 minutes,
toujours avec une precision de 250 nanosecondes.

Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

snipped-for-privacy@l28g2000vba.googlegroups.com...
Quoted text here. Click to load it

comme ton timer n'est pas lance par interruption, il peut donc faire un tour
meme sur 16 bits

s ' il est rendu a 0xFFFE quand tu lis la valeur de debut, il sera passé par
0 quand ti liras la valeur de fin

on ne peut pas lancer le timer sur un front sur ces pics ?



Re: Mesure de la largeur d'une impulsion issue d'une voie d'un RC

Quoted text here. Click to load it

Oui tu as raison.

Quoted text here. Click to load it

Sur ce PIC la je ne sais pas, mais on peut toujours forcer
sa valeur a zero lors de la detection du front montant :

while( !ENTREE ) ; // attend le debut de l'impulsion
TIMER 3D% 0;            // force la valeur du timer a zero
while(  ENTREE ) ; // attend la fin de l'impulsion
uDuree 3D% TIMER;   // lit la valeur du timer
fDuree 3D% (float)(uDuree) * FACTEUR; // conversion en ms


Site Timeline