Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Commentez, partagez et proposez des Tutos en langage C !
Structures, Champ de bit et Union !!
Jérémy
Administrateur du site
Administrateur du site
Messages : 2032
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » mer. 14 oct. 2015 22:10

Bonjour à tous ,

Avec ce Tuto , je vais tenter de vous dégrossir le fonctionnement des Structures , des champs de bit et des Unions en langage C.

Je tiens avant tout à signaler que ces notions délicates et ne sont pas encore très clair pour moi. je modifierais le tuto au fur et à mesure de mes connaissances et des remarques d'experts !

Ne prenez donc pas pour argent comptant tout ce que je vais dire ici. En tout cas, tout à été tester en réel ! ( vidéo à l'appui :) ).
Je reste dans la philosophie de ma signature, en dérivant un peu, c'est en faisant des erreurs qu'on prouve qu'on à essayé. Donc tout correction est le bienvenue, mais ne m'en voulez pas si il y des erreurs ou des oublis ! A contrario si ceci vous à aidez, vous pouvez aussi le faire savoir , ça ne mange pas de pain et surtout ça motive et fait plaisir !


Image



Configuration :

- PIC18F45K22
- IDE : MikroC Pro for PIC Version 6.6.2
- Compilateur : Mikro prog suite fo PIC V 2.32
- Plaque Easy PIC V7
- LCD en mode 4 bits








Pourquoi diable rassembler des données ou les dissocier !!

Dans certains cas, il est peut-être utile et pratique de compartimenter, diviser, ou fractionner un OCTET.
Pour ma part j'utilise dans mes montages beaucoup de flags (drapeaux), me permettant de mettre une sortie de mon PIC à 1 ou à 0 par exemple.

Ces commandes me sont fortes utiles pour commander une led , une relais , etc .... . C'est ce que j'appelle des Tout ou Rien (TOR) , soit c'est 1 soit c'est 0. Ce serait du gaspillage de mémoire que de stocker ces valeurs dans des int ou des char , qui peuvent contenir respectivement 65536 ou 256 valeurs chacun.

Si on reste en interne du PIC à la limite se ne serait pas trop gênant, mais si l'on doit envoyer ces infos par voie radio ou sur un BUS ou en IR , cela ne serait pas pratique d'envoyer 8 octets différents pour faire passer 8 informations en Tout Ou Rien .

Première méthode :
Nous allons commencer pour ce faire utiliser le Champ de bit. C'est à dire que nous allons diviser un Octet en 8 bits distincts.

Un champ de bit n'est ni plus ni moins qu'une structure particulière. Une structure à vocation à acceptée différentes "type" à l’intérieur ( long, float char etc ...). On ne peut donc pas l’appeler seulement par son nom comme une vulgaire variable étant donné qu'elle contient elle même plusieurs variables.

Tout d'abord nous allons créer un champ de bits donc une structure :
Notre structure contiendra 8 variables de 1 bit chacune ( on aurai pu mettre 4 variable de 2bits aussi par exemple).

Code : Tout sélectionner

 struct {               // Déclaration de notre structure grâce au mot clefs "struct"
        inter0:1;              // Nous définissons nos 8 bits en leur assignant un nom et une longueur en bit séparé par ":"
        inter1:1;             
        inter2
:1;
        inter3:1;
        inter4:1;
        inter5:1;
        inter6:1;
        inter7:1;
     } monCHAMPS;           // Nom de notre structure, qui est un champ de bits en fait !                


Voila notre champs de bits(structure) est créer , nous pouvons maintenant changer et appeler chaque bits indépendamment en utilisant cette syntaxe :
monCHAMPS.inter0
On commence par appeler le nom de notre structure , séparé par un point . suivi du nom de notre variable (qui est un bit dans cette exemple).

C'est le même principe que pour définir la broche d'un PORT par exemple ! ou la valeur d'un registre:
PORTB.B2 correspond à la structure qui s'appelle PORTB , et B2 la variable déclarée grosso-modo hein !

C'est bien beau ça , mais si on ne peut pas appelé cette structure, on ne pourra pas l'envoyer par voie radio non plus ?

Effectivement . Pour cela nous allons associer notre champ de bits à une variable, grâce à une union.

une Union permet de réunir différentes structures, variables, et autres sous la même adresse mémoire !. Plutôt pratique ça dans notre cas .
On va créer une variable qu'on appellera Mavariable , puis notre champ de bit qui s’appelle monCHAMPS , et on va les unir pour que les deux possède la même adresse mémoire . Ainsi si l'on change la valeur de l'un cela changera aussi la valeur de l'autre.

Une union se déclare de la même façon qu'un structure mais avec le mot clef "union".

Code : Tout sélectionner

// Création de l'UNION
 union  {                     // Nom de l'union qui réunie deux structures ( 1 Champs de bits et 1 variable)
                              // Les deux structures auront la même adresse mémoire
       unsigned char Mavariable; // Ici la première structure qui est une variable appelée Mavariable

       struct {                // ici la deuxième structure qui est un champ de bits
                inter0:1;
                inter1:1;
                inter2:1;
                inter3:1;
                inter4:1;
                inter5:1;
                inter6:1;
                inter7:1;
                
              
} monCHAMPS;    // Nom du champs de bits
  } Union;                    // Nom de l'UNION
// Fin de l'UNION               


Et voila, nous avons un OCTET qui s’appelle Mavariable
un deuxième OCTET monCHAMPS qui est un champ de bits appelable bit à bit .

Ces deux OCTET sont réunis par une UNION qui s’appelle Union. si on change l'un des deux OCTETS , cela changera aussi l'autre étant donné qu'il partage la même adresse mémoire. Ils sont UNIS.


Deuxième méthode plus facile à comprendre :

L'utilisation du sbit permet de finir un Bit . le nom du bit sera immédiatement mis après le mot clef sbit .
Le mot clef at désigne le nom de la bit que l'on vise sera immédiatement suivie du nom réel du bit en question.
Comme pour le nom du bit d'un PORT , ou d'un registre . Le résultat est le même que la première méthode .

Code : Tout sélectionner

// Ici on décortique notre variable en bit
sbit Monbit0 at Mavariable.B0;   // On déclare que Mavariable.B0 vaudra Monbit0 dans le programme
sbit Monbit1 at Mavariable.B1;   // On pourra bien sur renommé "MonbitX" par le nom de son choix .
sbit Monbit2 at Mavariable.B2;
sbit Monbit3 at Mavariable.B3;
sbit Monbit4 at Mavariable.B4;
sbit Monbit5 at Mavariable.B5;
sbit Monbit6 at Mavariable.B6;
sbit Monbit7 at Mavariable.B7;
// Fin de déclaration  

Résultat en vidéo :
- Chaque BP du PORT correspond à 1 bit de notre variable ( interx) .
- Un appui sur un BP transforme le bit de (0 à 1) ou de (1 à 0).
- On visualise donc champ de bit sur les leds du PORTD .
- Mais par contre on visualise notre variable globale sur l'écran LCD .

Ainsi on se rend bien compte qu'un changement se répercute bien sur les deux façons de faire , mais sur une seule et même variable , que l'on peut soit appelée par son nom globale, soit bit par bit .

http://www.dailymotion.com/video/x39oiav
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 2 invités