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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    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 : 5063
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 confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 599
    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
    Membre averti
    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
    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 confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 599
    Par défaut
    Je n'ai fait que suivre le schéma de la doc

  5. #5
    Membre averti
    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
    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 confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 599
    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.

+ 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