<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
voila mon programme:
int8 compte = 0 ;
#int_EXT
void EXT_isr(void)
{ disable_interrupts(GLOBAL);
compte++ ;
enable_interrupts(GLOBAL);
}
void main(void)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(0, L_TO_H);
usb_init_cs(); //config car envoi par usb
while (TRUE)
{
usb_task();
usb_debug_task();
printf(usb_cdc_putc, " Le nombre d'impulsions est = %d\n\r", compte);
}
}
et voila le résultat
sauf que je rencontre un petit soucis.A chaque niveau haut, mon compteur s'incrémente donc OK.Mais le pb c'est qu'il affiche continuellement "Le nombre d'impulsions est ..." ; comment faire pour qu'il l'affiche seulement à chaque fronts montants?j'ai mis mon instruction "printf(usb_cdc_putc, " Le nombre d'impulsions est = %d\n\r", compte);" dans mon interruption mais sa ne marche pas...
help me please!!!
Rien de plus simpleCode:void main(void) { int8 iOldValue = -1; enable_interrupts(GLOBAL); enable_interrupts(INT_EXT); ext_int_edge(0, L_TO_H); usb_init_cs(); //config car envoi par usb while (TRUE) { usb_task(); usb_debug_task(); if(iOldValue != compte) { printf(usb_cdc_putc, " Le nombre d'impulsions est = %d\n\r", compte); iOldValue = compte; } } }
Pas étonnant qu'il affiche tout le temps le message puisqu'il est dans un boucle while, sans condition.
Une solution : l'afficher uniquement quand la valeur change.
edit : grillé par RicounetZapint8 compte;
int8 old_compte;
...
old_compte = -1;
compte = 0;
...
if (compte != old__compte) {
afficher message
old_compte = compte;
}
Dernière modification par sdec25 ; 10/02/2010 à 13h10.
Merci à vous deux
Re!!
J'ai à nouveau un problème mais différent cette fois ci :
Je souhaite réalisé un programme permettant de calculer la durée entre un front montant et un front descendant sur une entrée de mon PIC (PIN B0) à une fréquence quelconque grâce à un GBF. Pouvez me dire ce qu'il ne va pas dans mon programme, car il affiche des valeurs qui n'ont rien à voir.
unsigned int8 time;
#int_EXT
void EXT_isr(void)
{ disable_interrupts(GLOBAL);
while(!input(PIN_B0)); /* wait for signal to go high */
set_timer1(0);
while(input(PIN_B0)); /* wait for signal to go low */
time = get_timer1();
enable_interrupts(GLOBAL);
}
void main(void)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(0, L_TO_H); //interruption sur front montant
usb_init_cs();
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
do
{
usb_task();
usb_debug_task();
printf(usb_cdc_putc,"La duree entre 2 fronts est de %d\n\n\r", time);
} while (TRUE);
}
Merci d'avance
Je l'est un peu modifié mais il ne fonctionne toujours pas
unsigned int8 time;
unsigned int8 oldtime;
#int_EXT
void EXT_isr(void)
{ disable_interrupts(GLOBAL);
set_timer1(0);
while(input(PIN_B0)); // attente d'un niveau bas
time = get_timer1();
enable_interrupts(GLOBAL);
}
void main(void)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(0, L_TO_H);
usb_init_cs();
do
{
usb_task();
usb_debug_task();
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
if (oldtime !=time)
{
printf(usb_cdc_putc,"La duree entre 2 fronts est de %d\n\n\r", time);
oldtime = time;
}
else
{
printf(usb_cdc_putc, "Attente front montant... \n\r");
delay_ms(1000);
}
}
while (TRUE);
}
Il m'affiche des valeurs soit positives, soit négatives mais je ne sais pas à quoi elles correspondent!!
Merci de votre aide
Personnellement, je m'applique toujours pour avoir une durée de traitement de l'interruption la plus courte possible.
Donc, je ne ferais pas comme ça.
Dans la boucle principale, j'attends le changement d'état de l'entrée.
Je lance le timer
J'attends le nouveau changement d'état.
J'arrete le timer
Je lis la valeur
Le timer est configurer pour incrémenter une valeur à chaque interruption.
Connaissant la durée de ton timer, et le nombre d'interruption qui on été déclenché, tu connais le temps.
Concerant les valeurs négatives ou positive, on utilise le bit de poid fort pour indiquer le signe.
un signed char qui a pour valeur 0x81 sera traduit par -1
Si tu ne travailles pas avec des nombres négatif, utilises des unsigned char, ou unsigned int etc...
Cordialement
do
{
usb_task();
usb_debug_task();
while(input(PIN_B1)) ;
delay_us(3);
while(!input(PIN_B1));
set_timer1(0);
delay_us(3);
while(input(PIN_B1));
time = get_timer1();
printf(usb_cdc_putc, "Counter value: %d\n\n\r", time);
}
while (TRUE);
}
mais sa marche po!!!
Tu veux que quelqu'un fasse le programme à ta place ou le faire toi même ?
Si tu veux le faire toi-même, comment veux-tu qu'on t'apporte de l'aide si le seul diagnostic est "sa marche po" ?
Personnellement, quand quelqu'un demande de l'aide et n'analyse pas le problème je ne lis même pas le programme.
non mais je sais c juste que c ma liaison usb qui commence merder.je te dit ce qui ne va pas quand j'ai réglé ce problème...
Quand je laisse l'interruption, cela m'affiche :
La duree entre 2 fronts est 51
La duree entre 2 fronts est 63
La duree entre 2 fronts est 135
La duree entre 2 fronts est 3
ect...
Lorsque je met mes changements d'états dans ma boucle while, rien ne se passe, rien ne s'affiche...
faut-il vraiment que j'utilise le timer1?j'ai vu sur la doc qu'il retournait un entier de 16bit ; mais je ne peut pas déclare des entiers de 16bits à l'intérieur de mon printf?ça me met une erreur!!!alors qu'avec les entiers 8 bits ça marche!!
HELP ME please
merci d'avance
unsigned short time ou unsigned int16 time ça ne va pas ?
Quand je met unsigned int16 time, j'ai une erreur " Printf format type is invalid ::".
Quand je met unsigned short time, rien ne s'affiche...
Bizarre que tu ais une erreur pour un format de printf.
Essaie avec le format %u
C avec %u que j'ai essayé.
printf(usb_cdc_putc,"La duree entre 2 fronts est de %u\n\n\r", time);
Peut-être que cela est du à l'emploi de l'usb?
En fait quand je lance un timer, que je l'arrête et que je lis sa valeur, concrètement cela correspond à quoi?Enfin ceci ne résout pas mon problème car pour une même fréquence, il me trouve des résultats différents ;
Voici mon programme, si vous voyez d'où cela peut venir, merci de me tenir au courant
unsigned int8 time = 0;
unsigned int8 oldtime = -1;
#int_EXT
void EXT_isr(void)
{ disable_interrupts(GLOBAL);
set_timer1(0); // mettre timer1 à 0
while(input(PIN_B0)); // attente d'un changement de niveau
time = get_timer1(); // on récupère la valeur de timer1
enable_interrupts(GLOBAL);
}
void main(void)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(0, L_TO_H);
usb_init_cs();
do
{
usb_task();
usb_debug_task();
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
if (oldtime !=time)
{
printf(usb_cdc_putc,"La duree entre 2 fronts est de %u\n\n\r", time);
oldtime = time;
}
}
while (TRUE);
}
Bonjour,
Ce n'est quand même pas trop compliqué, cela s'appelle le débordement et ça peut causer de gros soucis (Demande à Arianne Espace )
Si ton timer est à une fréquence de 1 kHz, il va incrémenter ton compteur toutes les 1 ms.
Tu déclares un int8, donc un champ qui peut varier de 0 à 255, (0x00 à 0xFF)
Lorsque ton compteur arrive à 255, si tu rajoutes 1, il repasse à 0 (0xFF + 0x01 = 0x0100 qui codé sur 1 octet donne 0x00)
Donc, si tu as un signal de période 256 ms, ton compteur t'indiquera 1.
Concernant le problème de communication USB, je ne connais que le stack Microchip, mais il est clairement indiqué qu'il faut appeler la fonction USB_Device_Task de façon périodique.
Si tu bloques ton programme pendant trop longtemps, tu risques de perdre la communication.
Cordialement
Salut,C'est exactement cela...il faut qu'elle soit appelée au moins toutes les ms...et il faut tester des sémaphores avant d'appeler certaines API pour faire les accès aux bons moments dans les Endpoints.Concernant le problème de communication USB, je ne connais que le stack Microchip, mais il est clairement indiqué qu'il faut appeler la fonction USB_Device_Task de façon périodique.
Si tu bloques ton programme pendant trop longtemps, tu risques de perdre la communication.
Cordialement
a+
Bonjour,
Finalement, j'utilise 2 interruptions différents.J'ai à peu près compris l'histoire des débordements, mais étant donné que je réinitialise mon Timer à chaque fois, les débordements devraient toujours être les mêmes,non?
unsigned int8 time = 0;
unsigned int8 oldtime ;
#int_EXT
void EXT_isr(void)
{ disable_interrupts(GLOBAL);
set_timer1(0); // mettre timer1 à 0
enable_interrupts(GLOBAL);
}
#int_EXT1
void EXT1_isr(void)
{ disable_interrupts(GLOBAL);
time = get_timer1(); // on récupère la valeur de timer1
enable_interrupts(GLOBAL);
}
void main(void)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
ext_int_edge(0, L_TO_H);
ext_int_edge(1, H_TO_L);
setup_timer_1(T1_INTERNAL|T1_D IV_BY_2);
set_timer1(0);
usb_init_cs();
do
{
usb_task();
usb_debug_task();
if(oldtime !=time)
{
printf(usb_cdc_putc,"La duree entre 2 fronts est de %u\n\r", time);
oldtime=time;
}
}
while (TRUE);
}
Merci d'avance
je galère...
Bon normalement j'ai trouvé...il me reste juste un petit problème d'équation : lorsque j'affiche la valeur de mon Timer1,(avec une fréquence de 1Hz en entrée), mon programme m'affiche environ 39080.Quelle est l'équation qui me permettrait de retrouver mes 1s (car 1Hz en entrée)?
Merci de vos réponses
Bonjour,
Tu as une fréquence d'horloge du PIC : FOSC (ex : 4 Mhz)
La fréquence du timer sans prescaler est FOSC/4 (ex : 1 Mhz)
Si tu as un prescaler de n, la fréquence est f_timer = FOSC/4/n
La valeur lue (39080) est le nombre d'impulsions du timer à la fréquence ci-dessus pendant un temps t.
Pour avoir le temps correspondant : t = nb_impulsions / f_timer
La fréquence du signal est 1/T (avec T = temps d'un front montant à l'autre front montant).
Re bonjour tout le monde.
Afin de ne pas ouvrir un doublon, je fais un petit up sur celle-ci.
J'ai de nouveau un problème ; j'arrive donc à calculer la durée entre deux fronts d'un signal carré.
Le problème, c'est que je me servais de 2 entrées de mon PIC ==> l'une autorisait les interruptions sur un front montant et l'autre sur front descendant.
Je déclenchait puis arrêtait mon Timer sur chacune des interruption.
Je veux à présent me servir d'une seule entrée
Je réalise une interruption sur front montant et je lance mon Timer.
Quand faut-il que je l'arrête?Dans l'interruption?Dans le programme principal?
merci de vos réponse
tchou
re,
Si je comprends bien tu veux utiliser une interruption uniquement sur front montant.
Tu veux mesurer le temps entre 1 front montant et 1 front descendant, ou entre 2 fronts montants ?
Si c'est entre 1 front montant et 1 descendant, je vois 2 solutions :
- Changer le sens de l'interruption
- Faire de l'attente active dans la fonction principale (autant ne pas utiliser les interruptions du tout)
Ce serait entre 2 fronts montants, je pense que ce serait plus simple mais je ne vois pas comment faire.