Vous êtes sur la page 1sur 18

TP 4 : Opérations bit-à-bit

Introduction

Dans cette partie nous allons approfondir 2 notions plus spécifiques


au domaine de l’embarqué :

1) Codage binaire des nombres entiers, en lien avec le langage C

• voir UE de 1ère année "Systèmes Numériques"


• on se limitera ici aux nombres entiers (signés ou non signés)

2) Opérations bit-à-bit

• dans cette partie on va s’intéresser aux différents bits qui


composent une variable, indépendamment les uns des autres
58
TP 4 : Opérations bit-à-bit
Codage binaire des nombres entiers

décimal
Exemple 8 bits : binaire
non signé signé (*)
(Rappel cours Logique) 00000000 0 0
00000001 1 1
00000010 2 2

01111111 127 127
10000000 128 -128

11111101 253 -3
11111110 254 -2
11111111 255 -1

(*) Rappel cours Logique : 59


codage en "complément à 2", utilisé par tous les systèmes numériques
TP 4 : Opérations bit-à-bit
Codage binaire des nombres entiers

Types non-signés en langage C :

unsigned char : sur 8 bits (valeurs de 0 à 255)

unsigned short int : sur 16 bits (valeurs de 0 à 65535)

unsigned long int : sur 32 bits (valeurs de 0 à 4 milliards et quelques…)

Remarque 1 : le type int (ou unsigned int) dépend de l’architecture


du système (16 ou 32 bits)

Remarque 2 : en C, la fonction sizeof()permet de connaître la taille


d’une variable ou d’un tableau en nombre d’octets
60
TP 4 : Opérations bit-à-bit
Codage binaire des nombres entiers

A votre avis, qu’affiche le programme suivant ?

main()
{
int i;
unsigned char c=0;

for(i=0 ; i<259 ; i++)


printf("%d ", c++);
printf("\n");
}

61
TP 4 : Opérations bit-à-bit
Codage binaire des nombres entiers

A votre avis, qu’affiche le programme suivant ?

main()
{
int i;
unsigned char c=0;

for(i=0 ; i<259 ; i++)


printf("%d ", c++);
printf("\n");
}

→ réponse : 0 1 2 3 … 255 0 1 2 61
TP 4 : Opérations bit-à-bit
Codage binaire des nombres entiers

Types signés en langage C :


signed char ou plus simplement char
signed short int " short int
signed long int " long int

A votre avis, qu’affiche le programme suivant ?


main()
{
int i;
char c=0;

for(i=0 ; i<259 ; i++)


printf("%d ", c++);
printf("\n");
}
62
TP 4 : Opérations bit-à-bit
Codage binaire des nombres entiers

Types signés en langage C :


signed char ou plus simplement char
signed short int " short int
signed long int " long int

A votre avis, qu’affiche le programme suivant ?


main()
{
int i;
char c=0;

for(i=0 ; i<259 ; i++)


printf("%d ", c++);
printf("\n");
}
62
→ réponse : 0 1 2 … 126 127 -128 -127 … -2 -1 0 1 2
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Symboles du langage C correspondant aux opérateurs bit-à-bit :


& ET
| OU
^ OU-exclusif
~ inversion
<< (>>) décalage à gauche (resp. droite)

Ces opérateurs vont nous permettre de travailler sur un ou plusieurs bits (selon
le cas) d’une variable :
- positionner (ou forcer) des bits
- tester des bits
- décaler des bits
- inverser des bits
… avec pour objectif très concret de gérer des registres d’un microcontrôleur, 63
permettant de gérer des entrées-sorties, configurer des modules (ADC, Timer, etc)
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Décaler des bits

Syntaxe :

x << n : décalage logique des bits de x, de n positions vers la gauche


x >> n : décalage logique des bits de x, de n positions vers la droite

Exemple :

int n=6; //soit n=00000110


n = n << 1; //ou n <<= 1
printf("n<<1=%d\n", n); //résultat : 12 (=00001100)
n = n >> 2;
printf("n>>2=%d\n", n); //résultat : 3 (=00000011)

64
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Inverser des bits


1) Tous les bits d’une variable : opérateur ~
Exemple
char a=0xf0, b;
b = ~a;
printf("b=%x\n", b); //f

2) Sélection de bits : opérateur ^ (OU-exclusif )


D’après la table du OU-exclusif, on constate A B A OU-ex B
que quand B est à 1, A se trouve inversé ; 0 0 0
d’où l’idée d’utiliser cet opérateur pour 0 1 1
1 0 1
inverser des bits sélectionnés 1 1 0
Exemple :
char a=0x0f, masque=0x03; //a : variable à traiter 65
a = a ^ masque; //ou a ^= masque;
printf("a=%x\n", a); //a=c
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Positionner un bit, à 1 (1/2)


Observons la table de vérité de la fonction OU logique :
A B A OU B En raisonnant sur B, on constate que B à 1
0 0 0 impose un 1 en sortie, et ceci quel que soit
0 1 1 l’état de A correspondant → cette propriété
1 0 1 peut donc être utilisée pour forcer un (ou
1 1 1 plusieurs) bit(s) à 1, sans modifier les autres.

Exemple :
char a=0x15; //une variable a traiter
char masque=0x1A; //"masque" <-> selection de bits
a = a | masque; //ou a |= masque
printf("a=%d\n", a); //a=31 (00010101 | 00011010 = 00011111) 66
printf("a=%x\n", a); //a=1f (affichage en hexadecimal)
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Positionner un bit, à 1 (2/2)


Exemple d’application avec un microcontrôleur : dans le MSP430 de
Texas Instrument, il existe une variable P1OUT, de type unsigned char,
dont chacun des bits correspond à une sortie d’un groupe de 8
entrées/sorties, appelé port d’entrée/sortie.

Pour allumer une LED connectée sur la première entrée/sortie de ce


port (bit d’indice 0), on pourra écrire :

char masque=0x01; //masque 8 bits


P1OUT = P1OUT | masque; //ou P1OUT |= masque

Résultat : le bit d’indice 0 de P1OUT est forcé à 1


67
→ niveau logique 1 sur la sortie correspondante (↔ tension Vcc)
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Positionner un bit, à 0
Observons la table de vérité de la fonction ET logique :
A B A ET B En raisonnant sur B, on constate que B à 0
0 0 0 impose un 0 en sortie, et ceci quel que soit
0 1 0 l’état de A → cette propriété peut donc être
1 0 0 utilisée pour forcer un (ou plusieurs) bit(s) à 0,
1 1 1 sans modifier les autres.
Exemple :
char a=0x3D; // une variable
char masque=0x22; // une autre qui nous sert de masque
a = a & masque; // ou a &= masque
printf("a=%d\n", a); //c=32 (00111101 & 00100010= 00100000)
68
printf("a=%x\n", a); //c=20 (affichage en hexadecimal)
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Positionner un bit, exemple récapitulatif

On souhaite forcer 2 bits d’une variable P1OUT :


- bit d’indice 0 à 1
- bit d’indice 1 à 0
sans modifier les autres, et en utilisant les 2 constantes prédéfinies
suivantes :

#define BIT0 0x01


#define BIT1 0x02

Résultat :
P1OUT = 0x02; //exemple de valeur
P1OUT |= BIT0; //forcer le bit d’indice 0 a 1 69
P1OUT &= ~BIT1; //forcer le bit d’indice 1 a 0
printf("P1OUT=%02x\n", P1OUT); //01 dans cet exemple
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Tester un bit, à 1

Reprenons la table de vérité du ET logique :

A B A ET B On constate que le seul cas où la sortie est à


0 0 0 1 est celui où les 2 opérandes sont à 1 :
0 1 0 → cette propriété peut être utilisée pour
1 0 0 détecter qu’un (ou plusieurs) bit(s) d’une
1 1 1 variable est (sont) à 1 :
SI A ET 1 = 1, alors c’est que A = 1
Exemple :
int n=0x33; //variable a tester
int masque=0x02; //masque pour test du bit d’indice 1
if((n & masque) == masque) 70
printf("le bit d'indice 1 est egal a 1\n"); //c le cas ici
else
printf("le bit d'indice 1 est egal a 0\n");
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Tester un bit, à 0

Reprenons la table de vérité du OU logique :

A B A OU B On constate que le seul cas où la sortie est à


0 0 0 0 est celui où les 2 opérandes sont à 0
0 1 1 → cette propriété peut être utilisée pour
1 0 1 détecter qu’un (ou plusieurs) bit(s) d’une
1 1 1 variable est (sont) à 0 :
SI A OU 0 = 0, alors c’est que A = 0
Exemple :
int n=0x11; //variable a tester
int masque=0xFD; //masque pour test du bit d’indice 1
if((n | masque) == masque) 71
printf("le bit d'indice 1 est egal a 0\n"); //c le cas ici
else
printf("le bit d'indice 1 est egal a 1\n");
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Tester un bit, exemple récapitulatif

Exemple d’application : on souhaite tester l’état d’un bouton-poussoir,


connecté sur l’entrée 3 d’un port d’entrée/sortie d’un microcontrôleur (le
test va dépendre du circuit électrique associé au bouton)
1er extrait de programme-solution (cas où l’appui génère un 1) :
#define BIT3 0x08 //un masque
char P1IN=0x08; //simulation d’une entree du uc
...
if((P1IN & BIT3) == BIT3)
printf("bouton appuye\n");

2e extrait de programme-solution (cas où l’appui génère un 0) :


72
if((P1IN | ~BIT3) == ~BIT3)
printf("bouton appuye\n");
TP 4 : Opérations bit-à-bit
Opérations bit-à-bit

Récapitulatif : positionner / tester un bit

Positionner
Tester un bit …
un bit …
opération
à1 à0 à1 à0

opérateur logique OU ET ET OU
bit à utiliser
1 0 1 0
dans le masque

Rm : avec le même principe, on pourra positionner/tester plusieurs bits 73


en même temps

Vous aimerez peut-être aussi