C'est plutôt quelque chose qu'on évite à tout prix : cela consomme de l'énergie, chauffe, diminue la durée de vie du processeur...CHOSE IMPORTANTE : quand le processeur est allumée, l’architecture tourne sans cesse.
Ainsi, un programme de manière principale est-il forcement une boucle infinie? Il faut tout de même faire tourner son programme sinon si il s’arrête et s’il n’y a pas d’interruption, le processeur ne servira à rien.
Quand il ne se passe rien, le processeur doit se mettre en attente d'un évènement type exception comme le dit bobfuck.
A priori il est possible de faire le traitement de l'info sans Interruption mais avec INPUT et JUMP Z.
Cela évite de sauvegarder l'environnement dans la pile et de perdre du temps car apres je dois déclencher l'injection d'un signal.
Oui c'est comme un exercice pour s'approprier le fonctionnement soft et hard d'une carte générique.
Si c'est un picoblaze, alors c'est dans une FPGA.
Si tu as besoin d'un traitement vraiment rapide, alors fais-le en utilisant la FPGA !
Sinon, fais-le sous interruption.
Bah sous assembleur, ça va tellement vite, scrute ton entrée, je dirais toutes les X millisecondes, ça devrai suffire. Le reste tu fais ce que tu veux, et entre 2 scrutations quelques milli secondes, c'est énorme ce que tu peux faire.
C'est une technique que j'utilisais pour allumer des leds, elles n'étaient alimentés que toutes les 10milli secondes, avec la rémanence et la vison humaine, on n'y voit que du feu et on croit qu'elles sont allumées en permanence. J'ai dit milli secondes mais ça peut être plus court.
Quelqu'un qui s'occupe des activités électroniques m'a dit qu'on peut scruter le port d'entrée sans interruptions.
Ce que j'aimerais savoir c'est comment structurer mon code.
En assembleur ca donne ca :Code:scrute_port: test du bit 0 du port A si le bit est à 0 alors on reboucle sur f(scrute_port) sinon on passe à f(une_injection). une_injection: sortir la valeur X sur le port B puis retourner à f(scrute_port).
C'est basique mais est-ce que c'est correcte?Code:scrute_port: INPUT s0,10 ;envoie 10 sur port_id et la valeur d'entrée va dans s0 JUMP Z, scrute_port ; si le bit carry est actif, alors on va a la fonction scrute_port. une_injection: OUTPUT, ....
Si la frequence de mon processeur est à 40MHz, les instructions sont executés en 2 cycles avec le picoblaze et donc toute les 50ns.
A priori, ce que j'ai fait la n'est pas bon car je boucle à l'infinie. C'est ce qu'on m'a dit. Maintenant pourquoi je ne sais pas
Dernière modification par Antoane ; 16/10/2016 à 15h40. Motif: réparation balises de code
J'oubliais en fin de prog asm
JUMP scrute_port
Oui évidemment on peut scruter, mais cette technique est primaire.
Un µC doit être utiliser en mode événementiel pour une bien meilleure efficacité.
Maintenant si dans ton application il n'y a quasi rien d'autre que de détecter une malheureuse touche, c'est différent.
C'est juste une mauvaise pratique, comme il y en a tant quand les principes n'ont pas été compris.
Je ne sais pas si c'est une mauvaise pratique, ... mais je dois etre le plus reactif possible donc je ne peux pas attendre 1ms pour sauvegarder tout l'environnement du processeur (picoblaze).
Les interruptions c'est bien mais je ne suis pas persuadé d'en avoir crutialement besoin.
Est-ce que j'ai développé de base ci-dessus est correcte?
Merci
Moi j'en suis certain, car il dépend de la durée de la tâche de fond, mais tu fais comme tu veux.Je ne sais pas si c'est une mauvaise pratique
Une bonne pratique est d'utiliser des processus valables quelque soit le µC, c'est un conseil.
La réactivité est maximale dès l'instant que tu captes l'événement DES qu'il survient, le processus d'interruption est très rapide sur un µC.
De plus si tu enrichis ton programme ultérieurement ta boucle principale va devenir de plus en plus longue et au bout d'un moment tu vas rater un événement qui peut être important, voir parfois vital, selon l'application (par exemple une sécurité de presse hydraulique).
Dans ton exemple oui effectivement.
Si tu utilises ce uC uniquement pour surveiller une pin, alors oui, tu n'as pas besoin d'utiliser une interruption... Mais c'est idiot d'utiliser un uC uniquement pour surveiller une pin ! Alors que :
- Codé proprement, avec une interruption, le uC pourra faire d'autres choses sans aucun problème. C'est à ça que sert un uC... pas juste à émuler une porte logique !
- Et si c'est pas assez rapide, tu as un FPGA ! Code la surveillance de pin en VHDL, là tu auras encore moins de latence !
Par exemple, si ton signal à détecter est d'une durée très faible et que tu as peur de le rater...
-> Utilise une interruption "edge triggered"
-> Si ton uC ne gère pas ce type d'interruption... tu as une FPGA, tu dois bien pouvoir instancier un flop ou une bascule RS...
Ou si tu peux avoir beaucoup d'événements, que tu veux les compter sans en rater un seul...
-> Sur un uC normal, utilise un timer/counter
-> Dans une FPGA... eh ben, instancie un compteur !
Je suis d'accord oui.
Je dois respecter une architecture dupliqué X fois pour X projets.
Plusieurs fonctions seront réalisées pour le picoblaze comme un premier test pour allumer les LEDS dans deux positions différente, écrire dans la mémoire microprogramme du picoblaze-3, reset le composant, ...
Je respecte juste ce qu'on m'a dit c'est à dire de ne pas utiliser d'interruptions mais surement parce qu'il n'y a pas grand chose comme fonctions oui.
Après les choix des un et des autres je ne suis pas en mesure de répliquer étant en phase de reprise de mes cours pour ce genre de situation.
Merci pour vos réponses en tout cas.
<< my 2 cents >>
mmhhh ... bof ... si tu fais un système temps-réel tu ne peux pas avoir une boucle de type while(1) qui tourne sans être cadencée, donc scruter une pin va juste te prendre un peu de temps CPU (très peu)
De plus cela me semble bien plus compliqué de faire un VRAI traitement anti-rebond avec une gestion sous IT.
Mais AMA il n'y a pas de règle absolue, tout dépend du besoin et du contexte.
Dans le cas présent, le but est d'avoir une réaction la plus rapide possible, donc en effet une IT semble toute indiquée ... sauf contrainte spécifique que l'on ignore ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Je ne connais pas une application sérieuse qui se passe d'IT, indispensable pour cadencer les actions et pour détecter et traiter convenablement (donc proprement) des événements non prédéterminés.
On appelle ça la règle de l'art, les interruptions ne sont pas une option mais une méthode destinée à synchroniser des actions pouvant être multiples et n'ayant pas la même occurrence.
Vous raisonnez comme si votre boucle est ultra rapide et ne fait que ça, or ce n'est pas souvent le cas dans la vraie vie.
Un appui bouton c'est grosso modo 50ms~100ms, sauf que si tu fais un anti-rebonds (indispensable) cela entraine donc un abandon de la tâche de fond d'au moins autant de ms, donc pendant ce temps là rien n'est fait d'autre que d'attendre comme un couillon si tu mets par exemple un bestial delay_ms(100).
Sous IT on détecte l'appui (événement) => lancement tempo en IT => on fait autre chose pendant la tempo puis on revient voir ce qui se passe après la durée de la tempo, juste à temps, on a fait plein d'autres choses durant ce temps, peut être capter d'autres événements qu'on va pouvoir traiter sans rien perdre.
Maintenant vous faites comme vous voulez braves gens.
mes tempo sont "fais n fois la tâche de fond" !
l'interruption c'est quand je suis obligé
Ben ça doit pas être bien beau
Effectivement, faire un anti-rebond comme ça c'est à bannir ...Un appui bouton c'est grosso modo 50ms~100ms, sauf que si tu fais un anti-rebonds (indispensable) cela entraine donc un abandon de la tâche de fond d'au moins autant de ms, donc pendant ce temps là rien n'est fait d'autre que d'attendre comme un couillon si tu mets par exemple un bestial delay_ms(100)
Bah justement, j'appelle pas ça un anti-rebond / anti-parasite valable ...
Dernière modification par Seb.26 ; 17/10/2016 à 17h36.
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Voici ce que j'ai développé dernièrement.
Le mainprog et les subroutines sont-ils dans le bonne ordre?
Merci d'avance et bonne soiréeCode:CONSTANT CST_AD_REG_STATE_LED,18 ; command reg_timer_status, finish counting? CONSTANT CST_AD_REG_STATE_LED_1,10 ; command reg_led_r CONSTANT CST_AD_REG_STATE_LED_2,10 ; command reg_led_r CONSTANT CST_AD_REG_TIMER_VAL,15 ; command reg_timer_val to decount ;--------------------------------------------------------------------------------- ;Special Register usage NAMEREG s0,ZEROS ;use NAMEREG s1,ONES ;use NAMEREG s2,STATE_LED_1 ;use NAMEREG s3,STATE_LED_2 ;use NAMEREG s4,TIMER_VAL ; use ;NAMEREG s5,ZEROS NAMEREG s6,REG_VAL_ENTRY ;ne pas utiliser s7 (boucles) ;ne pas utiliser s8 (interne) ;NAMEREG s9,ZEROS ;NAMEREG sA,ZEROS ;NAMEREG sB,ZEROS ;NAMEREG sC,ZEROS ;NAMEREG sD,ZEROS ;NAMEREG sE,ZEROS ; ne pas utiliser sF (macro) ;--------------------------------------------------------------------------------- ;Initialisation LOAD ZEROS,00 LOAD ONES,11 LOAD STATE_LED_1,00 ; STATE OF LEDS LOAD STATE_LED_2,0F ; STATE OF LEDS LOAD TIMER_VAL,FF ; ;-------------------------------------MAINPROG------------------------------------ ;--------------------------------------------------------------------------------- mainprog: ;CALL maj_timer_val CALL test_entry ;CALL stateleds ; state 1, see the difference ;CALL maj_timer_val CALL test_entry_2 ;CALL stateleds_2 ; state 2, see the difference return mainprog ;------------------------------------SUBROUTINE----------------------------------- ;--------------------------------------------------------------------------------- test_entry: INPUT REG_VAL_ENTRY,CST_AD_REG_STATE_LED ;AD_REG_STATE_LED is PORT_ID ;and select the INPUT_data and s0 receive the data JUMP NZ, stateleds ;if entry value s0 is not NULL, jump in stateleds return stateleds: OUTPUT STATE_LED_1,CST_AD_REG_STATE_LED_1 ;OUTPUT PORT, PORT ID return test_entry_2: INPUT REG_VAL_ENTRY,CST_AD_REG_STATE_LED ;AD_REG_STATE_LED is PORT_ID ;and select the INPUT_data and s0 receive the data JUMP NZ, stateleds_2 ;if entry value s0 is not NULL, jump in stateleds return stateleds_2: OUTPUT STATE_LED_2,CST_AD_REG_STATE_LED_2 ;OUTPUT PORT, PORT ID return maj_timer_val: OUTPUT TIMER_VAL,CST_AD_REG_TIMER_VAL ;OUTPUT PORT, PORT ID return