User Tools

Site Tools


onewire:crc

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
onewire:crc [2012/05/15 14:08] fdconewire:crc [2013/09/18 09:08] sdolt
Line 1: Line 1:
-<note>Les exemples pratiques utilisés dans cette démonstration proviennent de [[http://www.maxim-ic.com/app-notes/index.mvp/id/27|cette page]]. </note>+<note>Les exemples pratiques utilisés dans cette démonstration proviennent de [[http://www.maxim-ic.com/app-notes/index.mvp/id/27|cette page]]. </note 
 + 
 +<note>Sur processeur AVR, une bibliothèque existe : [[avr:crc16.h|Somme de contrôle CRC]]</note>
  
 ====== DOW CRC (Dallas One Wire CRC) ====== ====== DOW CRC (Dallas One Wire CRC) ======
 +<note warning>Le code ci-dessous ne fonctionne pas. Mélange entre chaine de caractère et chaine normale</note>
  
 ===== DOW CRC-8 ===== ===== DOW CRC-8 =====
Line 9: Line 12:
 <file c> <file c>
 #include <stdio.h> #include <stdio.h>
 +#include <string.h>
 #define CRCPOLY8 0x18           //correspond au masque des XOR sur le polynôme x⁸+x⁵+x⁴+x⁰ #define CRCPOLY8 0x18           //correspond au masque des XOR sur le polynôme x⁸+x⁵+x⁴+x⁰
  
 void main(void) void main(void)
 { {
-        int crc = 0x00 , i = 0, bit_counter = 0, b = 0, feedback_bit = 0;       //déclaration + initialisation des variables+        int crc = 0x00 , i = 0, bit_counter = 0, b = 0, feedback_bit = 0, length = 0;       //déclaration + initialisation des variables
         char string[]={"A200000001B81C02"};     //chaîne utilisée pour le calcul du crc         char string[]={"A200000001B81C02"};     //chaîne utilisée pour le calcul du crc
  
-        for (i=0; i<=15; i++)           //passage dans chaque cellules de la chaine string+        length = strlen(string)-1;          //la longueur de la chaîne -1 (car tableau de caractères commence à 0) 
 +        for (i=0; i<=length; i++)           //passage dans chaque cellules de la chaine string
         {                                {                       
-                b = string[15-i];         //nous travaillons de droite à gauche(15-i)+                b = string[length-i];         //nous travaillons de droite à gauche(length-i)
                 bit_counter = 4;        //si le caractère a déjà été décomposé en hexadécimal => 4 bits par valeur                 bit_counter = 4;        //si le caractère a déjà été décomposé en hexadécimal => 4 bits par valeur
                 while (bit_counter>0)   //passage dans la boucle 4 fois                 while (bit_counter>0)   //passage dans la boucle 4 fois
Line 25: Line 30:
                         if (feedback_bit == 0x01) crc = crc ^ CRCPOLY8;    //si le dernier bit est un 1, XOR entre le CRC et le polynôme                         if (feedback_bit == 0x01) crc = crc ^ CRCPOLY8;    //si le dernier bit est un 1, XOR entre le CRC et le polynôme
                         crc = (crc >> 1) & 0x7F;                        //déplacement de crc de 1 sur la droite + vérification que le bit rajouter (celui de gauche) est bien un 0                         crc = (crc >> 1) & 0x7F;                        //déplacement de crc de 1 sur la droite + vérification que le bit rajouter (celui de gauche) est bien un 0
-                        if (feedback_bit == 0x01) crc = crc | 0x80;      //implantation du 1 du feedback_bit (1 au dernier bit) dans le crc en tant que premier bit+                        if (feedback_bit == 0x01) crc = crc | 0x80;      //implantation du 1 du feedback_bit (1 au dernier bit) dans le crc en tant que premier bit (tout à gauche)
                         b = b>>1;         //déplacement de b de 1 sur la droite (car le dernier bit a déjà été utilisé)                         b = b>>1;         //déplacement de b de 1 sur la droite (car le dernier bit a déjà été utilisé)
                         bit_counter--;                         bit_counter--;
                 }                 }
         }         }
-        printf("0x%i%i\n",crc/16,crc%16);+        printf("%#x\n",crc);
 } }
  
 </file> </file>
 ==== Exemple de fonctionnement ==== ==== Exemple de fonctionnement ====
-1-Wire ROM: A2 00 00 00 01 B8 1C 02 \\ CRCPOLY8 = 0x18+1-Wire ROM: A2 00 00 00 01 B8 1C 02 \\ CRCPOLY8 = 0x18 \\ CRCinitial = 0x00
 === i=0 === === i=0 ===
 === b = string [15] <=> '2' [0000'0010] === === b = string [15] <=> '2' [0000'0010] ===
Line 405: Line 410:
 === i=2 === === i=2 ===
 === b = string [13] <=> 'C' [0000'1100] === === b = string [13] <=> 'C' [0000'1100] ===
 +
 +. \\ . \\ .
 +
 +=== i=13 ===
 +=== b = string [2] <=> '0' [0000'0000] ===
 +
 +. \\ . \\ .
 +
 +== bit_counter = 1 ==
 +
 +<code c> feedback_bit = (crc ^ b) & 0x01;</code>
 +^  crc XOR b  ^^
 +|  crc  |  0101'1101  |
 +|  b  |  0000'0000  |
 +^ Résultat |  0101'1101  |
 +
 +^  (crc XOR b) & 0x01  ^^
 +|crc XOR b  |  0101'1101  |
 +|  0x01  |  0000'0001  |
 +^  Résultat  |  0000'0001  |
 +
 +**=> feedback_bit = 0x01**
 +
 +<code c> if (feedback_bit == 0x01) crc = crc ^ CRCPOLY8; </code>
 +
 +^  crc XOR CRCPOLY8  ^^
 +|  crc  |  0101'1101  |
 +|  CRCPOLY8  |  0001'1000  |
 +^  Résultat  |  0100'0101  |
 +
 +**=> crc = 0x45**
 +
 +<code c> crc = (crc >> 1) & 0x7F; </code>
 +
 +^  crc>> ^^
 +|  crc  |  0100'0101  |
 +^  crc>> |  0010'0010  |
 +
 +^  (crc>>1) & 0x7F  ^^
 +|  crc>> |  0010'0010  |
 +|  0x7F  |  0111'1111  |
 +^ Résultat  |  0010'0010  |
 +
 +**=> crc = 0x22**
 +
 +<code c> if (feedback_bit == 0x01) crc = crc | 0x80; </code>
 +
 +^  crc OR 0x80  ^^
 +|  crc  |  0010'0010  |
 +|  0x80  |  1000'0000  |
 +^  Résultat  |  1010'0010  |
 +
 +**=> crc = 0xA2 {C'est la valeur du CRC pour [00000001B81C (Numéro de série) + 02 (Family Code)], s'il est ajouté à la suite du numéro de série, le CRC final sera de 0x00!}**
 +
 +. \\ . \\ .
 +
 +=== i=14 ===
 +=== b = string [1] <=> '2' [0000'0010] ===
  
 . \\ . \\ . . \\ . \\ .
Line 417: Line 480:
 . \\ . \\ . . \\ . \\ .
  
-**=> crc = 0x00**+**=> crc = 0x00 {Nous avons au final un 0x00, 0xA2 est bel et bien le CRC de [00000001B81C02]}**
  
-===== CRC-16 =====+===== DOW CRC-16 =====
  
 ==== Fonction ==== ==== Fonction ====
Line 425: Line 488:
 <file c> <file c>
 #include <stdio.h> #include <stdio.h>
-#define CRCPOLY16 0x4002           //correspond au masque des XOR sur le polynôme x^16+x^15+x^2+x+#include <string.h> 
 +#define CRCPOLY16 0x4002           //correspond au masque des XOR sur le polynôme x^16+x^15+x^2+x^0
  
 void main(void) void main(void)
 { {
-        int crc = 0x0000 , i = 0, bit_counter = 0, b = 0, feedback_bit = 0;       //déclaration + initialisation des variables+        int crc = 0x0000 , i = 0, bit_counter = 0, b = 0, feedback_bit = 0, length = 0;       //déclaration + initialisation des variables
         char string[]={"75"};     //chaîne utilisée pour le calcul du crc         char string[]={"75"};     //chaîne utilisée pour le calcul du crc
  
-        for (i=0; i<=1; i++)           //passage dans chaque cellules de la chaine string+        length = strlen(string)-1;          //la longueur de la chaîne -1 (car tableau de caractères commence à 0) 
 +        for (i=0; i<=length; i++)           //passage dans chaque cellules de la chaine string
         {                                {                       
-                b = string[1-i];         //nous travaillons de droite à gauche(1-i)+                b = string[length-i];         //nous travaillons de droite à gauche(length-i)
                 bit_counter = 4;        //si le caractère a déjà été décomposé en hexadécimal => 4 bits par valeur                 bit_counter = 4;        //si le caractère a déjà été décomposé en hexadécimal => 4 bits par valeur
                 while (bit_counter>0)   //passage dans la boucle 4 fois                 while (bit_counter>0)   //passage dans la boucle 4 fois
Line 441: Line 506:
                         if (feedback_bit == 0x0001) crc = crc ^ CRCPOLY16;    //si le dernier bit est un 1, XOR entre le CRC et le polynôme                         if (feedback_bit == 0x0001) crc = crc ^ CRCPOLY16;    //si le dernier bit est un 1, XOR entre le CRC et le polynôme
                         crc = (crc >> 1) & 0x7FFF;                        //déplacement de crc de 1 sur la droite + vérification que le bit rajouter (celui de gauche) est bien un 0                         crc = (crc >> 1) & 0x7FFF;                        //déplacement de crc de 1 sur la droite + vérification que le bit rajouter (celui de gauche) est bien un 0
-                        if (feedback_bit == 0x0001) crc = crc | 0x8000;      //implantation du 1 du feedback_bit (1 au dernier bit) dans le crc en tant que premier bit+                        if (feedback_bit == 0x0001) crc = crc | 0x8000;      //implantation du 1 du feedback_bit (1 au dernier bit) dans le crc en tant que premier bit (tout à gauche)
                         b = b>>1;         //déplacement de b de 1 sur la droite (car le dernier bit a déjà été utilisé)                         b = b>>1;         //déplacement de b de 1 sur la droite (car le dernier bit a déjà été utilisé)
                         bit_counter--;                         bit_counter--;
                 }                 }
         }         }
-        printf("0x%i%i%i%i\n",crc/4096,(crc%4096)/256,(crc%256)/16,crc%16);+        printf("%#x\n",crc);
 } }
 </file> </file>
  
 ==== Exemple de fonctionnement ==== ==== Exemple de fonctionnement ====
-1-Wire ROM: 75 \\ CRCPOLY8 = 0x4002 \\ CRCinitial = 0x90F1+1-Wire ROM: 75 \\ CRCPOLY16 = 0x4002 \\ CRCinitial = 0x90F1
 === i=0 === === i=0 ===
 === b = string [1] <=> '5' [0000'0000'0000'0101] === === b = string [1] <=> '5' [0000'0000'0000'0101] ===
Line 828: Line 893:
  
 **=> crc = 0x6390** **=> crc = 0x6390**
- 
-<code c> b = b>>1; </code> 
- 
-^  b>> ^^ 
-|  b  |  0000'0000'0000'0000  | 
-^  b>> |  0000'0000'0000'0000  | 
- 
-**=> b = 0x0000** 
- 
-=== crc-16 de '75' vaut : 0x6390! === 
-**=> b = 0x00** 
- 
-=== i=2 === 
-=== b = string [13] <=> 'C' [0000'1100] === 
- 
-. \\ . \\ . 
- 
-=== i=15 === 
-=== b = string [0] <=> 'A' [0000'1010] === 
- 
-. \\ . \\ . 
- 
-== bit_counter = 1 == 
- 
-. \\ . \\ . 
- 
-**=> crc = 0x00** 
onewire/crc.txt · Last modified: 2013/09/18 09:08 by sdolt