Obtenir l'etat des bits qui composent un octet (conversion xx->binaire)

Soyez le premier à donner votre avis sur cette source.

Snippet vu 14 292 fois - Téléchargée 32 fois

Contenu du snippet

J'ai regardé très rapidement si la source n'existait pas et je ne l'ai pas trouvé.
Je précise que c'est une astuce que je viens d'apprendre en cours.
En utilisant "Les champs de bits" et une union, nous pouvons très simplement obtenir l'état des bits qui composent un octet... mais pourquoi pas un int en modifiant un peu le code.
Les champs de bits :
Pour se qui ne connaisse pas, ils permettent de limiter la place occupé en mémoire d'une variable si tous ces bits ne sont pas utilisés.
Pour représenter cela il suffit de mettre après le nom de la variable :nombre_bit
Par exemple, int état:1; //ici l'int ne fera pas 32bits mais qu'un seul, les valeurs max et min de etat seront donc -1 ou 0
union
A la différence d'un struct, les éléments contenus dans une union sont contenu au même emplacement mémoire
(La structure les met à la suite dans la mémoire)
Je me doute que se n'ai pas très clair un exemple:
struct _test{
int a;
unsigned char b;
}
Ici la structure occupera 5octets en mémoire (sizeof(int)=4octets et sizeof(char)=1octet)

union _test2{
int a;
unsigned char b;
}test2;
Ici sizeof(test2)=4octet
si
test2.a=0xFDE8; //valeur prise au hasard
Alors
b=0xE8;

Schéma de la mémoire:

structure union
|-----------| |-----------|
| | | |
| a | | a et b |
| | | |
|-----------| |-----------|
| b |
|-----------|

J?espère que c'est clair.
Revenons au but...créer une union entre un caractère et une structure et lire la structure pour avoir l'état des bits, regardez le code.

Les champs de bits ne sont pas toujours obligatoires.
Autre utilisation de l'union :
#include <stdio.h>

union _ip{
unsigned char membres[4]; //Les 4 membres qui compose une adresse IP
unsigned int adIp; //L'adresse IP au complet
}ip;

main()
{
printf("saisir une adresse ip en hexa :");
scanf("%x",&ip.adIp); //Saisie en hexa de l'adresse ip au complet

printf("l'adresse ip est : %03d.%03d.%03d.%03d\n"
,ip.membres[3],ip.membres[2],ip.membres[1],ip.membres[0]); //Attention a l'ordre,il est inversé
}

Source / Exemple :


#include <stdio.h>

typedef unsigned char uchar;	//evite de récrire le tout

/*Ma structure qui contiendra l'etat de chacun des bit qui compose un char*/
typedef struct{
	uchar b0:1;		//Poid faible
	uchar b1:1;
	uchar b2:1;
	uchar b3:1;
	uchar b4:1;
	uchar b5:1;
	uchar b6:1;
	uchar b7:1;		//Poid fort
}octet;

/*Mon union qui me permet de superposer les variable 'valeur' et 'etat'*/
union _mot{
	char valeur;
	octet etat;
}mot;

/*Mon main qui me permet de tester*/
main()
{
	printf("saisir une valeur (de -128 a +127):");   //Valeur max d'un char signé
	scanf("%d",&mot.valeur);

	printf("sizeof(octet) = %d\n",sizeof(octet));    //Montre l'interait des champ de bits 1 octet au lieu de 8
	printf("sizeof(mot) = %d\n",sizeof(mot));        //Montre que l'union superpose bien les deux variables et ne les met pas à la suite

	printf("Etat b0: %d\n",mot.etat.b0);
	printf("Etat b1: %d\n",mot.etat.b1);
	printf("Etat b2: %d\n",mot.etat.b2);
	printf("Etat b3: %d\n",mot.etat.b3);
	printf("Etat b4: %d\n",mot.etat.b4);
	printf("Etat b5: %d\n",mot.etat.b5);
	printf("Etat b6: %d\n",mot.etat.b6);
	printf("Etat b7: %d\n",mot.etat.b7);
}

A voir également

Ajouter un commentaire

Commentaires

Melodie_Nelson
Messages postés
5
Date d'inscription
jeudi 11 mai 2006
Statut
Membre
Dernière intervention
17 mai 2006
-
OK,
Mais en fait c'est bon j'ai réussi à régler ce problème. Mais j'en ai d'autres du coup maintenant.
Je vais donc aller voir sur jelectronique, merci
cs_VinceVG
Messages postés
222
Date d'inscription
mercredi 8 septembre 2004
Statut
Membre
Dernière intervention
30 mars 2016
-
On en chie tous le c est un anti language. Il doit rester réservé à des élus. On passe tellement de temps à apprendre à l'utiliser qu'aprés... une fois qu'on est dans le clan on refuse les autres outils avec dédain. je te dis ça j'ai commencer à programmer en hexa (et oui) puis en assembleur puis en basic (le vieu truc pourris) puis en gw basic. Et d'un coup j'ai commencé à respirer avec le pascal en enfin visual basic. Maintenant je suis punis et doit rétrograder au c.

Pour ton pb : si tu envoies le mot (qqs sa base) sur le port, ça devrait marcher sans pb. Ton compilateur s'en charge.Je ne connait pas le lpc2138 ni le compilateur que tu utilise mais bon je n'en connait pas pour lesquels ça ne marche pas.

Ceci dit j'interviens aussi sur un autre forum, plus dédié à ce type d'utilisation du c. L'avantage c'est que la bas tout le monde est électronicien et donc tu auras des réponses rapides et pointus.

Je te met l'adresse : http://forums.jelectronique.com/
Melodie_Nelson
Messages postés
5
Date d'inscription
jeudi 11 mai 2006
Statut
Membre
Dernière intervention
17 mai 2006
-
Merci.
Pfffou, j'en chie.
Tant qu'on y est j'ai une autre question ( enfin j'en ai des millions mais bon ).
Euh, comment dire, donc je commande mon LCD à partir d'un LPC2138. Et je ne sais pas comment assigner mes 8 bits de data du LCD. Je vais les commander en hexa.
Par ex : lcd_data(0x38)
donc ensuite ma procédure lcd_data(infodata) doit transformer ce code hexa pour assigner les 8 bits.
J'ai un peu du mal à expliquer parce que je ne comprends pas le problème.
Voici en gros mon programme :

union IO_PORT
{
u16 W;
u32 DW;
struct
{
u08 LSB;
u08 MLSB;
u08 MMSB;
u08 MSB;
} B2DW;
//etc

//l'afficheur est câblé sur les ports P0.16 à 23, ce qui correspond à B2DW.MMSB

//et on trouve aussi ça dans le fichier LPC_io.h :
#define IDE_PORT_L IO_IO1PIN->B2DW.MMSB


//ensuite :

void init_aff(void) /*faire l'init de l'afficheur*/
{
int i,j=0 ;
for(i=0;i<3;i++)
{
lcd_data(0x38);
delay(20000);
}

lcd_data (0x0C) ;
delay(20000);

//etc
}

void lcd_data (char infodata)
{

IO0CLR = LCD_RS ; //mode instruction du LCD
IO0CLR = LCD_RW ; //mode écriture du LCD

IO0DIR = 0xFEFFB705; // D0 à D7 en sortie

IDE_PORT_L = infodata ;
enable(80); // validation pendant tant de ns
}

Où est le problème ? Pourquoi ça ne marche pas ?
C'est peut-être un problème au niveau du lcd, je respecte peut-ête mal les procédures d'envoie de données. Voici sa doc http://www.spezial.de/doc/cctech/cmc216-01.pdf
Enfin je pense que c'est ma définition IDE_PORT_L qui n'est pas bonne.
BruNews
Messages postés
21054
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
7 novembre 2014
13 -
Va bon.
Melodie_Nelson
Messages postés
5
Date d'inscription
jeudi 11 mai 2006
Statut
Membre
Dernière intervention
17 mai 2006
-
bien, merci mais je pense faire autrement finalement

sinon j'ai une autre question, qui n'a rien à voir certes.

c'est pour obtenir le nombre de caractère d'un mot. sachant que je n'ai pas les librairies telle stdio ou string.

est-ce correct comme ça ??

int n=0;
while(word[n]!=0)
n++ ;  //n est donc le nombre de caractère de word

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.