« Code Gray » : différence entre les versions

De knowledge
Aller à la navigation Aller à la recherche
mAucun résumé des modifications
Ligne 145 : Ligne 145 :
Merci à http://m.joffroy.free.fr/in/Cours%20BTS%20MAI%201er%20et%202eme%20ann%C3%A9e/COURS%2009%20Les%20capteurs/Codeur%20Absolu.htm
Merci à http://m.joffroy.free.fr/in/Cours%20BTS%20MAI%201er%20et%202eme%20ann%C3%A9e/COURS%2009%20Les%20capteurs/Codeur%20Absolu.htm


=== Exemple de code ===
=== Implémentation ===
 
==== Codage/décodage hardware ====
L'opérateur booléen utilisé est le "ou exclusif" noté ⨁.
 
===== Codage (binaire vers Gray) =====
On considère le bit de poids n. G<sub>n</sub> est la valeur du bit en code Gray et B<sub>n</sub> la valeur en code binaire.
 
G<sub>n</sub>=B<sub>n</sub> ⨁ B<sub>(n+1)</sub>.
 
Si on veut coder 8 bits on utilise le schéma :
 
[[Fichier:Codage gray.png|sans_cadre]]
 
===== Décodage (Gray vers binaire) =====
La formule est :
 
B<sub>n</sub>=G<sub>n</sub> ⨁ B<sub>(n+1)</sub>
 
Le schéma donne :
 
[[Fichier:Conversion gray vers binaire.png|sans_cadre]]
 
==== Exemple de code "C" ====
 
On va utilisera du code en "C".<syntaxhighlight lang="c">
On va utilisera du code en "C".<syntaxhighlight lang="c">
typedef unsigned int uint;
typedef unsigned int uint;


// This function converts an unsigned binary number to reflected binary Gray code.
// Cette fonction reprends le schéma ci-dessus
uint BinaryToGray(uint num)
uint BinaryToGray(uint num)
{
{
     return num ^ (num >> 1); // The operator >> is shift right. The operator ^ is exclusive or.
     return num ^ (num >> 1); // L'operateur >> est un décalage binaire vers la droite. ^ est un ou exclusif.
}
}


// This function converts a reflected binary Gray code number to a binary number.
// Toujours selon le schéma ci-dessus.
uint GrayToBinary(uint num)
uint GrayToBinary(uint num)
{
{
     uint mask = num;
     uint mask = num;
     while (mask) {          // Each Gray code bit is exclusive-ored with all more significant bits.
     while (mask) {           
         mask >>= 1;
         mask >>= 1;
         num  ^= mask;
         num  ^= mask;
Ligne 166 : Ligne 190 :
}
}


// A more efficient version for Gray codes 32 bits or fewer through the use of SWAR (SIMD within a register) techniques.  
// plus performant mais pour 32 bits. On peut l'adapter...
// It implements a parallel prefix XOR function. The assignment statements can be in any order.
//
// This function can be adapted for longer Gray codes by adding steps.


uint GrayToBinary32(uint num)
uint GrayToBinary32(uint num)

Version du 21 mars 2025 à 21:53

La théorie

Le code Gray ou code binaire réfléchi est une façon de coder les nombres entiers en binaire en faisant en sorte que, d'un nombre consécutif à un autre il n'y ai jamais qu'un seul bit modifié.

Exemple avec un mot de 4 bits
Nombre Hexa Binaire Code Gray
0 0 0000 0000
1 1 0001 0001
2 2 0010 0011
3 3 0011 0010
4 4 0100 0110
5 5 0101 0111
6 6 0110 0101
7 7 0111 0100
8 8 1000 1100
9 9 1001 1101
10 A 1010 1111
11 B 1011 1110
12 C 1100 1010
13 D 1101 1011
14 E 1110 1001
15 F 1111 1000

Quel est l'intérêt d'un tel code me direz vous ?

Cela sert a faire des compteurs numériques de façon mécaniques par exemple. Imaginons que l'on ai un signal binaire qui s'excrément au fur et a mesure d'un process quelconque.

Signal Binaire 4 bits.png

Si les 4 lignes (A,B,D et D) sont parfaitement synchrones et qu'on lise le signe parfaitement au milieu de chaque état cela nous donne:

Signal Binaire 4 bits a lecture synchrone.png

Jusque là tout va bien. Imaginons que les lignes A,B,C et B ne soient pas bien en phase.

Signal asynchones.png

On voit bien que le 7 qui doit être 0100 est 11xx avec x où sait pas bien si c'est un 0 ou un 1.

Comment pourrait on faire un système de décompte binaire qui sont insensible a ces problèmes? Avec le code binaire réfléchi ou code Gray!

Si on change le signal binaire par un signal en code gray:

Gray code.png

On lit la valeur au début:

0 en binaire reflechi.png

Ok on commence à zéro. La "ruse" est qu'il suffit d'attendre que l'un des bits changes de valeur, sachant que jamais deux ne peuvent changer en même temps.

Gray à 1.png

Premier changement c'est la ligne D et on lit 0001 qui en code gray donne 1 . Après 0 on a bien un 1. Jusqu'ici tout va bien!

On attends le prochain changement :

Gray 2.png

La ligne C a changé et on a donc 0011 qui code un 2 en gray. Apres 1 on a bien 2.... on continue:

Gray.png

Et ca marche!

Mise en oeuvre

On peut réaliser une roue codeuse en code GRAY:

Encoder Disc (3-Bit).svg.png

Si on la lit avec 3 photodiodes on a un encodeur d'angle précis à 45°. Et c'est la même méthode, on attends qu'un bit change pour lire la nouvelle valeur.

J'ai même trouvé:

Gray code precis.gif

J'ai compté 10 bits donc mieux que 0,35° de précision.

Merci à http://m.joffroy.free.fr/in/Cours%20BTS%20MAI%201er%20et%202eme%20ann%C3%A9e/COURS%2009%20Les%20capteurs/Codeur%20Absolu.htm

Implémentation

Codage/décodage hardware

L'opérateur booléen utilisé est le "ou exclusif" noté ⨁.

Codage (binaire vers Gray)

On considère le bit de poids n. Gn est la valeur du bit en code Gray et Bn la valeur en code binaire.

Gn=Bn ⨁ B(n+1).

Si on veut coder 8 bits on utilise le schéma :

Codage gray.png

Décodage (Gray vers binaire)

La formule est :

Bn=Gn ⨁ B(n+1)

Le schéma donne :

Conversion gray vers binaire.png

Exemple de code "C"

On va utilisera du code en "C".

typedef unsigned int uint;

// Cette fonction reprends le schéma ci-dessus
uint BinaryToGray(uint num)
{
    return num ^ (num >> 1); // L'operateur >> est un décalage binaire vers la droite. ^ est un ou exclusif.
}

// Toujours selon le schéma ci-dessus.
uint GrayToBinary(uint num)
{
    uint mask = num;
    while (mask) {           
        mask >>= 1;
        num   ^= mask;
    }
    return num;
}

// plus performant mais pour 32 bits. On peut l'adapter...

uint GrayToBinary32(uint num)
{
    num ^= num >> 16;
    num ^= num >>  8;
    num ^= num >>  4;
    num ^= num >>  2;
    num ^= num >>  1;
    return num;
}