[CRC - 8 CRC - 16]

Signaler
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006
-
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006
-
Bonjour,

J'essaie de le resoudre un probleme depuis deja 2 semaines sans resultats ...

Je dois pour un projet, Créer une commnication seriel entre un pc et un automate satchwell.

J'ai reussi apres longue recherche à comprendre les differents octets du message à recréer.

Malgré tout ca, j'ai du soutirer quelque information pour comprendre 3 octets dont je ne comprennais pas la logique.

On ma alors dit que le message contennant un CRC- 8 et un CRC 16.

Le message se decompose ainsi :

Octet 0 à Octet 13 : Information propre au protocole (header)
Octet 14 : CRC - 8 portant sur les octets de 0 à 13
Octet 15 à X( longeur non constante) : Information propre au protcole (data)
Octet (N-1) : CRC16 (poids faible) portant sur les octects 16 à (N-2)
Octet (N) : CRC (poids fort)

Le polynome du CRC 8 est : X^8 + X^7 + 1
Le polynome du CRC 16 est : X^16 + X^12 +X^5 + 1

On m'as egalement fourni des petites routines en mais pas dans le language que je comprends :

ca vous aidera peut etre à m'aider lol :

CRC 8 :

unsigned char calcHeaderCRC (unsigned char datavalue, unsigned char crcvalue)
{
Unsigned int crc;

crc = crcvalue ^ datavalue;
crc = crc ^ (crc<<1) ^ (crc<<2) ^ (crc<<3) ^ (crc<<4) ^ (crc<<5) ^ (crc<<6) ^ (crc<<7) ;

return (crc & Oxfe) ^((crc<<8) & 1);
}

CRC 16 :

unsigned int calcdataCRC (unsigned char datavalue, unsigned char crcvalue)

{

Unsigned int crclow;



crclow = (crcvalue & 0xff) ^ datavalue;

return ((crcvalue>>8) ^ (crclow<<8) ^ (crclow<<3) ^
(crclow<<12) ^ (crclow>>4) ^ (crclow & 0x0f) ^ ((crclow & 0x0f)<<7)) ;



}
Voila

Je vais mettre aussi des trames types de l'automate pour que vous pouviez tester si vous avez le temps.

[AA 00 01 08 01 FF 02 00 1C 81 72 04 0A 00] E6 (00 00 7F FF) 55 7F
[AA 00 01 FF 01 08 00 88 1C 81 72 04 0A 00] 92

Entre [] C'est le header ( premiere partie )
Entre () C'est le data ( Deuxieme partie )
En vert le CRC 8 sur un Octet
En rouge le CRC 16 Sur 2 Octet

Merci d'essayer de prendre un peu de votre temps pour m'aider.

J'ai deja essayé sans succes tout les codes CRC présent sur le forum.

J'ai a part ca essayer de comprendre la trame en C :

^ : ou exclusif
>> : decalage de mot binaire

A part ca je sius un peu perdu et ca fais plus de 3 semaine que je bloque la dessus.

Merci de m'aider

12 réponses

Messages postés
363
Date d'inscription
vendredi 14 février 2003
Statut
Membre
Dernière intervention
20 avril 2010
3
petit exemple de ce que je t'expliquais



unsigned char calcHeaderCRC (unsigned char datavalue, unsigned char crcvalue)
{
Unsigned int crc;

crc = crcvalue ^ datavalue;

crc = crc ^ (crc<<1) ^ (crc<<2) ^ (crc<<3) ^
(crc<<4) ^ (crc<<5) ^ (crc<<6) ^ (crc<<7) ;

return (crc & Oxfe) ^((crc<<8) & 1);
}





devient



public function calcHeaderCRC (datavalue as integer, crcvalue as integer) as integer

dim crc as integer

crc = crcvalue xor datavalue

crc = crc xor (crc *2) xor (crc*4) xor (crc*8) xor (crc*16) xor (crc*32) xor (crc*64) xor (crc *128)

calcHeaderCRC = (crc and &HFE) Xor ((crc * 256) And 1)

end function
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006

Merci mais mon suicide n'est pas retardé lol

Je pete les plombs :

Vu la longeur de mes trames qui sont en Hex.

Je dois les passer en Dec pour les entrées dans la fonction, Rien que les entrées dans une variable me mets un beau overflow !

Je comprends rien !

datavalue = val("&H" & "AA00010801FF02001C8172040A00")
crcvalue = val("&H" & "11021")

public function calcHeaderCRC (datavalue as integer, crcvalue as integer) as integer
dim crc as integer
crc = crcvalue xor datavalue
crc = crc xor (crc *2) xor (crc*4) xor (crc*8) xor (crc*16) xor (crc*32) xor (crc*64) xor (crc *128)
calcHeaderCRC = (crc and &HFE) Xor ((crc * 256) And 1)
end function

Merci de m'aider

Et si pour ceux qui ont quelque chose pour tester le C pouvais voir si ca donne vraiment le bon crc avec la trame d'origine ..

Je suis au bord du goufre Help me Mario !
Messages postés
363
Date d'inscription
vendredi 14 février 2003
Statut
Membre
Dernière intervention
20 avril 2010
3
regarde plutot ta trame comme une chaine de caractère et tu fais le traitement caractère par caractère
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006

Je comprends pas ce que tu veux dire

Decouper? tu vx dire couper octet par octet ?
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
36
Salut akuvido, je viens effectivement de tester ton code en C, et je ne trouve pas les bons CRC.

pour les crc8 je trouve respectivement 0x46 et 0x58 et pour le crc16 je trouve 0xfdd3.

JE continue à vérifier mon code, je suis pas sur de tout car j'ai voulu codé avec le C++ de VS2003 et les tailles des variables ne sont pas les mêmes.

Je vais repasser sous VC6 pour vérifier.

Je cherche moi aussi l'algorithme du CRC16 et du CRC32 car j'aurais très bientot à coder ça pour du controle à la volée de transmissions séries.


Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006

ERRATUM

Désolé, j'ai fait une erreur en recopiant le code pour le CRC - 8

Ceci est la version corigée :

unsigned char calcHeaderCRC (unsigned char datavalue, unsigned char crcvalue)
{
Unsigned int crc;

crc = crcvalue ^ datavalue;
crc = crc ^ (crc<<1) ^ (crc<<2) ^ (crc<<3) ^ (crc<<4) ^ (crc<<5) ^ (crc<<6) ^ (crc<<7) ;

return (crc & 0xfe) ^((crc>>8) & 1);
}

Voila desolé de t'avoir fait travailler pr rien Casy !

Par contre le code du CRC 16 est correcte !

Merci pour ceux qui tente de m'aider parce que je suis vraiment dans le caca
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006

Je refléchissant a ce que vpoyo m'as dit :

"regarde plutot ta trame comme une chaine de caractère et tu fais le traitement caractère par caractère"

Je vois pas ce que traité partie par partie ferait.

L'overflow disparaitrais surement mais le but de ce calcul est de combiner toute les infomations pour trouver le Crc et je ne pense pas que ce soit la bonne solution de le faire comme tu le propose.

Merci de m'aider.

Peut etre qu'une erreure s'est glissé dans la converssion du language C en basic, car casy n'a pas le probleme d'overflow en utilisant la version C.

Je suis vraiment dessesperé et le temps commence a etre compté.

Merci d'essayer de m'aider qd meme.
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
36
Non akuvido, je n'ai pas le problème d'overflow, car je traite caractère par caractère en faisant une boucle et donnant en paramètre pour le caractère suivant, le calcul du crc sur le caractère précédent. Tout comme l'a dit vpoyo (j'avoue que ça m'a sembler tellement logique que je ne me suis même pas posé la question).

C'est ce que suggère les fonctions C qui t'ont été passées puisque'elles prenne un crc en paramètre.

Le problème c'est qu'en faisant le même code sous .NET et sous VS6, je trouve 2 résultats totalement différents. 3 si je tient compte du changement de formet des types de variables en .NET.
Aucun des résultats ne correspondent aux crc de tes trames.

En résumé, je suis pas capable de dire si tes algos sont corrects (le polynomme n'est peut-etre pas le bon), et je n'ai toujours pas trouver de solutions à mes propres problèmes.


Messages postés
363
Date d'inscription
vendredi 14 février 2003
Statut
Membre
Dernière intervention
20 avril 2010
3
l'algo je le connais pas !



par contre tu gères ca comme une "chaine de caractère" ou un tableau de
Byte (ou octet) et tu calcul toujours par rapport avec résultat courant



premier octet tu as une valeur, ensuite tu fais le second par rapport
au premier, puis le troisième par rapport au résultat des deux
précédents, et ainsi de suite jusqu'à la fin.
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006

J'ai suivi vos conseil et j'en suis arrivé a ca pour le CRC 8
Il faut mettre la trame a traité dans Text1.text et on recuperer le CRC dans Text2.text

Dim octet() As Byte
Dim traite() As Byte
Dim crc As Long
Dim long_trame As Integer

Private Sub Command1_Click()
long_trame = Len(Text1.Text)
ReDim octet(long_trame)
ReDim traite(long_trame)

For i = 1 To long_trame

octet(i) = Val("&H" & Mid(Text1.Text, i, 1))

Next i

End Sub

Private Sub Command2_Click()

For i = 1 To long_trame

datavalue = octet(i)
If i 1 Then crcvalue 385 Else: crcrvalue = calcHeaderCRC ' d'385 = h'181 = 'X^8 + X^7 + 1 ( si j'ai bien compris)

crc = crcvalue Xor datavalue
crc = crc Xor (crc * 2) Xor (crc * 4) Xor (crc * 8) Xor (crc * 16) Xor (crc * 32) Xor (crc * 64) Xor (crc * 128)
calcHeaderCRC = (crc And &HFE) Xor ((crc / 256) And 1)

Next i

Text2.Text = Hex(calcHeaderCRC)

End Sub

Mais ca ne fonctionne pas.

Je tombe sur des CRC differents de ceux des bons et meme differents de ceux que casy a trouvé .

Si vous pouviez verifié si mon code est bon ca serai cool.
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006

Ca serai sympa que de regarder mon code pour voir si ca vous semble coherant comme approche car je suis vraiment mal barrer et ca va bientot faire un mois que je suis bloqué ladessus.

Merci d'avance
Messages postés
13
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
18 avril 2006

Je crois m'etre rendu compte que le CRC 8 est calculer sur les octets du header.

Et d'apres ce que je viens de comprendre dans la doc constructeur le header ne prends pas en compte les octets de debuts.

le calcul du CRC se ferait donc sur les 12 octets et non sur les 14 :

ces 2 trames donnerai donc les CRc en Vert
header 01 08 01 FF 02 00 1C 81 72 04 0A 00 crc E6 header 01 FF 01 08 00 88 1C 81 72 04 0A 00 crc 92

Pourriez vous svp tester ce code et me dire si les reponses corresponsent a ce que ca doit donner.

unsigned char calcHeaderCRC (unsigned char datavalue, unsigned char crcvalue)
{
Unsigned int crc;

crc = crcvalue ^ datavalue;

crc = crc ^ (crc<<1) ^ (crc<<2) ^ (crc<<3) ^
(crc<<4) ^ (crc<<5) ^ (crc<<6) ^ (crc<<7) ;

return (crc & 0xfe) ^((crc>>8) & 1);
}

Je suis vraiment mal barer l'echeance approche et je n'arrive a rien depuis un mois.

Merci d'avance