IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Calcul d'un CRC-8


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2013
    Messages : 49
    Points : 28
    Points
    28
    Par défaut Calcul d'un CRC-8
    Bonjour à tous,

    Je rencontre quelques problèmes pour calculer un CRC-8 selon cette documentation :

    Nom : CRC-8_Scaime.png
Affichages : 4571
Taille : 71,8 Ko

    Déjà le polynôme ne me semble pas cohérent par rapport au schéma ou alors je comprend mal...

    Voici ma fonction pour le calcul du CRC :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    unsigned char cScmbusCrc8Calc ( unsigned char *pcBufData, unsigned short wNbData )
    {
    	unsigned char cLoopBit, cCrc;
    	unsigned char *pcPtr;
    	unsigned short wLoopData;
     
    	/* Initialisation */
    	/*================*/
    	pcPtr = pcBufData;
    	cCrc = 0x00;
     
    	/* Calcul CRC8 */
    	/*=============*/
    	for ( wLoopData = 0 ; wLoopData < wNbData ; wLoopData ++ )
    		{
    		cCrc ^= *pcPtr;
    		pcPtr ++;
    		for ( cLoopBit = 0 ; cLoopBit < 8 ; cLoopBit ++ )
    			{
    			if ( (cCrc & 0x80) != 0 )
    				{
    				cCrc <<= 1;
    				cCrc ^= 0x99;
    				}
    			else
    				cCrc <<= 1;
    			}
    		}
     
    	/* Fin */
    	/*=====*/
    	return (cCrc);
    }

    Par exemple pour cette trame : 0x01 0x31 0x0D ma fonction calcule ce CRC : 0x40

    Sauf que ce CRC n'est pas correct apparemment puisque mon appareil ne répond pas..

    Par contre si je force le CRC à la valeur : 0xFC j'obtiens une trame réponse.

    Si quelqu'un à une idée au vu de la documentation ou à partir du bon CRC (FC) je suis preneur !

    Merci,

    Jérôme .G

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,
    En suivant 'manuellement' le parcours des 24 bits à traiter j'obtient bien FC
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    injection du 01 en commençant par le bit faible
    1 ==> 1 0000000 -> 1
    0 ==> 1 1000000 -> 1
    0 ==> 1 1100000 -> 1
    0 ==> 1 1110000 -> 0
    0 ==> 0 1111000 -> 0
    0 ==> 0 0111100 -> 0
    0 ==> 0 0011110 -> 0
    0 ==> 0 0001111 -> 0
    injection du 31 en commençant par le bit faible
    1 ==> 1 0000111 -> 0
    0 ==> 0 1000011 -> 1
    0 ==> 1 0100001 -> 0
    0 ==> 0 1010000 -> 1
    1 ==> 0 0101000 -> 1
    1 ==> 0 0010100 -> 1
    0 ==> 1 0001010 -> 0
    0 ==> 0 1000101 -> 1
    1 ==> 0 0100010 -> 0
    injection du 0D en commençant par le bit faible
    0 ==> 0 0010001 -> 0
    1 ==> 1 0001000 -> 0
    1 ==> 1 1000100 -> 1
    0 ==> 1 1100010 -> 1
    0 ==> 1 1110001 -> 1
    0 ==> 1 1111000 -> 1
    0 ==> 1 1111100 <=> FC

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2013
    Messages : 49
    Points : 28
    Points
    28
    Par défaut
    Bonjour,

    Merci de ta réponse. Tu obtiens ce résultat en suivant ma fonction ou d'après la documentation ?

    Jérôme .G

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Je n'ai fait que suivre le schéma de la doc

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2013
    Messages : 49
    Points : 28
    Points
    28
    Par défaut
    D'accord. Je suis un peu perdu en fait, pourquoi a-t-on x à la puissance 8 alors qu'on est sur 8 bits ? Pour moi, ça en ferait 9 si je convertissais le polynôme en binaire…
    Bon en cherchant un peu, j'avais souvent vu des puissances de 8 pour des CRC 8 bits donc… J'en ai déduit que le polynôme était 10011001 soit 0x99

    Par contre, en faisant un relevé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    unsigned char cScmbusCrc8Calc ( unsigned char *pcBufData, unsigned short wNbData )
    {
    	unsigned char cLoopBit, cCrc;
    	unsigned char *pcPtr;
    	unsigned short wLoopData;
     
    	/* Initialisation */
    	/*================*/
    	pcPtr = pcBufData;
    	cCrc = 0x00;
     
    	/* Calcul CRC8 */
    	/*=============*/
    	Uart3WriteCar ('A');
    	for ( wLoopData = 0 ; wLoopData < wNbData ; wLoopData ++ )
    		{
    		Uart3WriteCar ('B');
    		cCrc ^= *pcPtr;
    		pcPtr ++;
    		for ( cLoopBit = 0 ; cLoopBit < 8 ; cLoopBit ++ )
    			{
    			if ( (cCrc & 0x80) != 0 )
    				{
    				Uart3WriteCar ('1');
    				cCrc <<= 1;
    				cCrc ^= 0x99;
    				}
    			else
    				{
    				Uart3WriteCar ('0');
    				cCrc <<= 1;
    				}
    			}
    		}
    	Uart3WriteCar ('C');
     
    	/* Fin */
    	/*=====*/
    	Uart3WriteCar (KC_ASCII_CR);
    	return (cCrc);
    }
    J'obtiens : AB00000001B11000011B01000000C

    J'ai l'impression qu'en fait, ma fonction parcourt les octets en commençant par le bit de poids fort et non celui de poids faible comme dans ta réponse. Est-ce correct ?

    Merci.
    Jérôme .G

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Le 8ième bit c'est le bit de la donnée à traiter (on le voit sur le schéma), il faut lire les bits les uns après les autres et les injecter dans la formule.
    As-tu compris mon schéma de déroulement ? On injecte un bit en décalant le crc.
    En C, cela donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       unsigned char crc = 0;
       unsigned char retenue = 0;
       for ( wLoopData = 0 ; wLoopData < wNbData ; wLoopData ++ )
       {
          unsigned char octet_lu = *pcPtr++;
          for ( cLoopBit = 0 ; cLoopBit < 8 ; cLoopBit ++ )
          {
             crc = ( ( octet_lu ^ retenue)  << 7 )   |  (crc >> 1); // nouveau crc
             retenue = (crc>>7)^(crc>>4)^(crc>>3)^crc; // retenue a xorer (dans bit0), autres bits quelconques
             octet_lu >>= 1; // bit suivant
          }
       }
    Il existe un moyen de traiter les bits 8 par 8, pour cela il faut utiliser un table de 256 octets, si tu as la place la méthode est nettement plus rapide.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2013
    Messages : 49
    Points : 28
    Points
    28
    Par défaut
    Je comprend pour le 8ème bit, merci.

    Pour ton schéma de fonctionnement oui et non, dans l'idée je comprend comment doit se faire le calcul du CRC mais je n'arrive pas à me repérer en lisant ton schéma. Il faut que je prenne le temps de me documenter le plus possible mais je manque un peu de temps..

    J'ai un peu modifier ta fonction pour qu'elle compile de mon côté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    unsigned char cScmbusCrc8Calc2 ( unsigned char *pcBufData, unsigned short wNbData )
    {
    	unsigned char cCrc = 0;
    	unsigned char retenue = 0;
    	unsigned char cLoopBit = 0;
    	unsigned char *pcPtr;
    	unsigned short wLoopData;
     
     
    	for ( wLoopData = 0 ; wLoopData < wNbData ; wLoopData ++ )
    		{
    		unsigned char octet_lu = *pcPtr++;
    		for ( cLoopBit = 0 ; cLoopBit < 8 ; cLoopBit ++ )
    			{
    			cCrc = ( ( octet_lu ^ retenue)  << 7 )   |  (cCrc >> 1); // nouveau crc
    			retenue = (cCrc>>7)^(cCrc>>4)^(cCrc>>3)^cCrc; // retenue a xorer (dans bit0), autres bits quelconques
    			octet_lu >>= 1; // bit suivant
    			}
    		}
     
    	return (cCrc);
    }
    Mais elle fait planter ma carte au bout de quelques tours de main en calculant un CRC différent à chaque fois. Je vais essayer de voir pourquoi.

    J'ai lu quelques articles parlant d'utiliser un table de 256 octets, je m'y intéresserait dans un 2ème temps pour optimiser si le besoin se fait sentir.

    Merci de ton aide en tout cas, n'hésite pas si tu as d'autres idées ou si tu vois ce qui être faux dans ma fonction

  8. #8
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    dans ton exemple pcPtr n'est pas initialisé, il devrait valoir pcBuffData

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2013
    Messages : 49
    Points : 28
    Points
    28
    Par défaut
    Ca fonctionne très bien merci beaucoup !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Calcul d'un CRC 16 bits
    Par pinto_armindo dans le forum Programmation et administration système
    Réponses: 5
    Dernier message: 22/06/2006, 15h35
  2. Calcul CRC ISO3309
    Par zodd dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 29/05/2006, 13h35
  3. calcul du CRC sur 2 octets
    Par jeannot27 dans le forum C++Builder
    Réponses: 6
    Dernier message: 19/12/2005, 10h55
  4. [SRC] Calcul de CRC
    Par cfdev dans le forum C++Builder
    Réponses: 3
    Dernier message: 07/03/2005, 13h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo