<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
D'accord, donc si je comprend bien:
-j'initialise un timer pour environ 10ms
-jautorise les interruption pour le timer,
-je crée ma routine d'interruption avec dedans : i++;
-et dans mon main je teste i et en fonction de sa valeur j'affecte la valeur des LED (comme dans ton explication précédement)
Je vais essayer tout ça
Merci encore
Nicolas
Et que pense tu de cela :
Code:main { /* init */ ... while(1) { flag_10ms=0; while(!flag_10ms); /* Ton code ici sera executé toute les 10ms ... */ ... } } Interupt_Timer { flag_10ms = 1; }
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
C'est vrai, c'est pas mal...
je te remercie encore
Bonjour,
bon, j'ai fais un programme et il marche pas...en fait, j'ai associée le principe que ma proposé Seb26 avec l'ajout du timer de 10ms..et ça ne marche pas..mon programme reste bloqué dans mon ss programme "TypePush"(enfin je pense...) car quand je le met en commentaire tout fonctionne(les autres interruptions), alors Si vous voyez une GROSSE ERREUR, faites moi signe...merci d'avance
Code:#pragma interrupt LED void LED(void) { if (INTCONbits.INT0IF) //Interruption INT0 { LEDA2=!LEDA2; INTCONbits.INT0IF=0; } if (INTCON3bits.INT1IF) //Interruption INT1 { lissage=0; TypePush(); INTCON3bits.INT1IF=0; } if (INTCON3bits.INT2IF) //Interruption INT2 { LEDA4=!LEDA4; INTCON3bits.INT2IF=0; } if (INTCONbits.TMR0IF) //Test du drapeau d'IT { TMR0L=0x3D; //Fixe le départ du timer->timer de 10ms INTCONbits.TMR0IF = 0; //efface le drapeau d'IT flag_10ms=1; } } #pragma code vecteur_d_IT=0x08 void TIMER(void) { _asm goto LED _endasm } #pragma code /*************************************************************************** *********************Programme Principal************************************ ***************************************************************************/ void main (void) { LEDA5=0; LEDA4=0; LEDA3=0; LEDA2=0; init_uc(); //Appel SP Initialisation du microcontroleur config_IT(); //Appel SP Initialisation des interruptions config_timer(); //Appel SP Initialisation du Timer while(1) { Nop(); }//Fin While(1) }//Fin Programme Principal /*************************************************************************** Nom : void init_uc(void) Role : Configuration et initialisation des Ports E/S *****************************************************************************/ void init_uc(void) { ADCON1=0x0F; // Configuration en numérique TRISA=0x00; // PORTA en sortie TRISB=0xF7; // PORTB en entrée --sauf RB3 en sortie TRISC=0x00; // PORTC en sortie TRISD=0x00; // PORTD en sortie TRISE=0x00; // PORTE en sortie PORTA=0x00; // PORTB=0x00; /// PORTC=0x00; ////Initialisation à 0 des Ports PORTD=0x00; /// PORTE=0x00; // } /*************************************************************************** Nom : void config_timer(void); Role : *****************************************************************************/ void config_timer(void) { T0CON=0xC7; } /*************************************************************************** Nom : void config_IT(void); Role : *****************************************************************************/ void config_IT(void) { INTCONbits.GIE=1; //Autorise les interruptions INTCONbits.GIEH = 1; //Autorise toutes les interruptions INTCON2bits.INTEDG0=0; //Interruption sur un front descendant sur RB0 INTCONbits.INT0IE=1; //Autorie les interruptions externes sur INT0 INTCON2bits.INTEDG1=0; //Interruption sur un front descendant sur RB1 INTCON3bits.INT1IE=1; //Autorie les interruptions externes sur INT1 INTCON2bits.INTEDG2=0; //Interruption sur un front descendant sur RB2 INTCON3bits.INT2IE=1; //Autorie les interruptions externes sur INT2 INTCONbits.TMR0IE=1; //autorise les interruptions de TMR0 } /*************************************************************************** Nom : void Delay_ms(int ms) Principe: 1TCY= FOSC/4 ->en architecture RISC: 1TCy=Tinstruction ex: FOSC=20MHz -> 5 MIPS (million instruction per second) donc 1 instruction = 0,2µs et 1ms = 5000 cycles *****************************************************************************/ void Delay_ms(int ms) { while(ms>0) { Delay1KTCYx(5); ms--; } } /*************************************************************************** Nom : void TypePush(void); Role : *****************************************************************************/ void TypePush(void) { flag_10ms=0; while((!flag_10ms) || (lissage!=0xFF)); { if(PORTBbits.RB1==0) { lissage++; } if(PORTBbits.RB1==1) { if(lissage>20) { lissage=0xFF; LEDA5=!LEDA5; } if((lissage>10) && (lissage<=20)) { lissage=0xFF; LEDA2=!LEDA2; } } } }
Salut,
(pas trop le temps mais vite fait):
Je ne vois pas l´interet de ton TypePush en relation avec ton Timer de 10ms (á mon avis tu t´es embrouillé quelque part!), ensuite, je me répete:
Si lissage ne va que jusqu´a 0xFF (=256) et que:
ca veut dire que ta boucle d´incrémentation de lissage ne peut durer que 256*0,2us = 51,2us !donc 1 instruction = 0,2µs
Après si tu l´incrémente encore, ca crée un overload et les résultats sont imprévisibles!
De quel type est ta variable lissage?
T´as essayé ma proposition message#26 ? Si tu veux te servir du Timer, tu peux remplacer la boucle for() par une gestion du timer... DANS MA PROPOSITION, JE TE PRECISE BIEN QU´IL FAUT AVOIR UNE VARIABLE LISSAGE TRES GRANDE! Si ton PIC exécute une instruction toutes les 0,2us, je dirais que pour 100ms il faut que seuil=250000 (car il fait un test puis une incrémentation dans la boucle for mais je ne suis vraiment pas sur, a tester) donc que lissage soit au moins un "long int" (4 octets)!
Est ce que tu fais des organigrammes pour structurer to programme avant de l´écrire?
PS: ou utilises-tu ton sous prog Delay_ms() ?
Ma variable "lissage" est un int.De quel type est ta variable lissage?
D'après ce que me diasait Seb26 dans son précédant message, tout ce qui est dans le while, est exécuté toutes les 10ms, donc je pense/pensais que ça serait bon..ca veut dire que ta boucle d´incrémentation de lissage ne peut durer que 256*0,2us = 51,2us !
Est ce que tu fais des organigrammes pour structurer to programme avant de l´écrire?je vais me faire taper sur les doigts je sais...et c'est surement de la que viens le problème...je sais.
Non je ne l'utilise pas...PS: ou utilises-tu ton sous prog Delay_ms() ?
Bon je vais mettre les choses au clair en faisant un organigramme je pense...
encore merci
Ah, oui, excuse moi, j´avais pas fait gaffe au ";" juste derriere le while!D'après ce que me diasait Seb26 dans son précédant message, tout ce qui est dans le while, est exécuté toutes les 10ms, donc je pense/pensais que ça serait bon..
Donc la, ce qui ne va pas c´est que du coup, tu attends (dans ton while ) flag_10ms = 1 ce qui arrivera bien toutes les 10ms mais tu attends aussi lissage = 0xFFh ce qui ne peux pas arriver puisque comme tu es dans ta boucle while!
Il faut donc simplement faire 2 boucles imbriquées:
désolé, j´avais pas fait gaffe au ";" mais c´est que tu as quand même mis des accolades (inutiles et fausses) donc pour moi tout ce qui était en dessous était dans la boucle while!void TypePush(void)
{
while (lissage != 0xFF)
{
flag_10ms=0;
while (!flag_10ms);
if(PORTBbits.RB1==0)
{
lissage++;
}
if(PORTBbits.RB1==1)
{
if(lissage>20)
{
lissage=0xFF;
LEDA5=!LEDA5;
}
if((lissage>10) && (lissage<=20))
{
lissage=0xFF;
LEDA2=!LEDA2;
}
}
}
}
Essaye ca, la normalement si tu appuis plus de 100ms mais moins de 200ms, ca change l´état de LEDA2 et si tu appuis plus de 200ms, ca change celui de LEDA5 (si ton Timer est bien paramétré...)
Et du coup pas de problème au niveau de la taille de "lissage"
Juste une remarque a vérifier dans tes essais, entre 100ms et 200ms il n´y a pas grand chose (pour un humain) donc je mettrais le seuil (actuellement 200ms) plus haut, par exemple pour différencier un appui court d´un long, je mettrais plutot 1s (donc lissage = 100) (sinon c´est a toi de le déterminer car je ne sais pas ce que tu veux faire)
Je vais essayé ça tout de suite...
je te remercie beaucoup..
bonne journée à toi lil vince.
De rien, bonne journée toi aussi et bon courage... (je repasse vers 12h pendant que je mange, dit moi si ca marche)
Bon...ça ne marche toujours pas..
Bon, j'ai encore mis en commentaire le ss programme et la ça tourne normalement, et mon timer est bien réglé à 10ms précisément..
Mais quand j'utilise le sous programme(que tu m'a transmis) le µC reste dans le sous programme...je vais essayé de comprendre pourquoi il y reste et ou..
Code:flag_10ms=0; while (!flag_10ms);je deviens fou...que fais exactement cette ligne..
"Tant que flag_10ms est différent de 0(car flag_10ms=0 juste avant), j effectue ce qui suis l'instruction"??ou je me plante??
ou alors, j'effectue ce qui suit l'intruction que lorsque flag_10ms=1(donc a tout les top timer)??ça doit etre ça je pense
Merci d'avance
Bon,....j'ai pas la solution..
J'ai beau eu faire l'organigramme du sous programme, faire toutes les combinaisons possibles, je ne trouve pas ou il peut rester bloqué...!!!
Alors avis au détective..
De plus, lorsque le programme est bloqué, le timer ne tourne plus car j'ai miset sur LEDA5 je n'ai rien( à l'oscilloscope..) et quand je met en commentaire le sous programme TypePush, la ça tourne..Code:if (INTCONbits.TMR0IF) //Test du drapeau d'IT { TMR0L=0x3D; //Fixe le départ du timer->timer de 10ms flag_10ms=1; LEDA5=!LEDA5; INTCONbits.TMR0IF = 0; //efface le drapeau d'IT }
AMA : débuter la programmation sur PIC n'est pas forcement la meilleure idée ...
Fais toi d'abord la main sur PC, c'est plus facile de visualiser pas à pas l'exécution de ton code ... essaye l'édition Express de Visual C++ par exemple, ou encore un IDE libre ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
C´est ca, car quand tu fais un while, tant que ce que tu as dans ta paranthese = 1, il exécute ce que tu as dans la boucle ,donc ici rien! Comme flag_10ms = 0 alors (!flag_10ms) = 1 donc tant que flag_ms = 0, tu reste dans ton while qui ne fait rien à cause du point virgule juste derriere... D´ailleurs, perso j´écrirais "while(!(flag_10ms)) {}" car mon compilateur n´a pas besoin de ";" apres un while et des parantheses pour être sur qu´il fait bien l´inversion de flag_10ms(mais surement inutiles les parantheses!)ou alors, j'effectue ce qui suit l'intruction que lorsque flag_10ms=1(donc a tout les top timer)??
Donc essaye peut-être déjà ca pour voir( while(!(flag_10ms)) {} )...
Ca tourne = LEDA5 clignote toutes les 10ms?et sur LEDA5 je n'ai rien( à l'oscilloscope..) et quand je met en commentaire le sous programme TypePush, la ça tourne.
Idée: (mais dépend du fonctionnement des PIC que je ne connais toujours pas)
Quand tu fais:
if (INTCON3bits.INT1IF) //Interruption INT1
{
lissage=0;
TypePush();
INTCON3bits.INT1IF=0;
}
Tu appels ton sous prog sans avoir remis INTCON3bits.INT1IF à 0 ! donc inverse ces 2 lignes:
if (INTCON3bits.INT1IF) //Interruption INT1
{
lissage=0;
INTCON3bits.INT1IF=0;
TypePush();
}
D´ailleurs ca doit etre ca car du coup a chaque interruption tu test d´abord INTCON3bits.INT1IF et comme il est toujours = 1 du coup tu rappel toujours TypePuch() sans arret (á chaque interruption qu´elle soit due au timer ou à INT1 ou INT2)!
Je sais pas si t´as compris mais c´est sur que ca ne pouvait pas marcher(avant ma derniere modif du while non plus)...
Sinon, comme tu lui avais conseillé, se servir du debugger est pratique pour trouver ses erreurs (un point d´arret sur le test d´interruption du Timer et il aurait tout de suite vu qu´il n´y arrivait pas...)AMA : débuter la programmation sur PIC n'est pas forcement la meilleure idée ...
Fais toi d'abord la main sur PC, c'est plus facile de visualiser pas à pas l'exécution de ton code ... essaye l'édition Express de Visual C++ par exemple, ou encore un IDE libre ...
Et il faut aussi (meme si c´est du vite fait au brouillon) faire des organigrammes quand on débute (et même apres)! Il n´y a pas de honte, dés que je fais des algo un peu compliqués ou que je sens que ma tete a du mal à retenir toute une partie du prog, je fais un organigramme, c´est plus visuel! En plus apres quand tu veux te remettre dedans ou faire une petite modif ca va tout de suite plus vite...
Oui, mais je le vois à l'osciloscope!!!pas à l'oeil nu!Ca tourne = LEDA5 clignote toutes les 10ms?
Bon sinon j'ai fais les modif': le while, et l'inversion des 2 lignes dans la routine d'interruption..et ça marche toujours pas...je vais donc essayé de me servir du debugger ICD2 pour trouver le problème...
Merci de vos aides
Bon apres midi
Et voila, avec cette instruction là, çà tourne(LEDA5 clignote ttes les 10 ms)...mais le fonctionnement de BP1 (interrruption sur RB1) n'est pas encore validé.Code:while(flag_10ms=0){}
J'y travaille...
Merci encore pour toutes vos explications...ça m'aide grandement pour mon évolution..
Normal, tu fais une affectation et pas un test ...
( ou alors t'as fait bon dans ton code et pas ici... )
Très sincèrement : range ton PIC pour le moment, et apprends à coder sur PC ... ne le prends pas mal, mais c'est comme si tu essayais d'apprendre à conduire sur une Enzo sans assistance au pilotage ... Tu vas perdre un temps fou et bousiller pas mal de voitures ...![]()
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Tu as déja conduit une Enzo???c'est comme si tu essayais d'apprendre à conduire sur une Enzo sans assistance au pilotage ...
Je sais je ne commence peut etre pas par le bon bout, mais, mon projet doit fonctionner avec un PIC, et le temps m'est compté .....4 semaines-5jours-9heures-35 minutes- et 52 secondes 51, 50, 49,...![]()
Bon trêve de plaisanteries...
J'avance tout doucement et je suis content d'apprendre la programmation comme ça..et j'apprends beaucoup..et puis j'ai de la programmation sur PC à l'école et ça ma rapidement barbé car je trouvais que ce n'étais pas concret du tout...et je détestai ça , alors que depuis peu j'ai du mis remettre et avec les PICs je trouve ça beaucoup plus simple (meme si ça ne marche pas tout le temps!!)
Pas depuis 2 semaines ... elle est au garage ...
Disons que quand je te vois te demander ce que fait la ligne "While(!toto);" ... je me dis que tu n'es déjà pas super à l'aise avec la prog ...Je sais je ne commence peut etre pas par le bon bout, mais, mon projet doit fonctionner avec un PIC, et le temps m'est compté .....4 semaines-5jours-9heures-35 minutes- et 52 secondes 51, 50, 49,...![]()
Bon trêve de plaisanteries...
J'avance tout doucement et je suis content d'apprendre la programmation comme ça..et j'apprends beaucoup..et puis j'ai de la programmation sur PC à l'école et ça ma rapidement barbé car je trouvais que ce n'étais pas concret du tout...et je détestai ça , alors que depuis peu j'ai du mis remettre et avec les PICs je trouve ça beaucoup plus simple (meme si ça ne marche pas tout le temps!!)
Mais c'est toi qui vois ...
Bon, alors tu en es où ?
Si tu veux, on reprend depuis le début :
Avec cela, tu as une LED qui clignote à 10ms et une autre à 100ms ...Code:#define uChar unsigned char; main { uChar uc_KernelCounter = 0; /* Init */ ... /* Main loop */ while(1) { /* Wait kernel 10ms event */ flag_10ms=0; while(!flag_10ms); /* 10ms tasks */ // ### Debug Led1 = !Led1; // Manage I/O : BP // ... à completer ... /* Manage 100ms event */ uc_KernelCounter++; if( uc_KernelCounter>10 ) { uc_KernelCounter -= 10; // /* 100ms tasks */ // ### Debug Led2 = !Led2; } } } Interupt_Timer { flag_10ms = 1; }
Et je t'ai mis où gerer ton entrée BP ...... dans mes autres posts, je t'avais mis un semblant de lissage de ton BP, il ne te reste pluq qu'a comprendre tout ça, et à le coder ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Je te remercie..
J'y travaille et je vous tiens au courant...
Encore merci
Voila deja la structure avec la gestion de l'interruption sur RB1, et le timer de 10 ms, reste maintenant à compléter le contenu du sous programme TypePush qui aura pour forme le "Main loop" que tu ma transmis précédement...Code:#pragma interrupt LED void LED(void) { if (INTCON3bits.INT1IF) //Interruption INT1 { lissage=0; INTCON3bits.INT1IF=0; TypePush(); } if (INTCONbits.TMR0IF) //Test du drapeau d'IT { TMR0L=0x3D; //Fixe le départ du timer->timer de 10ms flag_10ms=1; INTCONbits.TMR0IF = 0; //efface le drapeau d'IT } } #pragma code vecteur_d_IT=0x08 void TIMER(void) { _asm goto LED _endasm } #pragma code /*************************************************************************** *********************Programme Principal************************************ ***************************************************************************/ void main (void) { init_uc(); //Appel SP Initialisation du microcontroleur config_IT(); //Appel SP Initialisation des interruptions config_timer(); //Appel SP Initialisation du Timer while(1) { Nop(); }//Fin While(1) }//Fin Programme Principal /*************************************************************************** Nom : void init_uc(void) Role : Configuration et initialisation des Ports E/S *****************************************************************************/ void init_uc(void) { ADCON1=0x0F; // Configuration en numérique TRISA=0x00; // PORTA en sortie TRISB=0xF7; // PORTB en entrée --sauf RB3 en sortie TRISC=0x00; // PORTC en sortie TRISD=0x00; // PORTD en sortie TRISE=0x00; // PORTE en sortie PORTA=0x00; // PORTB=0x00; /// PORTC=0x00; ////Initialisation à 0 des Ports PORTD=0x00; /// PORTE=0x00; // } /*************************************************************************** Nom : void config_timer(void); Role : *****************************************************************************/ void config_timer(void) { T0CON=0xC7; } /*************************************************************************** Nom : void config_IT(void); Role : *****************************************************************************/ void config_IT(void) { INTCONbits.GIE=1; //Autorise les interruptions INTCONbits.GIEH = 1; //Autorise toutes les interruptions INTCON2bits.INTEDG1=0; //Interruption sur un front descendant sur RB1 INTCON3bits.INT1IE=1; //Autorie les interruptions externes sur INT1 INTCONbits.TMR0IE=1; //autorise les interruptions de TMR0 } /*************************************************************************** Nom : void TypePush(void); Role : *****************************************************************************/ void TypePush(void) { /*********Test du bouton avec lissage********/ }
A quoi va te servir l'IT RB1 ?
( vire cette IT ! )
Remplace :
par :Code:while(1) { Nop(); }//Fin While(1)
Normalement, ta diode clignote à 10msCode:while(1) { flag_10ms = 0; while(!flag_10ms); // ### DEBUG LEDA5=!LEDA5; }//Fin While(1)
Maintenant, ajoute l'appel à ta fonction qui gère le BP :
Et ta fonction TypePush(); doit ressembler en gros à :Code:while(1) { flag_10ms = 0; while(!flag_10ms); // ### DEBUG LEDA5=!LEDA5; TypePush(); // perso, je nomme toujours mes fonctions de façon à indiquer leur appel ... par exemple, celle là je mettrais : TypePush_10ms() }//Fin While(1)
Allez au boulot !Code:si( BP == appuyé ) si( lissage != 0xFF ) lissage ++; si( lissage > 20 ) lissage = 0xFF; Action_BP_long(); sinon si( lissage>10 && lissage!=0xFF ) Action_BP_court(); lissage = 0;
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
PS: avec ce code, le lissage est fait comme ci-dessous :
@++appui < 100ms = rien
100ms > appui > 200ms = appui court
appui > 200ms = appui long
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Je te remercie...
Je te tiens au courant
si( lissage>10 && lissage!=0xFF )![]()
Tu n'aurais pas fais une petite erreur??
Tu n'aurais pas voulus mettre
??Code:si( lissage>10 && lissage<=20 )
Mais je me trompe peut etre, et ça serait plus cohérent avec le message que tu avais mis ensuite:
appui < 100ms = rien
100ms > appui > 200ms = appui court
appui > 200ms = appui long