[PIC C18] pointeurs de pins pour pwm
Répondre à la discussion
Affichage des résultats 1 à 15 sur 15

[PIC C18] pointeurs de pins pour pwm



  1. #1
    Bouteille51

    [PIC C18] pointeurs de pins pour pwm


    ------

    Bonjour,

    Je me permet de poster ce message en doublon avec un autre forum d'electronique dans le but d'avoir le plus d'avis possible sur la question, j'espere ne pas violer une regle de la charte en faisant ceci.
    (http://www.abcelectronique.com/forum...ad.php?t=68001)

    j'ecris un message sur ce forum car j'ai un petit souci concernant l'ecriture d'un programme en C pour la gestion de pluseurs pwm en software sur un pic18f252.
    Le but de ce programme est de pouvoir gerer autant de pwm que désiré (en etant bien sur limité par la vitesse d'execution) mais toutes definies par une meme frequence (et donc un seul timer).

    Je pense m'en etre sorti pour ce qui est de la programmation de l'algo et du programme en general mais un probleme que je n'avais pas anticipé met un peu de plomb dans l'aile à mon programme.

    En effet, pour mettre successivement à 1 ou à 0 les pins associés a mes pwms je voulais utiliser un tableau de pointeurs vers les bits des pins (pensant que les booleens me sauveraient). Ainsi dans ce tableau, j'aurais pu avoir acces aux bits des buffers des pins et je n'aurais plus eu a me soucier dans l'algo des noms des ports etc... ca m'aurait meme permis (et c'est le but) de pouvoir utiliser des pins de ports differents pour les differentes sorties de mes pwms.

    Or, au moment de compiler j'ai eu l'agreable surprise de m'apercevoir que les booleens n'existent pas en C18 (eheh) et ensuite qu'il etait impossible de recuperer l'adresse (et donc de creer un pointeur) vers les bits des structures des ports.

    En fait je m'apercois que c'est apparement une caracteristique intrinseque du C puisqu'il semble interdit de recuprer l'adresse de champs de bits.

    Bref, je me retrouve donc un peu coincé dans cette logique et je ne sais plus trop comment faire pour arriver a gerer ce probleme.


    Voila l'exemple de ce que j'avais programmé et que je comptais faire :

    // Associate port pins to pointers used in pwm functions

    pwm_pins[0]=&(LATBbits.LATB0);

    pwm_pins[1]=&(LATBbits.LATB1);

    pwm_pins[2]=&(LATBbits.LATB2);



    // Start with all the pins at 0 (so we go to the new cycle block in the interruption)

    *(pwm_pins[0])=0;

    *(pwm_pins[1])=0;

    *(pwm_pins[2])=0;

    Ainsi, à chaque index du tableau correspondait une pwm (pour lequel je stocke dans d'autres tableaux le duty cycle etc...) et j'avais sous le meme index dans ce tableau directement le pin du port a modifier.

    Voila mon probleme et j'aurais voulu savoir si quelqu'un avait une idée pour pouvoir conserver ce systeme d'index pour acceder aux pins sans forcement faire un switch a chaque interruption sur l'index et les noms de pins...

    merci pour votre aide, n'hesitez pas a me demander plus de lignes de codes ou des details concernant le reste du programme...

    merci d'avance pour votre aide

    Romain.

    -----

  2. #2
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    Je pensais peut etre a un tableau de pointeurs vers des unsigned (definition des ports dans les typedef de pic18f252.h) pour savoir sur quel port operer.
    Puis un tableau d'indice de decalage de bit pour savoir sur quel bit du port operer...

    pour passer un pin a un ca donnerai quelque chose comme ca :

    index_pwm=4;
    *(portPointers[index_pwm])=(*(portPointers[index_pwm]))|1<<pinIndex[index_pwm]

    c'est incomprehensible ? lol

  3. #3
    sdec25

    Re : [PIC C18] pointeurs de pins pour pwm

    Salut,
    Effectivement on ne peut pas pointer sur des bits. Le C est un langage assez bas niveau, un pointeur n'est qu'un nombre entier donc si l'adresse d'un octet est 10, l'octet suivant est à l'adresse 11 et il n'y a rien entre les 2.
    Les différentes solutions pour travailler au niveau des bits :
    • Instructions assembleur
    • struct avec champ de bit
    • opérateurs sur bits (<<, >>, &, |)

    Tu as trouvé toi-même la solution (il faut utiliser à la fois l'adresse du registre et le numéro du bit) :
    Citation Envoyé par Bouteille51 Voir le message
    Je pensais peut etre a un tableau de pointeurs vers des unsigned (definition des ports dans les typedef de pic18f252.h) pour savoir sur quel port operer.
    Puis un tableau d'indice de decalage de bit pour savoir sur quel bit du port operer...
    Il n'y a pas plus simple mais plutôt qu'utiliser 2 tableaux je définirais une structure pour pointer les pins :
    Code:
    typedef struct {
    char* pPort;
    char numBit;
    }
    adresse_bit;
    
    // Fonction pour activer les bits
    void activerBit(adresse_bit* adresse, char etat);
    Si tu travaillais en C++ tu pourrais définir une classe bit similaire à cette structure avec une méthode Set(etat) ou l'opérateur =. Ça donnerait :
    Code:
    Bit bit(LATB, 5);
    bit = 1;
    Dernière modification par sdec25 ; 02/09/2010 à 12h42.

  4. #4
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    Ah super reponse, merci bcp pour ton aide et ta confirmation

    Effectivement l'idée de la struct est tres bonne egalement, je pourrai meme a la limite y associer tous les autres parametres de mes pwms et ne faire qu'une seul tableau de struct...

    Je suis en effet beaucoup plus familier avec le C++ et me retrouver a coder en C est parfois deroutant (j'ai pas dit degoutant lol) mais pas le choix pour ce qui est des microcontrolleurs pics donc on s'adapte comme on peut... J'imagine que les mallocs ce n'est pas trop possible et rentable sur un microcontrolleur pour mon tableau de structs... c'est tellement bien les objets avec constructeurs etc...

    il me reste a trouver dans quel sens decaler a partir de la declaration du champ de bits qui est faite pour les ports... je pense que le dernier pin (par exemple le pin7 qui est declaré comme le dernier bit du champ) pour un port doit se retrouver au bit de droite (oups pardon de poids minimal)... je vais de toute facon verifier ca

    merci beaucoup en tout cas et desolé pour ce long exposé pour un probleme si court

    Je suis a l'ecoute d'autres suggestions eventuelles !

    Merci !

  5. A voir en vidéo sur Futura
  6. #5
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    Je ne comprends d'ailleurs toujours pas pourquoi les booleens ne sont pas implementés pour ces compilateurs... si codés sur 1 bit ils auraient peut etre pu me sauver...

  7. #6
    sdec25

    Re : [PIC C18] pointeurs de pins pour pwm

    J'imagine que les mallocs ce n'est pas trop possible et rentable sur un microcontrolleur
    Ça doit être possible mais il ne faut pas en abuser Je ne sais pas si les lib C18 gèrent bien les allocations dynamiques, voir dans la doc du compilateur.

    Sinon, par convention bit n°0 = poids faible (1<<0), bit n°7 = poids fort (1<<7).

    Je ne comprends d'ailleurs toujours pas pourquoi les booleens ne sont pas implementés pour ces compilateurs... si codés sur 1 bit ils auraient peut etre pu me sauver...
    Ça ne résoudraient pas le problème, les booléens seraient stockés sur un mot et pas sur 1 bit, et on ne pourrait toujours pas adresser les bits avec les pointeurs classiques.

  8. #7
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    Citation Envoyé par sdec25 Voir le message
    Ça doit être possible mais il ne faut pas en abuser Je ne sais pas si les lib C18 gèrent bien les allocations dynamiques, voir dans la doc du compilateur.

    Sinon, par convention bit n°0 = poids faible (1<<0), bit n°7 = poids fort (1<<7).


    Ça ne résoudraient pas le problème, les booléens seraient stockés sur un mot et pas sur 1 bit, et on ne pourrait toujours pas adresser les bits avec les pointeurs classiques.
    Hihi ouais je vais pas abuser et eviter les mallocs, tant qu'on a pas droit aux new de toute facon je ne suis pas fan

    Ah ben super pour l'info sur les bits, meme pas besoin de tester, je n'ai plus qu'a mettre ca en oeuvre ce soir en rentrant du boulot (apres l'apero )

    Ok pour les booleens... tant pis alors
    Sans remettre en question les gourous createurs du C j'aurais trouvé ca pratique un booleen codé sur un bit, et donc l'acces au champs de bits

    En tout cas je te remercie, j'avoue que j'avais un peu peur de ne pas avoir de reponse, je ne sais jamais sur quel forum poster pour ce qui concerne la programmation des pics en C...

    Si j'arrive a faire marcher mes pwms, t'auras une dedicace eheh

  9. #8
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    mais alors quel est le type de la valeur qui revient lorsqu'on accede a portabits.RA0 par exemple ? un unsigned char avec uniquement le bit d'interet à 1 (si la valeur de RA0 est a 1)?

  10. #9
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    bon alors jusque la j'ai fait ca :


    typedef struct
    {
    unsigned char * port_ref;
    unsigned char bit_ref;
    }pin_ref;



    // Pointers to the real pins of the port associated to the PWMs

    pin_ref pwm_pins[PWM_NB];




    /*------------ FUNCTIONS ------------*/


    unsigned char pwm_getPin(unsigned char pwmNum)
    {
    return (*(pwm_pins[pwmNum].port_ref)) & (1<<pwm_pins[pwmNum].bit_ref);
    }

    void pwm_setPin1(unsigned char pwmNum)
    {
    (*(pwm_pins[pwmNum].port_ref))=(*(pwm_pins[pwmNum].port_ref)) | (1<<pwm_pins[pwmNum].bit_ref);
    }


    void pwm_setPin0(unsigned char pwmNum)
    {
    (*(pwm_pins[pwmNum].port_ref))=(*(pwm_pins[pwmNum].port_ref)) & ~(1<<pwm_pins[pwmNum].bit_ref);
    }



    void pwm_init()

    {

    // Associate port pins to pointers used in pwm functions

    // This pwm is associated to PortC bit0 (RC0)

    pwm_pins[0].port_ref=(&LATCbits);
    pwm_pins[0].bit_ref=0;

    // This pwm is associated to PortC bit1 (RC1)

    pwm_pins[1].port_ref=(&LATCbits);
    pwm_pins[1].bit_ref=1;

    // This pwm is associated to PortC bit2 (RC2)

    pwm_pins[2].port_ref=(&LATCbits);
    pwm_pins[2].bit_ref=2;



    // Start with all the pins at 0 (so we go to the new cycle block in the interruption)

    pwm_setPin0(0);

    pwm_setPin0(1);

    pwm_setPin0(2);



    // Init the duty cycles for the pins (only writing in the buffer, the interrupt will copy it (changing pointers) when needed (begin of each cycle))

    pwm_dcPtrBuffer[0]=128;

    pwm_dcPtrBuffer[1]=255;

    pwm_dcPtrBuffer[2]=50;



    }
    J'aurais voulu savoir si ca a l'air correct.
    La seule chose qui me chagrine c'est qu'a chaque appel de getpin ou set_pin dans mon interruption je vais avoir un saut vers la fonction qui coute des cycles mais je crois que c'est un minimum pour la lisibilité...

    Pour ma question precedente, je pense qu'en fait le retour est un unsigned char mais avec le resultat du bit etant shifté au bit de poid minimal... soit si j'ai bien compris le resultat d'un unsigned char >0... mais la j'extrapole peut etre

    En tout cas si je veux faire un pwm_getPin(2)==1 il faudrait que je modifie la fonction pwm_getPin pour qu'elle fasse "return (*(pwm_pins[pwmNum].port_ref)) & (1<<pwm_pins[pwmNum].bit_ref) >0"... mais c'est pas grave j'enleve juste le ==1 pour l'instant.

    merci de vos conseils.
    Dernière modification par Bouteille51 ; 02/09/2010 à 16h19.

  11. #10
    sdec25

    Re : [PIC C18] pointeurs de pins pour pwm

    Pour ma question precedente, je pense qu'en fait le retour est un unsigned char mais avec le resultat du bit etant shifté au bit de poid minimal... soit si j'ai bien compris le resultat d'un unsigned char >0... mais la j'extrapole peut etre
    Je pense que oui, mais la question n'a pas vraiment de sens, tout dépend du contexte et du compilateur.
    "if (RA0)" peut se traduire par une instruction assembleur permettant de tester un bit.
    "if (RA0)" peut aussi se traduire par un masque & et un test sur le mot (<> 0x00).
    "char test = RA0;" se traduit probablement par "si le bit RA0 est actif alors on copie 1 dans test, sinon 0"

    MPLAB permet d'afficher le code assembleur généré par le compilateur, c'est très instructif de l'analyser, tu verras que ce n'est pas toujours optimisé et ça prend + d'instructions que si on codait directement en assembleur.

    Sinon le programme a l'air correct.

  12. #11
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    Citation Envoyé par sdec25 Voir le message
    Je pense que oui, mais la question n'a pas vraiment de sens, tout dépend du contexte et du compilateur.
    "if (RA0)" peut se traduire par une instruction assembleur permettant de tester un bit.
    "if (RA0)" peut aussi se traduire par un masque & et un test sur le mot (<> 0x00).
    "char test = RA0;" se traduit probablement par "si le bit RA0 est actif alors on copie 1 dans test, sinon 0"

    MPLAB permet d'afficher le code assembleur généré par le compilateur, c'est très instructif de l'analyser, tu verras que ce n'est pas toujours optimisé et ça prend + d'instructions que si on codait directement en assembleur.

    Sinon le programme a l'air correct.

    Ok je comprends que ma question en demandait un peu trop par rapport a ce qui peut arriver au moment de la compilation...
    Si un jour j'arrive a me motiver a apprendre les bases assembleurs je pourrais peut être analyser le code généré mais j'avoue que je n'ai jamais eu assez de motivation jusqu'à présent...

    Une dernière chose cela dit, pour l'instant tout semble correct du point de vue du programme (ca compile mais pas encore testé lol) mais il me reste un "souci" a regler, en effet mon pointeur qui designe le port dans la structure est un (unsigned char *) or le port est defini de la maniere suivante :

    Code:
    extern __sfr __at 0xf89 LATA;
    typedef union {
    	struct {
    		unsigned LATA0:1;
    		unsigned LATA1:1;
    		unsigned LATA2:1;
    		unsigned LATA3:1;
    		unsigned LATA4:1;
    		unsigned LATA5:1;
    		unsigned LATA6:1;
    		unsigned :1;
    	};
    } __LATAbits_t;
    
    extern volatile __LATAbits_t __at 0xf89 LATAbits;
    Lors de la compilation j'ai bien sur un mismatch type lors de l'affectation de &LATAbits a mon pointeur... Un simple cast devrait fonctionner (ca compile et je pense que je pourrai acceder aux valeurs correctement) mais je me demandais si il etait possible d'affecter directement un pointeur vers le type defini et eviter le cast...

    Je n'arrive pas a trouver la declaration correcte pour arriver a pointer vers cette union{struct{}}...

    Si vous aviez un indice pour ce dernier point ca pourrait etre super

    merci de votre aide !

  13. #12
    sdec25

    Re : [PIC C18] pointeurs de pins pour pwm

    Essaie avec &LATA, ça devrait marcher puisque LATA n'est pas une struct.
    Si toutefois ça ne fonctionne pas, le cast est justement fait pour ça.

  14. #13
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    Citation Envoyé par sdec25 Voir le message
    Essaie avec &LATA, ça devrait marcher puisque LATA n'est pas une struct.
    Si toutefois ça ne fonctionne pas, le cast est justement fait pour ça.
    Et....... BUILD SUCCEEDED !!!!

    Super je te dois une fiere chandelle, merci beaucoup pour tes conseils !

    Je pensais avoir deja testé &LATA mais en fait non

    Je vais maintenant vérifier que tout marche correctement et je pourrai peut être enfin faire marcher cette led rvb correctement

    @ bientot et merci encore je donnerai des news et puis qui sait peut etre qu'un jour je pourrai aider qqun a mon tour sur ce forum

    bonne continuation !

  15. #14
    RISC

    Re : [PIC C18] pointeurs de pins pour pwm

    Salut,

    Regardes le fichier header de ton micro ( pic18f252.h ) à titre d'exemple.
    Tu trouveras la définition de tous les registres sous forme de structures de champs de bits.
    Ces structures sont optimales pour affecter ou tester un bit. Ne jamais faire une opération sur un champ de bits...le code généré explose (voir la fenêtre Disassembly Listing)

    a+

  16. #15
    Bouteille51

    Re : [PIC C18] pointeurs de pins pour pwm

    Citation Envoyé par RISC Voir le message
    Salut,

    Regardes le fichier header de ton micro ( pic18f252.h ) à titre d'exemple.
    Tu trouveras la définition de tous les registres sous forme de structures de champs de bits.
    Ces structures sont optimales pour affecter ou tester un bit. Ne jamais faire une opération sur un champ de bits...le code généré explose (voir la fenêtre Disassembly Listing)

    a+
    Effectivement, le code de definition du port que j'ai copié dans mon precedent message est tiré du pic18f252.h

    merci pour le conseil.

Discussions similaires

  1. PIC pwm pour servo
    Par ben1015 dans le forum Électronique
    Réponses: 15
    Dernier message: 31/05/2010, 10h47
  2. [PIC C18] problème pour activer 2 sorties en même temps
    Par invitec89d22d7 dans le forum Électronique
    Réponses: 7
    Dernier message: 05/03/2010, 22h26
  3. Transmettre information PIC -> pins
    Par invite304155d6 dans le forum Électronique
    Réponses: 9
    Dernier message: 21/07/2009, 13h11
  4. Réponses: 8
    Dernier message: 11/05/2009, 11h52
  5. generateur pwm pour mcc a pic
    Par chirvane dans le forum Électronique
    Réponses: 2
    Dernier message: 22/04/2009, 08h45
Découvrez nos comparatifs produits sur l'informatique et les technologies.