Prog µcontrolleur : Ports et pointeurs ...

Prog µcontrolleur : Ports et pointeurs ... - C - Programmation

Marsh Posté le 22-11-2007 à 19:47:24    

Salut!
 
Je dois programmer un microcontrolleur F310XP. Pour cela, j'utilise l'IDE Silicon laboratories, et sdcc.
 
J'ai une librairie de base, qui définis un le port P2: il est sur 8 bits, 4 bits pour les boutons et 4 bits pour les leds. Je doit programmer P2. Voila l'énnoncé.
 
Maintenant, je veux créer une fonction pour allumer certaines leds, et eteindre d'autre... Le proto:

Code :
  1. void UI_Leds (char led0, char led1, char led2, char led3);
  2. /* Args: trois valeurs possibles:
  3.  0: allume la Led concernée
  4.  1: eteint la Led concernée
  5.  2: Ne change pas l'état de la Led concernée
  6.  Retour: void
  7. */


 
Le seul hic, c'est que mon P2 n'est pas accessible depuis la fonction, donc, normal, je fais un pointeur.
 

Code :
  1. // Allume éteint les leds
  2. void UI_Leds (char *port, char led0, char led1, char led2, char led3){
  3. /* Args: trois valeurs possibles:
  4.  0: allume la Led concernée
  5.  1: eteint la Led concernée
  6.  2: Ne change pas l'état de la Led concernée
  7.  Retour: void
  8. */
  9. char P2 = *port;
  10. if (led0 == 1)
  11.  P2 = P2 | 0x10 ; // 0001
  12. else if (led0 == 0)
  13.  P2 = P2 & ~0x10 ; // 1110
  14. if (led1 == 1)
  15.  P2 = P2 | 0x20 ; // 0010
  16. else if (led1 == 0)
  17.  P2 = P2 & ~0x20 ; // 1101
  18. if (led2 == 1)
  19.  P2 = P2 | 0x40 ; // 0100
  20. else if (led1 == 0)
  21.  P2 = P2 & ~0x40 ; // 1011
  22. if (led3 == 1)
  23.  P2 = P2 | 0x80 ; // 1000
  24. else if (led1 == 0)
  25.  P2 = P2 & ~0x80 ; // 0111
  26. *port = P2 & 0x0F;
  27. *port = P2 | 0xF0;
  28. }


 
Le seul truc qui peut aider, et encore, je ne sais pas ce que cela signifie réellement:

Code :
  1. sfr P2       = 0xA0;    //ds le header de la lib du microcontrolleur


 
note: j'appelle mes fonctions dans mon main via:
 

Code :
  1. if (UI_Boutons (&P2,0,0,2,2)) UI_Leds (&P2,0,0,0,0);
  2.  else UI_Leds (&P2,1,1,1,1);


 
Et pas d'erreur de compilation :/
 
Mais là rien ne marche :/ Alors si vous pouviez m'aider, ou me donner une autre solution que les pointeurs? Merci d'avance :)


Message édité par rc_jk78 le 22-11-2007 à 19:52:08
Reply

Marsh Posté le 22-11-2007 à 19:47:24   

Reply

Marsh Posté le 22-11-2007 à 21:17:39    

Salut, j'ai jamais programmé de microcontrolleur en C, uniquement en ASM mais je vais essayer de te donner plusieurs points
 
- ta fonction UI_Leds a l'air bonne dans l'ensemble mais je pense que tu peux l'améliorer en enlevant la nécessité d'avoir UI_Boutons.
L'idée c'est que la valeur d'un bit de poids fort dans P2 est directement modifiée par la valeur d'un bit de poids faible. Tu as l'air d'utiliser une logique bit = 0 pour courant qui passe (j'ai oublié le terme) donc je vais supposer que P2.0 = 0 signifie que le bouton 1 est appuyé (ou a été appuyé, voir plus loin) et donc que la led 1 doit être allumée donc P2.4 = 0. Au final, tu peux simplifier le tout en une seule ligne correspondante à 3-4 instructions ASM :

Code :
  1. *P2 = (*P2 & 0x0F) * 16 + (*P2 & 0x0F);

Tu auras peut-être besoin de détailler cette ligne en plusieurs mais je crois pas.
- Maintenant, il faut voir à quel moment cette ligne va être exécutée. Je ne sais pas quel est l'architecture derrière mais je pense qu'aucun des boutons ne soit relié à une interruption externe (sur une patte du microcontrolleur). Mais je suppose qu'il y a un CPL qui se charge de fournir sur une des pattes P2 correspondant à un bouton un signal qui correspond à l'état demandé, peut-être avec une mémoire temporaire dans le cas d'un bouton poussoir. Donc l'état de P2 est cohérent à la demande à chaque fois que tu exécute les instructions qui allument/éteignent les leds. Tu as donc 2 choix possibles pour çà :
  - soit une boucle dans le main mais tu ne contrôle pas l'utilisation en ressources sur le microcontrolleur (comme toutes les boucles en général)
  - soit en ajoutant une interruption "virtuelle" (contrairement à externe) à base de timers (cette solution ne fonctionne que si ils sont dispos dans le microcontrolleurs et je ne connais pas du tout le F310XP). L'idée, c'est que tu as 2 ou 3 registres qui gèrent un ou plusieurs timers. Généralement (dans ce que j'ai déjà vu), un registre gère le paramétrage de l'activation des timers et des interruptions associées et un ou deux autre registres gèrent le temps du timer, 2 registres multipliés qui constituent le nombre de cycles processeur pour choisir la durée par exemple. Là tu dois donc faire en sorte que les instructions d'allumage/extinction des leds soient gérées dans l'interruption et non dans le main. Généralement, en ASM, on place le code qui correspond à une interruption à un endroit spécifique dans la mémoire du microcontrolleur. Il y a une correspondance entre l'endroit dans la mémoire et l'interruption ciblée. Ceci doit être expliqué dans la doc du microcontrolleur. Il faut donc que tu trouves l'instruction du compilateur qui convient à cela pour lui dire où (en mémoire) mettre le code compilé obtenu. Ensuite ça devrait fonctionner.
 
Voilà, j'espère que c'est suffisamment clair :hello:


Message édité par TheRom_S le 22-11-2007 à 21:19:00

---------------
The Rom's, à votre service
Reply

Marsh Posté le 22-11-2007 à 22:06:54    

Merci d'avoir répondu :D
 
Mais le seul hic, c'est que j'ai 2 fonctions différentes: je veux dire que ce n'est pas parceque j'appui sur le bouton 1 que la led 1 doit s'allumer . La fonction ui_led me permettrais aussi d'afficher des codes d'erreurs, ou d'autre choses comme des messages de bon fonctionnement. Donc, je ne peux pas appliquer ta solution 1, car ce n'est pas ce que je veux . Donc, ca ne marche pas ...
 
"soit une boucle dans le main mais tu ne contrôle pas l'utilisation en ressources sur le microcontrolleur (comme toutes les boucles en général) "
C'est tout à fait ca :) On utilise une bouble while()
 
 
Si je peux reformuler ma question, c'est juste que je ne comprends pas pourquoi je peux utiliser mon P2 dans ma fonctio main, et pas dans les autres fonctions. Pour y remédier, j'ai voulu faire passer l'addresse de P2 par un pointeur: mais ca ne fonctionne pas :/
 
Je referais des tests dans la semaine, pour te tenir au courant :)
 
En tout cas, merci de ton aide :D


Message édité par rc_jk78 le 22-11-2007 à 22:08:31
Reply

Marsh Posté le 22-11-2007 à 22:14:24    

Comme je t'ai dit, je n'ai jamais programmé de microcontroller directement en C donc je ne peux pas t'aider plus maintenant. Si ça ne fonctionne pas avec le port ou son pointeur, c'est qu'il doit y avoir une autre subtilité. Peut-être que P2 est est déclaré static dans le main et gêne la déclaration dans la fonction (je ne sais pas trop) ou alors il y a des méthodes particulières pour utiliser les pointeurs avec les microcontrolleurs. Essaie de lire la doc du compilateur, la solution doit se trouver de ce côté. Bonne chance :hello:


---------------
The Rom's, à votre service
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed