Dallas - CRC-beräkning-lite hjälp önskas.

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
benring
Inlägg: 900
Blev medlem: 18 januari 2005, 19:35:25

Dallas - CRC-beräkning-lite hjälp önskas.

Inlägg av benring »

Hej, jag har upptäckt att jag behöver använda CRC för att kontrollera fel i templäsningen på DS18s20.

Info om CRC finns här: http://www.maxim-ic.com/appnotes.cfm/appnote_number/27

Dock, som vanligt anser jag, så är det inte så självklara förklaringar man får, det är för mycket "runtomkring", tycker maxim ska se över sina beskrivningar....

Kan nån kortfattat tala om hur jag ska göra??

MVH / B
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Ursäkta????!!!!

Du har tabeller, assembler och exempler i överflöde! Vad begär du? Att vi ska skicka ett färdigt program????

Bättre beskrivning än denna har jag sällan sett!
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Notera att längst ner på sidan står det :

"Love it? Hate it? Think it could be better? Or just want to comment? Please let us know..."

Så det är väll bra att maila Maxim och föreslå förbättringar... :-)

Allvarligt talat, sidan fullständigt svämmar över av information, och kan väll kanske verka lite oöverstiglig, men å andra sidan är ju inte CRC beräkningar något som går att beskriva i ett par meningar.

> Kan nån kortfattat tala om hur jag ska göra??

Du får väll göra en CRC beräkning på det data som du får och jämföra resultatet med den CRC som du fick tillsammans med datat från givaren. Om de är lika så är sannolikheten mycket stor att datat är OK. *Hur* man beräknar en CRC finns som sagt beskrivet på Maxims sida.
Pjoms
EF Sponsor
Inlägg: 644
Blev medlem: 24 maj 2004, 12:18:40
Ort: Ö-vik

Inlägg av Pjoms »

Såja, lugn & fin nu! :)
Det här med CRC tyckte jag själv var ett elände tills jag fick till det. Jag vet fortfarande inte riktigt exakt hur det fungerar, jag nöjer mig med att det fungerar... :wink:
Nåväl.

Det du ska göra är att köra CRC-beräkningen på samtliga (nio) bytes du får från givaren. Resultatet av denna procedur skall bli 0 (noll) om allt är rätt, i annat fall har du ett CRC-fel = överföringsfel och får läsa datan på nytt från givaren.
Jag använder en assemblersnutt som jag hittat på nätet och förmodligen är snarlik med den på maxims sida.
benring
Inlägg: 900
Blev medlem: 18 januari 2005, 19:35:25

Inlägg av benring »

OJ, idag har vissa vaknat på fel sida. Icecap....... kan du tagga ner?

"Allvarligt talat, sidan fullständigt svämmar över av information, och kan väll kanske verka lite oöverstiglig, " JA, det är precis vad jag tycker.


Den informationen Pjoms gav är ungefär det jag lyckats få fram, grejen är att jag inte vet hur jag ska beräkna CRC:

CRC = X8 + X5 + X4 + 1 ? (ur databladet)

jag vet inte om jag vågar fortsätta denna tråd....


Tror jag gräver ner mig i databladet o uppfinner hjulet på nytt.

/B
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

OK, jag vaknade med feber och var ganska bitsk....förlåt.

Men allvar: jag har stirrat mig idiotisk på de där flödesscheman med shift-registre och XOR-gates så jag blev sinnessjuk (mer än vanligt) och de säger mig INGET!

Å andra sidan hade jag ett problem som innebar att jag var tvungen att greja just en CRC och jag var tvungen att dekoda hur den räknades ut via assembler, det var liiiite tidsödande. Men slutet blev (Borland C Builder):

Kod: Markera allt

WORD __fastcall TForm1::Checksum(BYTE * Data, WORD Size)
  {
  WORD Res1, Res2;
  BYTE X;
  BOOL Carry;
  const WORD Pattern = 0x1021;
  Res1 = 0; // Start point
  while(Size)
    {
    Res2  = (*Data) << 8;
    Res2 ^= Res1;
    for(X = 0; X < 8;X++) // Do 8 times
      {
      if(Res2 & 0x8000)
        {
        Res2 <<= 1; // Shift left 1 step
        Res2 ^= Pattern;
        }
      else
        {
        Res2 <<= 1; // Shift left 1 step
        }
      }
    Res1 = Res2;
    Data++;
    Size--;
    }
  return(Res1);
  }
Detta är inte hur du ska räkna ut det men en beskrivning i C hur det KAN vara, bara så att du får ett hum om det.
benring
Inlägg: 900
Blev medlem: 18 januari 2005, 19:35:25

Inlägg av benring »

Hoppas du mår bättre nu då;)


Jag programmerar i VB6, kan inte C precis, men får ett hum om hur besvärligt det verkar...

har inte den blekaste om vad som menas med EXOR o prylar.....


/B
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jorå...barnen i skola/dagis, tanten bortrest över dagen och en kanna te innanför.....mindre dålig.

XOR = gatetyp, t.ex. 7486, visas i det shift-flödes schema i länken.

C förklaring:
"while(Size)" = while(Size > 0)
"Res2 <<= 1" = Res = Res * 2
"Res2 ^= Pattern" = Res2 = Res2 XOR Pattern

I grunden betyder det att man rullar alla bits till vänster och OM man rullar "ut" en '1' XOR man det resterande med den konstant som passar just till den CRC man behöver.

Ganska enkelt....när man väl har fått till det! ;-)
benring
Inlägg: 900
Blev medlem: 18 januari 2005, 19:35:25

Inlägg av benring »

Bra att du mår bättre:)

"XOR = gatetyp, t.ex. 7486, visas i det shift-flödes schema i länken. "
Ledsen men jag hajjar inte detta alls, 7486, vad betyder det?


ok, men vad gör man när man "XOR det resterande" ? Hur vet man den konstant som passar just den CRC man behöver?

Säkert enkelt men just nu är jag lost;)

Får vi bara spåna på detta så släpper det nog, bara jag inte får i ansiktet att jag e korkad....fattar jag inte så fattar jag inte. Men jag är villig att lära mig...som bekant kanske.


/B
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Eftersom du har läst sidan (eller hur ?) så vet du nu att en CRC kan beräknas med lite olika metoder beroende på om man gör det i hårdvara eller programvara. 1-wire enheterna gör det i hårdvara och då använder man ett "återkopplat" skiftregsiter (figur 2 på Maxim sidan).

När man som du skall implementera en CRC beräkning i programvara kan man göra likadant (vilket ger kod som tar lite längre tid att köra men som ofta blir kompakt) eller vanligare via tabeller som gör CRC beräkningen 8 bitar i taget. Detta beskrivs utförligt på sidan (exemepl 1, 2, 3 och tabell 1). Denna metod tar lite mer plats (för lagringen av tabellen) men blir rellativt snabb.

(Delen om CRC-16 på sidan kan du glömma för tillfället...)

Lite andra länkar som kanske kan vara till hjälp :
http://www.piclist.com/techref/method/error/crc.htm
http://www.piclist.com/techref/method/m ... guide.html
http://www.piclist.com/techref/method/error/crccalc.htm
http://www.piclist.com/techref/method/crc_delphi.htm

Notera att den mesta färdiga koden använder andra CRC-polynom
än den som Maxim har för sina 1-wire enheter. Här är några exempel, notera att inget stämmer helt överens med Maxims polynom :
  • CCITT-32: 0x04C11DB7 = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
  • CRC-16: 0x8005 = x16 + x15 + x2 + 1
  • CRC-CCITT: 0x1021 = x16 + x12 + x5 + 1
  • CRC-XMODEM: 0x8408 = x16 + x15 + x10 + x3
  • 12bit-CRC: 0x80f = x12 + x11 + x3 + x2 + x + 1
  • 10bit-CRC: 0x233 = x10 + x9 + x5 + x4 + x + 1
  • 8bit-CRC: 0x07 = x8 + x2 + x + 1
Assembler exemplen på sidan är inte skrivna för PIC, men bör väll kunna portas utan allt för mycket problem, de är bra kommenterade. Kanske att lite av koden från piclist kan vara till hjälp också.

Till sist, när man har behov av kod för ett speciellt behov, kolla gärna arkivet på www.piclist.com (http://www.piclist.com/techref/microchip/routines.htm), där finns koder (i assembler) för det mesta man kan göra med en PIC... :-)
benring
Inlägg: 900
Blev medlem: 18 januari 2005, 19:35:25

Inlägg av benring »

Tack Sodjan, jo jag har läst sidan minst 2 ggr:)

tack så mycket för länkar o grejer, ska kolla på dessa.

"8bit-CRC: 0x07 = x8 + x2 + x + 1 " vad står X:et för?

Jag har defenetivt missat nått väsentligt hör, som hur jag räknar ut ovan.
(8bit-CRC: 0x07 = x8 + x2 + x + 1 ) tex.

/B
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Nu tror jag att jag vet vad du har svårt för!

Grejen i allt detta är att man (i detta fall) flyttar alla bits ett steg till vänster, kör uträkningen och sparar resultatet som den mest höger bit. Därefter gör man exakt det samma igen..och igen..och så framledes för alla bitar i orden (8 eller 9 bit = 8 eller 9 gånger), sen tar man nästa dataklump (byte/9 bit) och upprepar detta. Tar lite tid men kan göras ganska snabbt på olika sätt.

X8 + X2 + X + 1 är helt enkelt "bit 8" + "bit 2" + "bit 1" + "bit 0" + 1, summa ihop dessa värden till 1 bit (spola overflow), spara resultatet rätt ställe, skift bitsen 1 steg till vänster och upprepa....
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Och Maxim använder X8 + X5 + X4 + 1, men principen är densamma.

Hela operationen kan beskrivas i ord på lite olika sätt. Icecap's stämmer säkert, jag har inte tänkt igenom det helt, jag saknar bara hur man sedan kombinerar ihop resultaten från varje "dataklump". Man skall ju av 64 "in-bitar" få *ett* 8-bitars CRC-värde. Svaret ges delvis av beskrivningen av "table lookup" metoden på Maxims sida, där varje nytt index i listan (= ny 8-bitars "dataklump" i Icecaps teminologi :-) ), EXOR'as med föregående resultat innan ny tabelluppslagning görs.

Man kan även bygga ett simulerat shiftregister (t.ex ett register i PICen) där man skiftar in varje bit i taget från 64-bitars värdet. Sedan gör man lite bit-tester för at fixa återkopplingen (de tre EXOR grindarna i Figur 2). Sedan rullar man på i 64 "varv", och det som till slut ligger i 8 bitars registret är just CRC-värdet !

Behöver jag tillägga att Basic kanske inte är det smidigaste verktyget att fixa dett på ? Men du har ju fått igång inline-asm, så det skall väll lösa sig... :-)
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Här har du lite gammal CRC8-kod i VB som jag skrev för länge sedan.
Kanske finns något du har nytta av:

Kod: Markera allt

Public g_crc As Long

Public Sub crc_table(ByVal nVal As Long)
    Dim n As Long
    Dim CRC_ARRAY As Variant
    
    CRC_ARRAY = Chr(&H0) & Chr(&H5E) & Chr(&HBC) & Chr(&HE2) & Chr(&H61) & Chr(&H3F) & Chr(&HDD) & Chr(&H83) & Chr(&HC2) & Chr(&H9C) & Chr(&H7E) & Chr(&H20) & Chr(&HA3) & Chr(&HFD) & Chr(&H1F) & Chr(&H41) & _
                Chr(&H9D) & Chr(&HC3) & Chr(&H21) & Chr(&H7F) & Chr(&HFC) & Chr(&HA2) & Chr(&H40) & Chr(&H1E) & Chr(&H5F) & Chr(&H1) & Chr(&HE3) & Chr(&HBD) & Chr(&H3E) & Chr(&H60) & Chr(&H82) & Chr(&HDC) & _
                Chr(&H23) & Chr(&H7D) & Chr(&H9F) & Chr(&HC1) & Chr(&H42) & Chr(&H1C) & Chr(&HFE) & Chr(&HA0) & Chr(&HE1) & Chr(&HBF) & Chr(&H5D) & Chr(&H3) & Chr(&H80) & Chr(&HDE) & Chr(&H3C) & Chr(&H62) & _
                Chr(&HBE) & Chr(&HE0) & Chr(&H2) & Chr(&H5C) & Chr(&HDF) & Chr(&H81) & Chr(&H63) & Chr(&H3D) & Chr(&H7C) & Chr(&H22) & Chr(&HC0) & Chr(&H9E) & Chr(&H1D) & Chr(&H43) & Chr(&HA1) & Chr(&HFF) & _
                Chr(&H46) & Chr(&H18) & Chr(&HFA) & Chr(&HA4) & Chr(&H27) & Chr(&H79) & Chr(&H9B) & Chr(&HC5) & Chr(&H84) & Chr(&HDA) & Chr(&H38) & Chr(&H66) & Chr(&HE5) & Chr(&HBB) & Chr(&H59) & Chr(&H7) & _
                Chr(&HDB) & Chr(&H85) & Chr(&H67) & Chr(&H39) & Chr(&HBA) & Chr(&HE4) & Chr(&H6) & Chr(&H58) & Chr(&H19) & Chr(&H47) & Chr(&HA5) & Chr(&HFB) & Chr(&H78) & Chr(&H26) & Chr(&HC4) & Chr(&H9A) & _
                Chr(&H65) & Chr(&H3B) & Chr(&HD9) & Chr(&H87) & Chr(&H4) & Chr(&H5A) & Chr(&HB8) & Chr(&HE6) & Chr(&HA7) & Chr(&HF9) & Chr(&H1B) & Chr(&H45) & Chr(&HC6) & Chr(&H98) & Chr(&H7A) & Chr(&H24) & _
                Chr(&HF8) & Chr(&HA6) & Chr(&H44) & Chr(&H1A) & Chr(&H99) & Chr(&HC7) & Chr(&H25) & Chr(&H7B) & Chr(&H3A) & Chr(&H64) & Chr(&H86) & Chr(&HD8) & Chr(&H5B) & Chr(&H5) & Chr(&HE7) & Chr(&HB9) & _
                Chr(&H8C) & Chr(&HD2) & Chr(&H30) & Chr(&H6E) & Chr(&HED) & Chr(&HB3) & Chr(&H51) & Chr(&HF) & Chr(&H4E) & Chr(&H10) & Chr(&HF2) & Chr(&HAC) & Chr(&H2F) & Chr(&H71) & Chr(&H93) & Chr(&HCD) & _
                Chr(&H11) & Chr(&H4F) & Chr(&HAD) & Chr(&HF3) & Chr(&H70) & Chr(&H2E) & Chr(&HCC) & Chr(&H92) & Chr(&HD3) & Chr(&H8D) & Chr(&H6F) & Chr(&H31) & Chr(&HB2) & Chr(&HEC) & Chr(&HE) & Chr(&H50) & _
                Chr(&HAF) & Chr(&HF1) & Chr(&H13) & Chr(&H4D) & Chr(&HCE) & Chr(&H90) & Chr(&H72) & Chr(&H2C) & Chr(&H6D) & Chr(&H33) & Chr(&HD1) & Chr(&H8F) & Chr(&HC) & Chr(&H52) & Chr(&HB0) & Chr(&HEE) & _
                Chr(&H32) & Chr(&H6C) & Chr(&H8E) & Chr(&HD0) & Chr(&H53) & Chr(&HD) & Chr(&HEF) & Chr(&HB1) & Chr(&HF0) & Chr(&HAE) & Chr(&H4C) & Chr(&H12) & Chr(&H91) & Chr(&HCF) & Chr(&H2D) & Chr(&H73) & _
                Chr(&HCA) & Chr(&H94) & Chr(&H76) & Chr(&H28) & Chr(&HAB) & Chr(&HF5) & Chr(&H17) & Chr(&H49) & Chr(&H8) & Chr(&H56) & Chr(&HB4) & Chr(&HEA) & Chr(&H69) & Chr(&H37) & Chr(&HD5) & Chr(&H8B) & _
                Chr(&H57) & Chr(&H9) & Chr(&HEB) & Chr(&HB5) & Chr(&H36) & Chr(&H68) & Chr(&H8A) & Chr(&HD4) & Chr(&H95) & Chr(&HCB) & Chr(&H29) & Chr(&H77) & Chr(&HF4) & Chr(&HAA) & Chr(&H48) & Chr(&H16) & _
                Chr(&HE9) & Chr(&HB7) & Chr(&H55) & Chr(&HB) & Chr(&H88) & Chr(&HD6) & Chr(&H34) & Chr(&H6A) & Chr(&H2B) & Chr(&H75) & Chr(&H97) & Chr(&HC9) & Chr(&H4A) & Chr(&H14) & Chr(&HF6) & Chr(&HA8) & _
                Chr(&H74) & Chr(&H2A) & Chr(&HC8) & Chr(&H96) & Chr(&H15) & Chr(&H4B) & Chr(&HA9) & Chr(&HF7) & Chr(&HB6) & Chr(&HE8) & Chr(&HA) & Chr(&H54) & Chr(&HD7) & Chr(&H89) & Chr(&H6B) & Chr(&H35)
    
    n = (nVal Xor g_crc) And &HFF
    g_crc = Asc(Mid(CRC_ARRAY, n + 1, 1))
End Sub

Public Function crc_calc(ByVal varData As Variant) As Long
    Dim n As Long
    
    g_crc = 0
    For n = 1 To Len(varData)
        crc_table Asc(Mid(varData, n, 1))
    Next
    
    crc_calc = g_crc
End Function
Inte den snyggaste koden, men den var smidig till den tillämpning jag behövde den till.

Mvh
speakman
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

I princip samma kod som på Maxims sida, fast i Basic... :-)
Vilket CRC polynom är det ? Om det inte stämmer med det som Maxim använder så är ju tabellen helt fel...
Skriv svar