Manipuler bit seul dans un variable en C
Répondre à la discussion
Affichage des résultats 1 à 22 sur 22

Manipuler bit seul dans un variable en C



  1. #1
    invitead51e543

    Manipuler bit seul dans un variable en C


    ------

    Bonjour à tous,

    J'espère que vous allez bien. Juste une petite question :
    En C, peut-on manipuler un bit seul comme en assembleur? Je m'explique : Je récupère des valeurs de contacts sur ma carte (0 ou 1), que je souhaite mettre dans une variable (de 8 bits), sachant que chaque contact à sa place précise dans la variable. Suis je obligé de passer par des décalages de bits et des masques? Ou bien y a t-il des instructions toute faites comme en assembleur :

    Code:
    bcf  nom_de_la_variable, position_du_bit
    bcf  nom_de_la_variable, position_du_bit
    Merci de votre aide & bonne fin de journée

    -----

  2. #2
    Seb.26

    Re : Manipuler bit seul dans un variable en C

    Tu peux le faire avec des variables de type "union" ... mais le plus simple (et le plus portable) reste les masques ...
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  3. #3
    invite936c567e

    Re : Manipuler bit seul dans un variable en C

    Bonjour

    Il n'existe pas d'opération orientée bit dans le langage C.

    En revanche, sur certaines plateformes, on peut trouver des extensions (sous forme de fonctions ou de macros) qui permettent de faire le travail. On peut également en définir soi-même, en faisant appel à des opérations en assembleur (directive "asm"). Mais ce n'est absolument pas portable.

    La meilleure façon de faire reste l'utilisation des masques et/ou des décalages. Lorsque le compilateur est suffisamment intelligent, il est possible qu'il parvienne à détecter l'opération souhaitée et à la traduire par une instruction orientée bit du processeur, si elle existe et s'avère plus avantageuse.

  4. #4
    invitead51e543

    Re : Manipuler bit seul dans un variable en C

    Ok, c'est juste ce que je voulais savoir.
    Merci de vos réponses, et bonne soirée à vous

  5. A voir en vidéo sur Futura
  6. #5
    Jack
    Modérateur

    Re : Manipuler bit seul dans un variable en C

    Il y a les bit fields qui permettent d'accéder à des bits ou groupes de bits sans masques ou décalages.

  7. #6
    invite105cee1c

    Re : Manipuler bit seul dans un variable en C

    par bit field tu entends structure ?
    souvent la notice du compilo utilisé est une bonne aide .

  8. #7
    Jack
    Modérateur

    Re : Manipuler bit seul dans un variable en C

    oui, c'est une structure particulière, avec sa syntaxe. Couplée à une union, ça permet d'accéder à une port directement sous forme d'octet ou bit par bit, ou par groupe de bits.

  9. #8
    invite936c567e

    Re : Manipuler bit seul dans un variable en C

    Les bit fields permettent de déclarer et de manipuler les bits de variables de type entier, au même titre que les masques (et d'ailleurs, même si la syntaxe est différence, le code généré est généralement identique dans les deux cas).

    En revanche, cela ne permet pas de forcer le compilateur à réaliser la mise à un ou à zéro d'un bit particulier à l'aide d'une instruction machine adaptée.

    Autrement dit, le compilateur a autant (ou pas plus) de raison de générer un code différent pour un bit field d'un seul bit et pour un bit field de plusieurs bits que de le faire dans les cas équivalents à base de masques déclarés sur des entiers complets.


    Par ailleurs, la seule écriture d'une succession de bit fields dans le programme ne garantit pas que les bits considérés seront placés consécutivement dans le même octet, mot ou mot long.

    En effet, ce qu'indique la syntaxe du bit field, c'est seulement la taille de l'élément déclaré, et pas sa position dans l'espace adressable.

    Ainsi, huit bit fields d'un bit chacun déclarés consécutivement pourraient très bien occuper huit octets, mots ou mots longs distincts, de même que deux octets déclarés dans une structure struct pourraient occuper deux mots ou deux mots longs distincts.

    Le résultat dépend du réglage des options d'alignement et de compactage des données, lesquelles sont généralement spécifiques au compilateur, et bien souvent totalement extérieures au code source du programme.

  10. #9
    invitead51e543

    Re : Manipuler bit seul dans un variable en C

    Bonjour à tous,

    Donc selon toi PA5CAL, mieux vaut utiliser masques & décalages?

  11. #10
    invite936c567e

    Re : Manipuler bit seul dans un variable en C

    Ce qu'il vaut mieux faire, c'est ce qui est le plus réaliste et le plus avantageux, relativement à tes besoins et à tes contraintes.

    Par exemple :
    - Si tu ne développes que pour une plateforme particulière, et ne recherches moins la portabilité du code qu'une optimisation dont tu prendrais toi-même une partie en charge, alors il vaut mieux que tu intègres des fonctions à base de directives assembleur, définies dans un coin pour pouvoir les retrouver et les changer au besoin.
    - Si tu souhaites une portabilité directe et totale, alors il vaut mieux utiliser les masques ou les décalages.
    - Si tu sais pouvoir toujours contrôler le comportement de ton compilateur et préfères un code plus lisible, alors les bit fields sont envisageables.

    Le choix nécessite de bien connaître le contexte de ton projet et d'avoir une idée sur son avenir à long terme.

  12. #11
    Jack
    Modérateur

    Re : Manipuler bit seul dans un variable en C

    Par ailleurs, la seule écriture d'une succession de bit fields dans le programme ne garantit pas que les bits considérés seront placés consécutivement dans le même octet, mot ou mot long.
    Je ne suis pas tout à fait d'accord. Si la structure de donnée accueillant les bits fields est suffisante (un octet par exemple), la norme garantit que tous les bits seront consécutifs (packed). Ceci est garanti si les bit fields sont déclarés consécutivement et donc non séparés par un champ non bit field, ou un bit field de longueur nulle.

    Bref:
    Code:
    /*** PTAD - Port A Data Register; 0x00000000 ***/
    typedef union {
      byte Byte;
      struct {
        byte PTAD0       :1;                                       /* Port A Data Register Bit 0 */
        byte PTAD1       :1;                                       /* Port A Data Register Bit 1 */
        byte PTAD2       :1;                                       /* Port A Data Register Bit 2 */
        byte PTAD3       :1;                                       /* Port A Data Register Bit 3 */
        byte PTAD4       :1;                                       /* Port A Data Register Bit 4 */
        byte PTAD5       :1;                                       /* Port A Data Register Bit 5 */
        byte PTAD6       :1;                                       /* Port A Data Register Bit 6 */
        byte PTAD7       :1;                                       /* Port A Data Register Bit 7 */
      } Bits;
    } PTADSTR;
    Dans ce cas, les 8 bits sont donc forcément consécutifs

  13. #12
    Seb.26

    Re : Manipuler bit seul dans un variable en C

    C'est ce que je proposais en parlant des "union" ...

    -> il suffit d'aller voir dans les fichiers .h de ton CPU pour voir comment c'est déclaré.

    -> tous les compilos pour uCPU propose l’accès aux registres sous forme de bit.

    -> les masques restent plus portables (mais puisque l'on parle d'accès à des ports d'un registre la portabilité n'est de toute façon probablement pas un problème).
    Dernière modification par Seb.26 ; 09/04/2015 à 13h55.
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  14. #13
    jiherve

    Re : Manipuler bit seul dans un variable en C

    Bonjour,
    Jack et Seb ont raison la solution de l'union est générale, on peut déclarer une structure complexe. Au final la manipulation se fera soit par masque et/ou décalage ou par une instruction assembleur unique si le micro le permet.
    JR
    l'électronique c'est pas du vaudou!

  15. #14
    invite936c567e

    Re : Manipuler bit seul dans un variable en C

    Citation Envoyé par Jack Voir le message
    Je ne suis pas tout à fait d'accord. Si la structure de donnée accueillant les bits fields est suffisante (un octet par exemple), la norme garantit que tous les bits seront consécutifs (packed). Ceci est garanti si les bit fields sont déclarés consécutivement et donc non séparés par un champ non bit field, ou un bit field de longueur nulle.
    Il y a les principes qu'on souhaiterait voir respecter, et puis il y a la dure réalité.

    Le respect de la norme (ou plus précisément d'une des normes) réclame malheureusement souvent des réglages particuliers des options du compilateur. Bien souvent, le comportement proposé par défaut s'en éloigne, et certains compilateurs (même parmi les plus répandus) sont dans l'incapacité de s'y conformer strictement.

    Quoi qu'il en soit, le compactage n'est pas le seul point qui soulève des questions. Par exemple, le fait de déclarer plusieurs bits consécutifs avec des bit fields ne garantit pas non plus qu'ils seront cadrés à droite et rangés par ordre de poids croissant dans l'entier qui les contient...

  16. #15
    Jack
    Modérateur

    Re : Manipuler bit seul dans un variable en C

    Il y a les principes qu'on souhaiterait voir respecter, et puis il y a la dure réalité.
    Quand on travaille avec des compilateurs ne respectant pas la norme, c'est sur qu'il faut se cogner la doc. C'est le cas pour l'exemple que j'ai donné, issu d'un compilateur freescale pour µC 8 bits.

    A+
    Dernière modification par Jack ; 09/04/2015 à 14h44.

  17. #16
    invitead51e543

    Re : Manipuler bit seul dans un variable en C

    En utilisant des décalages & masques, mon code aurait cette forme là, bon ça ne marche pas, mais je l'ai écrit vite fait, c'était plus pour montrer la syntaxe .
    - Chaque SW correspond à un PORTXbits.RXX (pour la simul, j'ai affecté les valeurs manuellement)
    - Je met ce bit dans une variable (un unsigned char)
    - Je passe cette variable dans une autre tout en faisant mon décalage de bits
    - A chaque fois, je fais un ou logique afin de conserver mes bits déjà décalés.

    Auriez vous procédez comme ça? Je trouve que c'est le plus simple et plus logique, après je me trompe peut-être.

    Pour info, je développe avec un PIC18F4431, sous MPLABX avec XC8 comme compilo. Pour ce qui est de la portabilité, pour l'instant, ça n'est pas une obligation, j'essaie de travailler en priorité avec ce µ.

    Code:
            unsigned char variable1 = 1;
            unsigned char variable2 = 0;
            unsigned char variable3 = 1;
            unsigned char variable4 = 0;
            unsigned char variable5 = 1;
            unsigned char variable6 = 0;
            unsigned char variable7 = 1;
            unsigned char variable8 = 0;
            unsigned char variable9 = 1;
            unsigned int resultat = 0;
    
            //variable8 = SW8;
            resultat = ((unsigned char)(variable8)<<7); //0000 0000 car SW8 = 0;
            //variable7 = SW7;
            resultat = ((unsigned char)((variable7)<<6) || (resultat)); //0100 0000 car SW7 = 1 (valeur que j'ai définit)
            //variable6 = SW6;
            resultat = ((unsigned char)((variable6)<<5) || (resultat)); //0100 0000 car SW6 = 0 (valeur que j'ai définit)
            //variable5 = SW5;
            resultat = ((unsigned char)((variable5)<<4) || (resultat)); //0101 0000 car SW5 = 1 (valeur que j'ai définit)
            //variable4 = SW4;
            resultat = ((unsigned char)((variable4)<<3) || (resultat)); //0100 0000 car SW4 = 0 (valeur que j'ai définit)
            //variable3 = SW3;
            resultat = ((unsigned char)((variable3)<<2) || (resultat)); //0101 0100 car SW3 = 1 (valeur que j'ai définit)
            //variable2 = SW2;
            resultat = ((unsigned char)((variable2)<<1) || (resultat)); //0100 0000 car SW2 = 0 (valeur que j'ai définit)
            //variable1 = SW1;
            resultat= ((unsigned char)(variable1) || (resultat)); //0101 0101 car SW1 = 1; (valeur que j'ai définit)
    Au niveau du résultat final de resultat, j'obtiens resultat = 0x01 au lieu de resultat = 0x55

  18. #17
    Jack
    Modérateur

    Re : Manipuler bit seul dans un variable en C

    resultat = ((unsigned char)(variable8)<<7); //0000 0000 car SW8 = 0;
    Je ne vois pas trop l'intérêt de décaler variable8 qui vaut 0. Le résultat du décalage sera invariablement 0.

  19. #18
    invitead51e543

    Re : Manipuler bit seul dans un variable en C

    Dans ce cas oui, mais si variable8 = 1, comment fais tu?

  20. #19
    invitead51e543

    Re : Manipuler bit seul dans un variable en C

    J'ai modifié l'ordre des parenthèses, je pensais que le problème venait d'un ordre de priorité, mais ça n'en a pas l'air :

    Code:
    resultat= ((((unsigned char)(variable7))<<6) || (unsigned char)(resultat)); //0100 0000 car SW7 = 1;
    Malheureusement, j'obtiens toujours le résultat resultat = 0x01 au lieu de resultat = 0x80

  21. #20
    Jack
    Modérateur

    Re : Manipuler bit seul dans un variable en C

    Pour ce genre d'opération, il faut utiliser l'opérateur OU bitwise (bit à bit) et pas le OU logique, donc l'opérateur | et pas ||

  22. #21
    invite936c567e

    Re : Manipuler bit seul dans un variable en C

    Il ne faut pas confondre les opérations sur les bits (qui sont arithmétiques) avec les opérations booléennes.

    L'opérateur « OU » bit à bit (bitwise) s'écrit « | », et non pas « || »;

    [EDIT: grillé]

  23. #22
    invitead51e543

    Re : Manipuler bit seul dans un variable en C

    J'ai voulu aller trop vite, voilà ce que ça donne.
    Merci à vous 2 pour la rapidité de la réponse

Discussions similaires

  1. Un seul électron dans l'univers ?
    Par invite6754323456711 dans le forum Archives
    Réponses: 11
    Dernier message: 11/08/2014, 22h01
  2. Statistique descriptif a un seul variable
    Par invitea2924f07 dans le forum Physique
    Réponses: 0
    Dernier message: 25/09/2010, 15h44
  3. Un seul électron dans l'Univers ?
    Par invite85dfba75 dans le forum Physique
    Réponses: 22
    Dernier message: 11/06/2009, 15h37
  4. Equation dans C avec un paramètre variable dans R
    Par invite3a0844ce dans le forum Mathématiques du supérieur
    Réponses: 7
    Dernier message: 24/09/2007, 16h43
  5. La prepa... seul, dans un appart!
    Par invite6cbab356 dans le forum Orientation après le BAC
    Réponses: 2
    Dernier message: 28/01/2006, 14h23
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...