Modérateurs: Modération Forum DIY, Modération Forum Installations, Le Bureau de l’Association HCFR • Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 23 invités

J'ai besoin d'aide pour comprendre interruption sur PIC

Message » 11 Mar 2005 9:04

Bonjour à tous,

je suis en train de travailler sur la carte controleur de mon CD DIY. Cette carte va gérer tous les périphériques inhérents au lecteur, notamment le Drive (via bus phillips DSA), une carte avec les boutons de commande (lecture, pause, stop, etc) , un LCD et un décodeur RC5 pour la télécommande. :wink:

Je précise que je suis newbie en pic, et que je sais que je ne commence pas par le plus simple. Néanmoins, je me suis déjà amusé avec mon PIC à faire des choses simples, donc je comprends à peu près ce qui se passe. Et je passe beaucoup de temps sur le forum de microchip, ainsi qu'à lire le datasheet du µC, mais les subtilités techniques ajoutées à l'anglais me laisse penser quil faut d'abord qu'on m'explique en Français avant d'aller plus loin dans l'analyse. :oops:

Le PIC en question est le PIC18F452 et je programme en C (compliateur mCC18 de Microchip). Ne me parlez pas en Assembleur, j'y comprends rien :lol:

J'ai décidé de m'orienter vers les interruptions pour gérer tout cela.
A mon sens (et c'est là que j'ai besoin de vous :idee: ), y'a 3 sources d'interruptions différentes :

1- La conversion A/D (induite par l'appui sur un bouton) : chaque fois que la conversion se termine (i.e, que le PIC a décelé un changement de niveau sur la PIN A/D (RA0 dans mon cas) et qu'il a calculé la valeur, une interruption est génerée. Pour le PIC en question, l'interruption se génére en fin de conversion A/D et pas en début.

Pb : je n'arrive pas à savoir comment programmer l'interruption associée à l'A/D ? J'ai les procs d'A/D qui marchent bien, mais comment intégrer l'interruption là-dedans ?

2- Les data reçues du drive En simplifiant fortement, le protocol DSA s'apparente à un protocole série. Y'a 3 signaux (data, strobe, acknoledge).
A mon sens, quand le CD tourne, le PIC recoit sur la ligne DATA des infos style la durée de lecture. Donc toutes les secondes, le µC recoit une nouvelle donnée à afficher sur le LCD...
Peut-on considérer cela comme une interruption qui apparait toutes les secondes ? Ou alors ce traitement fait partie d'une boucle infinie ?

3- Une récéption IR de la telecommande. Il faut que le PIC embraye sur le décodage du code et fasse l'action derrière. Par exemple, en cours de lecture, le bouton STOP de la teleco est appuyé. Un peu comme pour l'A/D, il faudrait que l'interruption soit générée lorsque le décodage du code RC5 est terminé, pas au début..


Voilà le tableau
J'arrive pas à écrire ma procédure de gestion des interruptions avec ces 2 ou 3 sources.

Il me semble que les boutons et l'IR doivent être considérées comme des interruptions de haute priorité, tandis que la réception en lecture de données du drive (encore une fois si c'est une interrutpion) de priorité basse, i.e. qu'elle sera court-circuitée par une interrutpion de priorité haute.

Désolé si c'est un peu long, mais j'ai besoin de comprendre ce que je dois faire.

Merci.
ZERS
 
Messages: 2165
Inscription Forum: 17 Juin 2002 16:48
Localisation: Isère (38) mais Gône
  • offline

Message » 11 Mar 2005 11:58

patyat
 
Messages: 529
Inscription Forum: 20 Nov 2001 2:00
Localisation: Tours, France
  • offline

Message » 11 Mar 2005 13:50

Pourle cours Bigonnoff, oui mais ses exemples ne traitent que le cas d'une source unique d'interruption. Gérer plusieurs sources c'est moins cool.

Et our l'autre oui aussi, rien de bien concluant.
ZERS
 
Messages: 2165
Inscription Forum: 17 Juin 2002 16:48
Localisation: Isère (38) mais Gône
  • offline

Message » 11 Mar 2005 14:34

Daisy ne fournit pas un kit avec un micro préprogrammé pour gérer le drive ?
Johnix
 
Messages: 1233
Inscription Forum: 10 Oct 2002 15:32
  • offline

Message » 11 Mar 2005 14:49

Johnix a écrit:Daisy ne fournit pas un kit avec un micro préprogrammé pour gérer le drive ?

Si mais j'ai envie d'apprendre :wink: Rien ne presse...
ZERS
 
Messages: 2165
Inscription Forum: 17 Juin 2002 16:48
Localisation: Isère (38) mais Gône
  • offline

Message » 11 Mar 2005 23:20

Je ne sais pas précisement comment marche un pic mais en général ça se passe comme ça sur un µ-proc :

- Une interruption est liée à une ressources particulière. Leur priorité est en générale fixée et tu ne peux pas la changer.
(par exemple sur un Atmel l'interruption 0 a la plus haute priorité, l'interruption 31 la plus faible). Le rôle de la priorité est d'ordonner le traitement si plusieurs interruptions sont à traiter simultanément.

- Si tu es hors interruption, la 1ère interruption qui se déclenche envoie le programme dans le sous-programme d'interruption associé...sauf si les interruption sont interdites. Basiquement c'est le cas tant que tu n'as pas activé les interruptions (pour l'initialisation ou pour faire une écriture de données partagées) ou si tu es en cours de traitement d'interruption.

- Si tu es en cours de traitement d'interruption, et qu'une interruption arrive, elle est stocké (on peut s'amuser avec plusieurs niveau d'interruptions mais bon). Elle sera traité dès que tu auras fini de traiter la première interruption. Le stockage est en général un bit qui passe à 1 pour dire qu'il faut traiter l'interruption machin. Si plusieurs interruptions machins arrivent avant que la première ne soit traitée, le proc n'en traitera donc qu'une seule.

- Si plusieurs interruptions différentes arrivent pendant le traitement d'une interruption. A la fin du traitement en cours, le proc ira traiter en 1er celle de plus haute priorité

Comme tu ne fais pas d'assembleur l'integration des interruptions dans un code C/C++ passe par des directives particulière (désolé j'ai oublié le nom préçis).
En général il faut concrêtement placer un #pragma "interruption machin" juste avant le sous-programme lié à l'interruption_machin. Au niveau du code il ne te reste donc plus qu'à activer l'interruption_machin et d'activer les interruptions générale (à faire dans le programme principal, à la fin des initialisations) pour que ça marche.
Le plus simple pour comprendre est de regarder un code d'exemple spécifique au pic.

- Le 1 ne devrait pas poser de souci

- Pour le 2, c'est typiquement un truc à faire sous interruption. Si le bus ne va pas trop vite tu peux échantillonner le bus à intervalle régulier avec une interruption (en utilisant un timer) et décoder "à la volée" les commandes. Sinon tu peux choper le bit qui indique un début de commande et t'arranger pour déclancher une interruption qui va alors s'occuper de recevoir la commande. Si tu ne peux pas te permettre de rester trop longtemps dans l'interruption (comprendre s: i la durée de réception de la commande est long) alors ça va commencer à devenir assez technique...

- Le 3 est similaire mais encore plus complexe à traiter. Comme ton pic ne va pas savoir traiter le code IR seul, il faut que tu t'en occupe toi même. 2 possiblités :
- si ton code a pas mal d'action à faire à des moments précis, le plus simple est de coder la réception RC-5 dans le programme principal et de gérer les autres taches par interruption.
- sinon tu peux coder la reception RC-5 sur interruption (déclenché par chg d'état d'une patte par exemple) mais ça va pas être évident...

Pour résumer : ce n'est pas évident du tout à faire ton truc...

Pour commencer essaye peut-être de simplifer la tâche en limitant le nombre de tâche à traiter par le pic.
Peut-être qu'une solution serait de mettre 2 PICs. Un pour la partie affichage/DSA, un autre pour la partie RC-5/clavier et de faire en sorte que le 2ème envoie les infos nécessaire au 1er par une simple liaison série (géré en hard par le pic si je n'abuse).
Robinet
 
Messages: 1378
Inscription Forum: 09 Jan 2001 2:00
Localisation: Verrières (91)
  • offline

Message » 12 Mar 2005 5:43

Robinet

Ca c est une explication claire :lol:
JLD
 
Messages: 2174
Inscription Forum: 11 Jan 2002 2:00
Localisation: Guerande
  • offline

Message » 12 Mar 2005 15:40

Salut Zers,

Un autre élément de réponse :

Je te conseille de procéder par étapes :

Tester et comprendre comment implémenter la gestion des IT en C
Les PIC18Fxxx possèdent 2 niveaux de priorité, haute et basse.
Chaque source d'IT peut être affectée à un de ces 2 niveaux.
Ensuite, il faut autoriser le traitement de ces IT. Ici, 2 bits, respectivement pour les priorités hautes et basses, te permettent de valider ou pas ces catégories d'IT.

Comme il n'existe que 2 vecteurs IT ( haute et basse ), il faut que le le code d'interruption associé aillent lire les registres concernés pour déterminer quelle source a généré une IT ( Timer, CAN... ).
Pour cela, il faut te référer à la doc de ton compilateur, des exemples doivent exister, au travers de directives #pragma bien souvent.

Un exemple pour vérifier que tout fonctionne bien est d'utiliser un timer et de le programmer pour générer une IT chaque seconde. Le code dans le main peut se résumer ainsi :

int main(void)
{

' Initialisation du timer sur 1 seconde
' Définition de la priorité du timer ( pour l'instant il n'y en a qu'une, donc peu importe,
' mettons basse priorité )
' Autorisation de l'IT du timer
' Autorisation générale des IT de priorité basse

' Boucle infinie : ton code ne fait rien, si ce n'est attendre qu'une IT se produise

while(1);
}


' Ici, c'est un exemple, te référer a la doc de ton compilo pour connaître la syntaxe exacte
#pragma interrupt void IT_low_priority(void)
{

' Si c'est l'IT timer qui a généré l'IT Alors
' Faire toggler une GPIO, une sortie par exemple
' Remettre a zéro le bit d'IT du timer pour éviter de retraiter cette IT

' Lorsque tu voudras traiter plusieurs IT, tu pourras rajouter d'autres tests comme ci-dessus

}

Dans le datasheet des pic18fxxx, il y a deux pages a lire et bien comprendre, pages 75 et 76. Utilises http://babelfish.altavista.com/ pour les traduire.

Bon courage :wink:
Fabien
LeFabDuSud
 
Messages: 278
Inscription Forum: 23 Juin 2004 9:40
Localisation: Suisse
  • offline

Message » 15 Mar 2005 12:51

Salut les amis,

merci de vos précisions mais (et ne le prenez pas mal), je savais déjà ce que vous m'avez dit.
Je vais néanmoins reprendre cela à tête reposée, car je suis au taf :( , dur de tout lire entre 2 réunions :lol: :wink:
ZERS
 
Messages: 2165
Inscription Forum: 17 Juin 2002 16:48
Localisation: Isère (38) mais Gône
  • offline

Message » 17 Mar 2005 21:30

Salut,
Je ne connais pas bien les PICs 18F, mais j'ai pas mal bricolé un 16F ;)
Par contre tout en assembleur, je ne sais pas bien comment ça vit en C.
Mais en gros tu as plusieurs sources d'interruption qui peuvent être l'écoulement de l'un des timers, le changement d'état d'une entrée, ou la reception d'un message sur le port série ou I2C du PIC par exemple.
Lorsqu'un de ces évènements apparait, un bit est mis à 1.
Pour activer les interruptions proprement dites, il y a
- un bit qui active le traitement des interruptions : s'il est à 0 aucune interruption n'est traitées. S'il est à 1 les interruptions activées individuellement sont traitées.
- un bit pour activer individuellement chaque interruption

Donc par exemple pour que l'interurption associée au timer 1 soit traitée lorsque le timer est écoulé, il faut que le bit d'activation de l'interruption TMR1 soit à 1 et que le bit d'activation général des interruptions soit à 1.

Même si l'un (ou les deux) de les bits est à 0, le bit t'indiquant que l'évènement est apparu sera quand même mis à 1.
Par contre si les deux bits d'activation sont à 1, l'apparition de l'évènement déclenche en plus un saut vers le sous-programme de traitement des interruptions.
Ce sous programme est unique est est atteint quelle que soit l'interruption. C'est ensuite à toi de tester les bits d'état de ces interruptions pour appeler la fonction qui va bien en conséquence. Ce qui te permet également de choisir les priorités.
Attention, si tu actives les interruptions et que l'évènement était apparu avant, tu va immédiatement passer au sous programme de traitement des interruptions.
A la fin du traitement de l'interruption tu peux retourner à la suite du programme principal.


Je pense que pour le 18F ça doit être un peu plus puissant, mais ça doit rester très proche de ça.

Pour le traitement des codes infra-rouge, il faut appeler régulièrement une fonction qui va scruter ton port d'acquisition, ce qui peut être fait en utilisant l'interruption associée à un timer.
Ensuite c'est assez simple si tu peus te permettre d'arréter tous les autres traitement pendant que tu traites l'ensemble de la réception de la trame IR. C'est beaucoup plus compliqué si tu veux faire plusieurs choses en même temps
Ki
 
Messages: 4427
Inscription Forum: 12 Jan 2003 14:55
  • offline

Message » 18 Mar 2005 11:33

Merci Ki, c'est super clair.
Mais évidemment ta dernière phrase m'inquiète car elle montre le problème auquel je suis confronté :
ki a écrit:Ensuite c'est assez simple si tu peus te permettre d'arréter tous les autres traitement pendant que tu traites l'ensemble de la réception de la trame IR. C'est beaucoup plus compliqué si tu veux faire plusieurs choses en même temps

Il est évident que je ne pourrais me permettre d'arrêter la lecture d'une chanson tant que l'interruption (code IR ou boutton) n'a pas été traitée en entier, l'une des dernières instructions étant de procéder à l'action associée à la récéption du signal. Avec 40Mhz d'horloge ca booste 8) , mais algorithmiquement, je fais deux choses en même temps..
ZERS
 
Messages: 2165
Inscription Forum: 17 Juin 2002 16:48
Localisation: Isère (38) mais Gône
  • offline

Message » 18 Mar 2005 12:57

Salut Zers,

40Mhz, oui, c'est bien assez pour faire ce que tu veux. Il y a 20 ans, avec des CPU qui tournaient a 1MHz, en d'architecture CISC sur 8bit, on savait faire des choses bien plus compliquees que gerer 3 sources hardware decorellees :wink:

Pour resumer, tu as 2 sources serielles a traiter :
1 - les donnes d'affichage en provenance du drive
2 - les commandes en provenance de la telecommande

Et enfin la lecture du clavier, qui est geree par un convertisseur AN, qui delivre une valeur discrete specifique en fonction de la touche appuyee. Corriges-moi si je me trompe.

Il faut traiter maintenant ces 3 evenements grace a des interruptions.
Une regle simple, c'est que le traitement dans le handler d'interrupt ( c'est le code sur lequel est deroute le processeur lorsqu'une IT arrive ) doit etre le plus court possible.
Cette regle permet de simplifier les priorites a assigner aux taches, et surtout, elle permet de gerer plusieurs taches en pseudo temps reel sans gros effort par ailleurs.

Pour le traitement du clavier, tu peux utiliser un timer qui va, toutes les XX ms, lire la valeur du CAN. XX doit etre superieur au temps maximum de conversion AN, sans quoi tu ne vas jamais recuperer de valeur !
Dans ton handler d'IT, en cas d'IT timer, tu lances une conversation AN... sous IT.

Pour le traitements des trames IR, je suppose que tu utilises un port serie du PIC. Si c'est le cas, lorsque ton port serie recois un mot, tu le configures pour generer une IT.
Dans ton handler d'IT, en cas d'IT du port serie dedie pour IR, tu stockes le mot recu dans un buffer circulaire public.

Pour le traitement des infos du drive, je suppose aussi que tu utilises un port serie du PIC. Si c'est le cas, lorsque ton port serie recois un mot, tu le configures pour generer une IT.
Dans ton handler d'IT, en cas d'IT du port serie dedie pour le drive, tu stockes le mot recu dans un autre buffer circulaire public.

Enfin, il te faut traiter l'IT de fin de conversion AN :
Dans ton handler d'IT, en cas d'IT EOC AN, tu lis la valeur de conversion et tu la stockes dans une variable public.

On peut consider qu'il est plus important de ne pas louper un ordre de l'utilisateur, plutot que de rafraichir l'affichage.
Dans ce scenario, tu peux definir les IT :
- Timer
- Port serie IR
- Fin de conv AN
comme hautes.
Et l'IT :
- Port serie drive en reception
comme basse.

Voila, maintenant que tu as tes deux handlers d'IT ( celui de priorite haute, et celui de priorite basse ) qui sont definis, il faut traiter les donnes et flag qu'ils generent.

Dans ton main() donc, tu ecris une boucle sans fin qui va scruter les 2 buffers circulaires et la variable public modifies par les handlers d'IT.

Pour le traitement du clavier, l'info se trouve dans la variable public. Si sa valeur correspond a une touche connue, alors il faut executer l'action prevue.

Pour le traitement de l'IR, tu peux travailler sur l'indice de remplissage du buffer circulaire ( cas ou les trames recues sont de taille fixes ), ou sur le contenu dans la trame elle-meme. Lorsque tu as identifie une trame pertinente, tu executes les actions prevues.

Pour le traitement des infos du drive, meme analyse que pour le traitement de l'IR.

Voila, c'est une approche, mais il en existe bien d'autres :wink:

Pour finir, je n'ai pas decrit ici les commandes a envoyer au drive ( genre lecture de la piste X, arret, pause... ). Je suppose que tu utilises le meme lien serie que pour la lecture des infos en provenance du drive... mais dans l'autre sens.
Dans ce cas, lorsque qu'une commande doit etre envoyee au drive, il faut preparer la trame a envoyer et la stocker dans un buffer. Tu configures ensuite ton port serie pour generer une IT lorsqu'un mot a ete envoye.
Pour initier l'envoie de la trame, tu ecris le premier mot de cette trame de la registre du port serie et tu autorises l'emission sur ce port. Lorsque le mot sera envoye, cela generera une IT.
Dans ton handler d'IT ( de priorite haute, cela va de soi ), si tous les mots n'ont pas ete envoyes, tu envoies le mot suivant. Si tous les mots sont partis, tu stoppes l'autorisation d'emission sur le port serie.

Encore une fois, c'est une approche...

A+,
Fabien
LeFabDuSud
 
Messages: 278
Inscription Forum: 23 Juin 2004 9:40
Localisation: Suisse
  • offline


Retourner vers Sources et DAC

 
  • Articles en relation
    Dernier message