ok, dans ce cas tu démarres ton timer dans la routine d'interruption et tu l'arrêtes aussi dans la routine d'interruption.
-----
ok, dans ce cas tu démarres ton timer dans la routine d'interruption et tu l'arrêtes aussi dans la routine d'interruption.
J'y avais pensé, mais comment faire. Je veux dire dans ma routine d'interruption :
#int_EXT // correspond à une interruption sur RB0
void EXT_isr(void)
{ disable_interrupts(GLOBAL);
set_timer1(0); // mettre timer0 à 0
enable_interrupts(GLOBAL);
}
Quand est-ce que j'arrête mon timer?
Parce que là mon timer va être lancé sur un front montant mais il faut également qu'il s'arrête sur un front montant...
C'est sur ce point que je bloque...
Comme ça :
Sans utiliser de variable globale tu peux savoir que le timer est lancé en lisant un bit dans le registre de config du timer.Code:volatile int timerLance = 0; #int_EXT // correspond à une interruption sur RB0 void EXT_isr(void) { disable_interrupts(GLOBAL); if (timerLance) { // On arrête le timer (on peut éventuellement mémoriser ici la valeur du timer) timerLance = 0; } else { // on démarre le timer timerLance = 1; } enable_interrupts(GLOBAL); }
Quel lien y a t-il entre timerLance et mon Timer?Parce que timerLance est juste définit comme un entier mais il n'y a pas de liens entre les 2.
Cela peut-il marcher?En revanche, je bloques pas mal avec ce timerLanceCode:#int_EXT // correspond à une interruption sur RB0 void EXT_isr(void) { disable_interrupts(GLOBAL); if (timerLance) { time = get_timer0(); flag = 1; // si flag=1, dans le main on récupère la valeur } else { set_timer0(0); // mettre timer0 à 0 } enable_interrupts(GLOBAL); }
Euh le lien doit se faire manuellement (on change la variable quand on lance ou arrête le timer, cf. les commentaires que j'ai mis dans le code).
A quoi sert ton flag ?
Si tu expliquais précisément ce que tu veux faire ?
Bonsoir,
pour informations un petit exemple fonctionnel en "pseudo-code" :
qui affiche le temps en µs entre deux impulsions sur RB0...Code:word temps = 0 void interruption // INT RB0 ( temps = TMR1H * 256 temps = temps + TMR1L TMR1H = 0 // re-init val. TMR1L = 0 // re-init val. re-active INT RB0 ) void main ( active TMR1 active INT RB0 // Le programme principal... while true ( affiche(temps + "µs") ) )
temps en µs avec FOsc = 4Mhz...
temps maximum mesurable avec Prescaler = 1 : 65,5ms (@4Mhz)
et avec une précision théorique de 1µs...
vede
;O]
__________________
...
re!
Ce que je veux faire c'est mesurer des périodes ; je ré-explique.Un composant va envoyer en continu à mon PIC un signal qui comprend 5 périodes différentes.Le but est de mesurer chaque période (entre chaque front montant) pour ensuite pouvoir les traiter.Mais je ne vois pas trop comment faire...
c'est ce que fait mon code dans le post précédent...
il "mesure" la période entre 2 front montants sur RB0...
en boucle...
où est le problème?
rere ;O]
petites corrections :
et il y aura un décalage constant d'environ +12µs...Code:// 16F-18F / 4Mhz / Fuses : HS, _ALL_OFF word temps = 0 byte TEMPH, TEMPL = 0 void interruption // sur INT RB0 ( TEMPH = TMR1H TEMPL = TMR1L temps = TEMPH * 256 temps = temps + TEMPL TMR1H = 0 TMR1L = 12 // étalonnable à la µs ici... INTCON.INTF = 0 // reactive interruption RB0 ) void main ( ADCON0 = 0 //ADC_OFF ADCON1 = 7 //ADC_OFF TRISB.0 = 1 // RB0 IN T1CON = %000001 //active TMR1 avec PreScaler=1 INTCON = %10010000 //active interruption sur RB0 // Le programme principal... while true ( affiche(temps + " µs") ) )
étalonnable en initialisant TMR1L entre 10 et 20...
et on peut donc mesurer des périodes d'environ 20µs à 65535µs...
ce avec une précision de 1µs...
vede
;O]
_____________________
...
Edit : j'ai écris des bêtises ;O] correction :
et il y aura un décalage constant de maximum +/- 5µs...
étalonnable en initialisant TMR1L entre 10 et 20...
et on peut donc mesurer des périodes d'environ 20µs à 65535µs...
ce avec une précision de 1µs... si étalonné... +/-5µs sans...
vede
;O]
_____________________
...
pour finir, correction interruption:
Code:void interruption // sur INT RB0 ( TEMPH = TMR1H TEMPL = TMR1L temps = TEMPH * 256 temps = temps + TEMPL while PORTB.0 = 0 wend // attente prochaine impulsion TMR1H = 0 TMR1L = 12 // étalonnable à la µs ici... INTCON.INTF = 0 // reactive interruption RB0 )
code final et corrigé:
Code:// 16F-18F / 4Mhz / Fuses : HS, _ALL_OFF word temps = 0 byte TEMPH, TEMPL = 0 void interruption // sur INT RB0 ( TEMPH = TMR1H TEMPL = TMR1L TMR1H = 0 TMR1L = 12 // étalonnable à la µs ici... INTCON.INTF = 0 // reactive interruption RB0 ) void main ( ADCON0 = 0 //ADC_OFF ADCON1 = 7 //ADC_OFF TRISB.0 = 1 // RB0 IN T1CON = %000001 //active TMR1 avec PreScaler=1 INTCON = %10010000 //active interruption sur RB0 // Le programme principal... while true ( temps = TEMPH * 256 temps = temps + TEMPL affiche(temps + " µs") ) )
merci beaucoup vede je vais essayer de comprendre ton code
quand je compile, il ne reconnais pas TMR1H et TMR1L ; faut-il les définir?
En fait ce que je voulais savoir, c'est comment définir l'instruction "si le timer0 est lancé, alors...".Je voulais essayer de continuer mon code.La routine d'interruption était la suivante :
C'est ce bout ce code que j'aurais voulu convertir mais pour l'instant en vain...Code:#int_EXT // correspond à une interruption sur RB0 et front montant void EXT_isr(void) { disable_interrupts(GLOBAL); if (timerLance) //si mon timer est déjà lancé { flag = 1; // on met le drapeau à 1 (ce qui va réaliser des instructions dans le main) } else { set_timer0(0); // initialiser timer0 à 0 } enable_interrupts(GLOBAL); }
J'ai réalisé un autre bout de code :
En revanche, je n'est rien qui s'affiche...Code:unsigned int16 time = 0, flag=0 ; #int_EXT // correspond à une interruption sur RB0 void EXT_isr(void) { disable_interrupts(INT_EXT); time = get_timer0(); // on récupère la valeur de Timer0 set_timer0(0); // initialiser timer0 à 0 flag = 1; // on met le drapeau à 1 flag = 0; enable_interrupts(INT_EXT); } void main(void) { int tableau[5]; unsigned int8 mille = 1000 ; float resultat, dureecycle = 0.0000213, resfinal ; enable_interrupts(GLOBAL); enable_interrupts(INT_EXT); // autorise les interruptions sur RB0 ext_int_edge(0, L_TO_H); // déclencher interruption0 sur front montant setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); // configuration du Timer0 usb_init_cs(); //configuration de la liaison usb do { usb_task(); //configuration de la liaison usb usb_debug_task(); //configuration de la liaison usb if (flag == 1) { time = get_timer0(); // on récupère la valeur de Timer0 for (time = 0 ; time < 5 ; time ++) { tableau[time] = time ; printf(usb_cdc_putc, "%lu \n", time); //printf(usb_cdc_putc, "en attente...\n\r" ); //resultat = time * dureecycle ; //resfinal = resultat * mille ; //printf(usb_cdc_putc, "duree : %4.6f \n\r", resfinal); } } } while (TRUE); }
Je pense avoir un problème avec ma routine d'interruption ; en effet,j'ai fait beaucoup de test de programme basique et rien ne fonctionne ; exemple :
Je ne vois pas d'où peut venir le problème étant donné que dans ma routine d'interruption, il y a juste "flag = 1;".Code:#int_EXT // correspond à une interruption sur RB0 void EXT_isr(void) { disable_interrupts(INT_EXT); //time = get_timer0(); // on récupère la valeur de Timer0 //set_timer0(0); // initialiser timer0 à 0 flag = 1; // on met le drapeau à 1 //flag = 0; //enable_interrupts(INT_EXT); } void main(void) { enable_interrupts(GLOBAL); enable_interrupts(INT_EXT); // autorise les interruptions sur RB0 ext_int_edge(0, L_TO_H); // déclencher interruption0 sur front montant setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32); // configuration du Timer0 usb_init_cs(); //configuration de la liaison usb do { usb_task(); //configuration de la liaison usb usb_debug_task(); //configuration de la liaison usb if (flag == 1) { printf(usb_cdc_putc, "flag a 1..."); } else { printf(usb_cdc_putc, "flag a 0..."); } } }
J'attends vos réponses avec impatience.
Merci d'avance
Bonjour,
quel problème?
ça affiche "flag à 0"?
c'est que l'interruption n'a pas eu lieu...
je commence à être perdu...
avec des lignes comme :
flag = 1; // on met le drapeau à 1
flag = 0;
....
à quoi ça sert de le mettre à 1 si c'est pour le mettre à 0 dans la foulée????
vede
;O]
________________
...
re ;O]
je me rends compte que je suis allé trop vite avec mes exemples...
pour assilimer les principes (timer, int...), il faut commencer par
un programme simple afin de les maîtriser... avant d'aller plus loin...
donc le "hello world" électronique, c'est de faire clignoter une led...
à différentes fréquences...et ici en utilisant timer et interruptions...
c'est comme ça que je fais pour comprendre...
un de mes récents exemples dans le post #18 de ce fil:
http://forums.futura-sciences.com/el...pic16f690.html
ps :
c'est quoi ce compilo de m.... qui renommes tous les registres du PIC????
car c'est vraiment illisible... rapports aux autres et surtout aux datasheets...
un conseil :
orientes toi vers MikroC (gratuit jusqu'à 2Ko de code... là on en est encore loin...)
ou C18... ou HTC... enfin un compilo plus "sérieux"...
Bonjour vede,
J'ai enfin réussi à faire fonctionner un programme qui stocke mes 6 valeurs de période dans un tableau. Le problème maintenant est qu'il faut que je manipule ces variables, afin par exemple de trouver la plus petite, la plus grande,...Sais-tu comment faire?
merci bonne journée
Les tableaux en C
Trouver le maximum d'un tableau non trié :
Code:int i; int max = 0; for(i=0; i<nb_elements; ++i) { if (tab[i] > max) max = tab[i]; }
Ce bout de code ne fonctionne pas ; il me donne une valeur qui correspond à la durée totale de mon signal et non pas de ma plus grande valeur.
Hi,
si, le code de SDEC25 fonctionne...
après la boucle, la variable max contient obligatoirement
la valeur maximum trouvée dans le tableau...
max est en 8 bits(int) ou 16 bits(word)?
et les éléments du tableau?
si tu peux, envoyes le code complet, ça sera plus clair...
et t'as un lien vers la doc de ton compilo?
(pour trier des tableaux il existe parfois des fonctions (sort, asort, rsort, min, max, ...))
vede
;O]
______________
...
ps : pour l'exemple de SDEC, aprés tu met l'élément max à 0, cad tab[max] = 0,
et tu recommences le test pour trouver max-1... récursivement...
re-ps :
>J'ai enfin réussi à faire fonctionner un programme qui stocke mes 6 valeurs de période dans un tableau
-comment tu sais que c'est les bonnes valeurs ????
(que les valeurs correspondent bien aux périodes injectées)
envoyes tout le code, tel que tu le compile, on avancera plus vite...
rere-ps :
http://www.google.fr/search?client=f...cherche+Google
_____________________
use the best ;O]
Hi vede
Voici mon code
Les valeurs que j'obtiens correspondent bien aux différentes valeurs des périodes j'ai calculé.Code:unsigned int16 time = 0, compte = 0; #int_EXT // correspond à une interruption sur RB0 void EXT_isr(void) { disable_interrupts(GLOBAL); time = get_timer0(); // on récupère la valeur de Timer0 compte++; // on incrémente la variable compte set_timer0(0); // initialiser timer0 à 0 enable_interrupts(GLOBAL); } void main(void) { unsigned int16 tableau[6] = {0, 0, 0, 0, 0, 0}; // on initialise les valeurs du tableau à 0 unsigned int16 greatest ; int i ; enable_interrupts(GLOBAL); enable_interrupts(INT_EXT); // autorise les interruptions sur RB0 ext_int_edge(0, L_TO_H); // déclencher interruption0 sur front montant setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64); // configuration du Timer0 usb_init_cs(); do { usb_task(); usb_debug_task(); switch(compte) { case 1: tableau[0]=time ; break; case 2: tableau[1]=time ; break; case 3: tableau[2]=time ; break; case 4: tableau[3]=time ; break; case 5: tableau[4]=time ; break; case 6: tableau[5]=time ; for (i = 0 ; i < 6 ; i ++) { printf(usb_cdc_putc, "%lu \n\r", tableau[i]); } compte = 0; break; } } while (TRUE); }
++
Sa marche!!comme un ***, j'avais oublié d'initialiser greatest à 0!!!^^