Planete Sciences

forums de Planete Sciences
It is currently Wed 22 May 2013, 01:06

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 98 posts ]  Go to page Previous  1, 2, 3, 4, 5 ... 7  Next
Author Message
PostPosted: Mon 30 Jan 2012, 18:43 
Offline

Joined: Fri 03 Nov 2006, 12:40
Posts: 156
Location: Belgique
Re,

je suis d'accord avec ce que tu écris. L'obligation de lire le port ou non est indiqué dans les spec du Pic utilisé.
Le flag de l'interrupt doit être effacé, dans mon cas c'est le compilateur qui le fait dans la routine d'interrupt. Je ne l'ai jamais fait, sauf lire le port quand c'est spécifié.
Pour en être certain, tu devrais voir le code Hex produit ......
Ce que je ne comprend pas dans l'exemple donné ci dessus c'est comment le compilateur peut différencier lesz routines de deux interrupts différents. Il n'y a pas de nom spécifique pour chaque routine. Mais cela est propre au compilateur, et celui là je ne le connais pas.

Pour les priorités des interrupts dans les anciens Pics (comme le 16F88), et valable quand (par exemple) deux interrupts arrivent en même temps, c'est uniquement l'ordre du test de chaque flag qui sera adapté. Le plus prioritaire sera le premier testé et ainsi de suite. Cela aussi c'est le compilateur qui doit le faire. Du moins si il en donne la possibilité quel que soit le Pic. Cela se faisait déjà avant d'avoir des Pics avec Priorité High et Low.

Bonne soirée.

Guuy.


Top
 Profile  
 
PostPosted: Mon 30 Jan 2012, 21:06 
Offline

Joined: Tue 21 Jul 2009, 15:01
Posts: 65
Bonsoir à tous,

Je viens de rentrer le temps de faire les differents test suite à vos propositions et je vous tient au courant.

Cordialement,
bypbop


Top
 Profile  
 
PostPosted: Mon 30 Jan 2012, 21:26 
Offline

Joined: Tue 21 Jul 2009, 15:01
Posts: 65
Re

Alors comme cela ca fonctionne :

Code:
int i;
void interrupt (void){

if(INTCON.INT0IF)
   {
      i++;
      Delay_ms(100) ;          // pour l'anti-rebond
      if (i==4)
      {
      i=1;
      }
      INTCON.INT0IF = 0;
   }

}
void main()
{
TRISA = 0b00000000; ; // port A en sortie
TRISB = 0b00000001;   // port B en sortie pin 0 en entrée

ANSEL = 0;
OSCCON = 0b01111000;
INTCON.GIE = 1;
INTCON.RBIE = 1;
INTCON.RBIF = 0;

INTCON.INT0IE = 1;
INTCON.INT0IF = 0;


ADCON1=0x0F;



i=1;


PORTB.B2 = 1 ;
Delay_ms(100) ;
PORTB.B2 = 0 ;
Delay_ms(100) ;


while(1)
{

if (i==1)
{
PORTA.B0 = 1 ;
PORTA.B1 = 1 ;

PORTA.B3 = 1 ;
PORTA.B4 = 1 ;

PORTA.B2 = 1 ;
PORTB.B1 = 1 ;

PORTA.B6 = 1 ;
PORTA.B7 = 1 ;
}
if(i==2)
{
PORTA.B0 = 0 ;
PORTA.B1 = 0 ;

PORTA.B3 = 0 ;
PORTA.B4 = 0 ;

PORTA.B2 = 0 ;
PORTB.B1 = 0 ;

PORTA.B6 = 0 ;
PORTA.B7 = 0 ;
}
if(i==3)
{
PORTA.B0 = 1 ;
PORTA.B1 = 1 ;

PORTA.B3 = 1 ;
PORTA.B4 = 1 ;

PORTA.B2 = 1 ;
PORTB.B1 = 1 ;
Delay_ms(1000);
PORTA.B6 = 1 ;
PORTA.B7 = 1 ;

PORTA.B0 = 0 ;
PORTA.B1 = 0 ;

PORTA.B3 = 0 ;
PORTA.B4 = 0 ;

PORTA.B2 = 0 ;
PORTB.B1 = 0 ;

PORTA.B6 = 0 ;
PORTA.B7 = 0 ;
Delay_ms(1000);

}
}
}


Faut que je récapitule car je n'y comprends plus grand chose

En me documentant j'ai compris qu'un interruption se definit sur 8 bits mais je vois plus la diffenrence entre le RB.. et le INT0 ...


cordialement,
bypbop


Top
 Profile  
 
PostPosted: Mon 30 Jan 2012, 23:18 
Offline

Joined: Mon 25 Jan 2010, 22:48
Posts: 344
Je comprend que je suis peut-être allé un peu vite en te conseillant la fiche technique du PIC. Peux-tu nous éclairer sur ton niveau en anglais ?

J'ai un peu peur quand tu dis :
bypbop wrote:
j'ai compris qu'un interruption se definit sur 8 bits


Je te présente ma manière de voir les choses :
Tu as un code principal, dans void main(){ ... }. Ce code s'exécute séquentiellement, chaque ligne l'une après l'autre.
Ce code peut s'interrompre pour en exécuter un autre. Cet autre code se trouve dans void interrupt (void){ ... }. Dès que le code dans interrupt() a été exécuté, le programme reprend son cours dans le main(), à l'endroit exacte où il l'avait quitté.

Tu choisis les événements qui peuvent interrompre ton code avec des bits de configuration.

Dans ton code tu as activé les interruption pour deux types d'évènement :
  • Les front montant (ou descendant) arrivant sur RB0 (INT0)
  • Un changement d'état de l'une des pattes RB4, RB5, RB6, ou RB7
Le deuxième type d'évènement ne te sert à rien et bloquerait ton code si une interruption se déclenchait (parce que tu ne ferait rien qui "lève" l'interruption. Ton code entrerait et quitterait sans cesse la fonction interrupt().

Pour commencer , la magie est ici :
Code:
INTCON.GIE = 1;
INTCON.RBIE = 1;
INTCON.RBIF = 0;

INTCON.INT0IE = 1;
INTCON.INT0IF = 0;


Et un petit dessin ne fait jamais de mal :

Image
Ce schéma présente toutes les sources possibles d'interruption, mais sans explication, c'est pas très clair.

Tu vois que tu as GIE (Global interruption Enable) qui permet de bloquer ou de débloquer toutes les interruptions. Si tu ne veux pas d'interruption, tu le mets à 0, sinon, si tu veux te servir d'au moins une interruption, tu le mets à 1.

Ensuite tu vois que pour chaque source d'interruption, tu as deux bits :
L'un qui passe automatiquement à un lorsque l'évènement se produit (le bit en "IF" => interrupt flag) - parfois appelé drapeau ou sémaphore.
L'autre que tu contrôles, et qui se termine en IE (interrupt enable) - qu'on peut traduite par "activation de l'interruption".

L'évènement ne déclenche une interruption que si les deux bits (IF et IE) sont à 1. Du coup, quand tu as choisis l'évènement pour lequel tu souhaites une interruption, tu mets son bit IE à 1.

Dans la pratique, avant de mettre le bit IE à 1, on met le bit IF correspondant à 0, pour s'assurer que l'interruption ne se déclenche pas si le bit IF était à 1.

Tu as mis deux bit IE à 1, INTCON.INT0IE et INTCON.RBIE.
Tu ne veux pas des interruptions liés aux RB4 à RB7, tu peux supprimer la partie INTCON.RBIE et INTCON.RBIF.

Un petit mot sur PEIE, on voit que PEIE permet de bloquer tout un lot d'interruption. il ne faudra pas oublier de le passer à 1 si tu veux te servir d'une des interruptions indiquées tout à gauche. PEIE prétend gérer les interruptions liées aux périphériques (mais c'est un peu arbitraire).

J'espère t'avoir éclairé un peu, n'hésite pas à poser tes questions.
Si certains lecteurs trouvent que mon explication mérite d'être approfondie/améliorée/tronquée par leur soin qu'ils n'hésite pas à me le faire savoir.

_________________
Équipe Poivron
Coupe 2012 : Équipe Poivron (73e)
Coupe 2011 : Équipe Poivron (122e) - Prix des équipes !
Coupe 2010 : Équipe Poivron (78e)

Passez voir le Portail des équipes


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 00:00 
Offline

Joined: Tue 21 Jul 2009, 15:01
Posts: 65
Un grand merci pour cette explication je comprends mieux maintenant,
comme je débute en electronique cette notion est pas forcement évidente ...

alors je viens d'enlever les interruptions sur RB qui ne sont pas utile dans mon cas (enfin pour l'instant)

Pour la sequence d'interruption j'ai remarqué que le programme terminé avant de changer de programme ce qui correspond bien a ce que tu expliques.

programme 1 > une interruption arrive j'incremente > je reprends et je change de programme > programme

ca c'est ok

Code:
INTCON.GIE = 1; // active les interruptions
INTCON.INT0IF = 0; // drapeau INT0 avant le IE
INTCON.INT0IE = 1; // j'active l'interruption INT0



alors j'ai une petite question quand je regarde le brochage de mon 16F88 je vois que sur le schéma la pin 6 correspond à RB0/INT/CCP1 alors je me demande quelle est la correspondance entre l'interruption Zéro dans mon programme et INT

Je comprends que la broche RB0 peut servir d'interruption par rapport au diagramme mais pourquoi je l'appelle INT0

J'espere que je suis comprehensible.

Cordialement,
bypbop


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 00:35 
Offline

Joined: Fri 03 Nov 2006, 12:40
Posts: 156
Location: Belgique
Re,
il faut lire la doc du Pic et la comprendre. Chaque Pin d'un Pic peut avoir plusieurs fonctions. C'est le cas de la pin 6. Elle peut être :
RB0 : pin I/O simple.
Int : un signal sur cette pin provoque un interrupt, c'est ce que tu as besoin.
CCP : comparateur et sortie PWM.

Ton code m'étonne, pourquoi écris tu : if(INTCON.INT0IF)
Si tu arrives à cet endroit c'est que ce flag est bien à 1 ......!
Relis ce que je t'ai écrit.

Guy.


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 00:41 
Offline

Joined: Mon 25 Jan 2010, 22:48
Posts: 344
Si j'ai bien compris ta question c'est pourquoi l'interruption s'appelle INT0 ? Pourquoi pas INT ? ou RB0 ?
La réponse sur ce schéma (un autre PIC) :
Image
(image cliquable)
Si tu repère RB0, RB1 et RB2, tu verra que chacune a une fonction nommée INTx (INT0, INT1 ou INT2). Sur ton PIC, tu n'a qu'une patte INT, il ont du se dire qu'ils n'avaient pas besoin de la numéroter.

Si tu veux en savoir plus sur les fonctionnalités que peut avoir un PIC, je te conseille cette page, tout en bas (petit coup de pub)...

Quote:
Ton code m'étonne, pourquoi écris tu : if(INTCON.INT0IF)
Si tu arrives à cet endroit c'est que ce flag est bien à 1 ......!
Relis ce que je t'ai écrit.


@Guy Detienne : Ça ne me choque pas, il n'a pas besoin d'économiser des cycles et c'est une bonne habitude à prendre. Il pourrait entrer dans l'interruption à cause de différents évènement... J'ai l'impression, d'après ce que tu m'as dis, que ton compilateur te faisait un tri en fonction de l'évènement qui déclenche l'interruption ?

_________________
Équipe Poivron
Coupe 2012 : Équipe Poivron (73e)
Coupe 2011 : Équipe Poivron (122e) - Prix des équipes !
Coupe 2010 : Équipe Poivron (78e)

Passez voir le Portail des équipes


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 00:51 
Offline

Joined: Tue 21 Jul 2009, 15:01
Posts: 65
Bien compris c'est mon schéma qui m'a induit en erreur RB0 correspond directement à INT0.
Je vais essayé de bosser sur une interruption avec un timer maintenant .


Encore merci à tous

Cordialement,
bypbop


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 10:42 
Offline
PMI

Joined: Wed 07 Jun 2006, 10:48
Posts: 778
Location: Grenoble
Guy Detienne wrote:
Ton code m'étonne, pourquoi écris tu : if(INTCON.INT0IF)
Si tu arrives à cet endroit c'est que ce flag est bien à 1 ......!
Relis ce que je t'ai écrit.
Guy.

C'est moi qui lui est conseillé de mettre un test à l'entrée de l'interruption. Je ne sais pas quel compilateur tu utilises mais apparemment il te simplifie pas mal les choses. Ce pic a deux vecteurs d'interruption. Donc apparemment, ici c'est abstrait pour le développeur, mais pour mon compilateur, j'ai deux prototypes de branchement en fonction de la priorité (high ou low).
Lorsque ton interruption pète, tu es branché directement au vecteur concerné, mais le pic ne connait pas la source de l'interruption, il est plus que conseillé de faire ce test dans la fonction d'interruption.
Ton compilateur permet peut être de s’abstenir d'effacer le flag en sortie de fonction interruption, ce n'est pas le cas de tous.
Je conseille tout de même d'ajouter la ligne
Code:
INTCON.INT0IF=0;
avant de sortir du if.

Ps: Je serais curieux de savoir comment ton compilateur fait pour ségréguer les parties de code à exécuter lorsqu'une interruption INT pète de celui lorsque TIMER pète par exemple, si tu mets pas de if et que tu ne clear pas les flags.

_________________
Président de l'association de robotique I-Grebot de Grenoble
http://www.igrebot.fr | Wiki | Forum| Vidéos


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 12:52 
Offline

Joined: Fri 03 Nov 2006, 12:40
Posts: 156
Location: Belgique
Bonjour,

je vous remercie pour vos interventions et je vais expliquer comment fonctionne mon compilateur et essayer, par vos réponses, de comprendre la logique de Mikro C.
Si je fais un programme avec plusieurs interrupts, ce qui est courant, j'écris une fonction par interrupt. Donc si on prend l'exemple de 3 interrupt, soit Timer0, RS232 et B0, voici ce que j'ai :
[code]
#int_rtcc
void Timer0Interrupt ( void )
{
// code ...
}

#int_RDA
void RDA_isr()
{
// code avec obligation de vider le buffer de reception
}

#int_ext
void intRB0 ()
{
// poussoir sur B0
// code ...
}
/code]

Dans le while, et lorsque ces interrupts sont permisent, une fois qu'une interrupt arrive le programme saute en début de mémoire et execute le programme gérant les interrupts. Là c'est classique, le programme sauve ce qu'il faut (status, pclath et w) et met GIE = 0 puis il teste les différents flags pour savoir qui a demandé une interrupt. Une fois trouvé, il va dans la routine concernée. Il sait laquelle est concernée par les mots clés attribués à chaque routine. A la fin de l'execution de cette routine il fait un clear de l'interrupt concerné. Retour d'où il vient et restaure ce qu'il avait sauvé, met GIE = 1 et retourne dans le while.
Ce fonctionnement me semble simple et logique. Si MikroC ne permet qu'une routine d'interrupt pour les 3 (dans mon exemple) alors il faut bien tester chaque flag .....
Si il faut lire le port (cas B4 ... B7 ou vider le buffer RCREG) c'est propre à l'architecture des Pic et indiqué dans le datasheet.
Pour ce qui est des priorités dans les interrupts, sauf erreur de ma part, ce Pic n'en a pas. Le compilateur permet de lui donner, pour tout les pics n'ayant pas cette fonction, d'entrer une priorité. Il va donc tester les flags dans l'ordre donné. Donc si je donne RDA, Timer0 et RB0 et que j'ai deux interrupts en même temps soit RDA et RB0, il va tester en premier RDA et executer cette routine, puis Timer0 (rien) en enfin executer RB0. L'ordre sera respecté.

Mes excuses si mes explications ont été un peu longues. J'espère que cela a un peu éclairé mes dires.


Guy.


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 14:01 
Offline

Joined: Mon 25 Jan 2010, 22:48
Posts: 344
Sur C18, on est un peu plus bas niveau que sur ton compilateur. Il y a bien une sauvegade et une restauration du context, mais il n'y a qu'une fonction par niveau d'interruption supporté par le PIC. La gestion des priotités au sein d'un même niveau se fait donc avec l'orde de test des semaphores (flag).
de mémoire, il n'y a pas d'action sur GIE en interruptio faite par le compilo, il me semblait même qu'il ne fallait pas toucher à GIE pendant une interruption ( mais ce n'est qu'un vague souvenir)

j'ai supposé que MikroC fonctionnait ainsi.

je pense que ce fonctionnement n'est ps très loin de celui que tu avais deviné.

_________________
Équipe Poivron
Coupe 2012 : Équipe Poivron (73e)
Coupe 2011 : Équipe Poivron (122e) - Prix des équipes !
Coupe 2010 : Équipe Poivron (78e)

Passez voir le Portail des équipes


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 14:21 
Offline

Joined: Fri 03 Nov 2006, 12:40
Posts: 156
Location: Belgique
Re,

pour ce qui est de GIE durant l'interrupt, faudrait vérifier. Cela devrait être décrit dans les datasheet. Je n'en ai pas sous la main pour l'instant.
Mais il ne faut surtout pas qu'il rentre à nouveau dans sa routine d'interrupt sinon il n'en sortira jamais .... de toute facon je n'y bouge pas. C'est le compilo qui gère et cela fonctionne trés bien.


Guy.


Top
 Profile  
 
PostPosted: Tue 31 Jan 2012, 17:34 
Offline

Joined: Fri 03 Nov 2006, 12:40
Posts: 156
Location: Belgique
Re,
je me suis documenté. Lors de l'interrupt, c'est le Pic qui arréte le déroulement du programme, il va à l'adresse 0x04 et il coupe le GIE.
Celui ci sera remis à 1 lorsque l'on quitte cette routine, non pas en donnant la commande "return" mais bien "retfie". Cette instruction est un "return" et un "GIE=1" en une seule commande.

Bonne soirée.

Guy.


Top
 Profile  
 
PostPosted: Wed 01 Feb 2012, 01:14 
Offline

Joined: Tue 21 Jul 2009, 15:01
Posts: 65
Bonsoir à tous,

Pour utiliser les timers il faut mettre le fusible WATCHDOG TIMER à enable .
C'est bien ca ?

J'utilise le module CCP en capture.

Cordialement,
bypbop


Top
 Profile  
 
PostPosted: Wed 01 Feb 2012, 10:03 
Offline

Joined: Mon 25 Jan 2010, 22:48
Posts: 344
@Guy : merci pour ces precisions sur GIiE

Malheureux ! Ne touche pas au watchdog timer ! Le watchdog timer fait redemarrer le pic quand il arrive au bout de son compteur. Ce n'est probablement pas ca que tu veux.

Je pense que tu n'as pas encore besoin du CCP...

Alors un peu de lecture, cas pratique de l'utilisation d'un timer :
[url= Corner - Interruption[/url]

Si tu as encore des problèmes, dis nous : 
1) ce que tu veux faire
2) ce que tu as fait
3) ce que ton pic fait

Je te rassure, les timers c'est toujours un peu difficile au début.

_________________
Équipe Poivron
Coupe 2012 : Équipe Poivron (73e)
Coupe 2011 : Équipe Poivron (122e) - Prix des équipes !
Coupe 2010 : Équipe Poivron (78e)

Passez voir le Portail des équipes


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 98 posts ]  Go to page Previous  1, 2, 3, 4, 5 ... 7  Next

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You can post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group