logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

CRC8 w C: Błąd w algorytmie transmisji SPI z wielomianem x8 + x2 + x + 1

alex2c 29 Cze 2008 11:18 6732 21
REKLAMA
  • #1 5296115
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Witam
    Przejrzałem wszystkie stosowne posty na elektrodzie i z ich pomocą próbowałem napisać transmisję po SPI z CRC8 (x8 + x2 + x + 1).
    Transmisja bez CRC przebiega pomyślnie, lecz z CRC nie ;/
    Potrzebuję Waszego potwierdzenia, że liczę poprawnie kod CRC8 lub korekty algorytmu. Próbowałem już na chyba wszystkie sposoby obliczać tę sumę. Wykorzystanie gotowej tablicy lub obliczanie jej "w locie"nie dało żadnych efektów. Początkowa wartość crc8 = 0 lub 0xff również nie pomogła jak również mnożenie za każdym razem wyniku przez 0xff (jak w przykładzie). Proszę o radę. Myślę, że błąd tkwi w moim algorytmie CRC8, ale gdzie ??
    Dziękuję za wszelkie uwagi i pozdrawiam

    Poniżej zamieszczam jeden z algorytmów, który próbowałem wykorzystać. Obliczanie tablicy CRC8 napisał użytkownik NOTSET, na TYM poście.
    -----------

    
        unsigned char crc8_temp = 0;
        unsigned char CRC8_TABLE[256];
        
        /*Obliczanie tablicy sumy kontrolnej CRC8*/
        unsigned char r; 
        int i, j; 
        for (i = 0; i < 256; i++) 
        { 
                 r = (unsigned char) i; 
                 for (j = 0; j < 8; j++) 
                     r = (unsigned char) ((r << 1) ^ ((r & 0x80) ? 0x07 : 0)); 
                 CRC8_TABLE[i] = r; 
        }
        /*suma CRC8 z 3 bajtow*/
    	crc8_temp = CRC8_TABLE[(crc8_temp ^ dat2) & 0xff];
    	crc8_temp = CRC8_TABLE[(crc8_temp ^ dat1) & 0xff];
    	crc8_temp = CRC8_TABLE[(crc8_temp ^ dat0) & 0xff];
    



    [Przenoszę z "Początkujący Nauka". Mariusz Ch.]
  • REKLAMA
  • #3 5299006
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Moim zdaniem typy zmiennych są jak najbardziej ok. Komunikacja na 8bitach oraz kod crc8 na 8 bitach wiec CHAR w zupełności wystarcza.
    Jeśli chodzi o RZUTOWANIE, to nie za bardzo rozumiem o co Ci chodzi, czy o mnożenie poprzez maskę 0xff po każdym kroku XORa ? Jeśli tak to próbowałem na różne sposoby (z maskowaniem oraz bez) i żaden nie był poprawny ;/ Muszę się przyznać, że nie do końca wiem jak działa funkcja wypełniająca macierz, tak więc nie mogę ingerować w nią ;/
    Może ktoś podzieli się własną, działającą funkcją ?
    pozdro
  • REKLAMA
  • #4 5299068
    maciek_slon
    Poziom 29  
    Posty: 942
    Pomógł: 143
    Ocena: 27
    Skoro na końcu ma być suma z trzech to rób sumę (operator +=) zamiast zwykłego przypisania (=)
  • #5 5299078
    Dżyszla
    Poziom 42  
    Posty: 7075
    Pomógł: 1095
    Ocena: 224
    zapodaj w necie hasło "rzutowanie" ;) Nie podoba mi się po prostu niepotrzebne mieszanie różnych typów zmiennych.

    Proponuję rozpisać sobie przykład na kartce i zdebugować - na pewno wyjdzie na jaw, gdzie bład... (nie analizuję całości - nie pamiętam dokłądnie zasad obliczania CRC).

    Dodano po 47 [sekundy]:

    Maciek - tam rekurencyjnnie jest jakoś liczone, więc może jest to poprawne jednak? ;)
  • #6 5299688
    szelus
    Poziom 34  
    Posty: 1508
    Pomógł: 315
    Ocena: 53
    1. Po "drugiej stronie" sam liczysz CRC, czy jest inny kod?
    2. Może kolejność bajtów powinna być odwrotna, tzn. zaczynać się od dat0?
  • #7 5299975
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    A czy nie jest tak, że jak policzę crc z każdego bajtu i wszystkie 3 sumy kontrolne dodam to będzie poprawnie ?
    Próbowałem już nawet odwrócić lustrzanie bajt crc8 i to również nie poskutkowało ;/
    "Z drugiej strony" CRC8 liczy przetwornik i albo się zgodzi z moją wysłaną sumą albo nie.

    Jeszcze raz pod wieczór popróbuję z gotową tablicą i się odezwę, dzięki za zainteresowanie.

    DŻYSZLA, wójek google opowiedział mi trochę o rzutowaniu ;) aczkolwiek nie rozumię dlaczego piszesz, że mieszam typy zmiennych, wszędzie wykorzystany jest unsigned char.
    -----
    Dla zainteresowanych CRC8 (x8 + x2 + x + 1):
    
    unsigned char CRC8_TABLE[256] = {
    	    0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,
    	    0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D,
    	    0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,
    	    0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D,
    	    0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,
    	    0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,
    	    0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,
    	    0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD,
    	    0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,
    	    0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,
    	    0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,
    	    0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A,
    	    0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32,
    	    0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,
    	    0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,
    	    0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,
    	    0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C,
    	    0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4,
    	    0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,
    	    0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,
    	    0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,
    	    0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,
    	    0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,
    	    0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34,
    	    0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,
    	    0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,
    	    0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,
    	    0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13,
    	    0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,
    	    0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83,
    	    0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,
    	    0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3
    	    };
    
  • #8 5299991
    Dżyszla
    Poziom 42  
    Posty: 7075
    Pomógł: 1095
    Ocena: 224
    i jest typu signed int. Ponadto - czy konieczne jest rzutowanie w linijce
    
    r = (unsigned char) ((r << 1) ^ ((r & 0x80) ? 0x07 : 0)); 
    
    ?

    A może podaj wyniki uzyskiwane tym programem oraz oczekiwane?

    A jest jeszcze opcja - program liczy dobrze, "przetwornik" - źle? Względnie ten drugi jako daną traktuje też samą sumę kontrolną?
  • REKLAMA
  • #9 5301366
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Nie ma znaczenia jakiego typu jest zmienna "i", ona nie bierze udziału w bezpośrednim liczeniu sumy kontrolnej, aczkolwiek faktem jest że niepotrzebnie zajmuje większy obszar.

    Odnośnie rzutowania zmiennej "r" masz rację, że jest to niekonieczne w tej linijce, jednak nie ma to wpływu na samo liczenie.

    Nie rozumię jednak zapisu:
    ((r << 1) ^ ((r & 0x80) ? 0x07 : 0));

    Mógłby mi ktoś "przeczytać" ten fragment ?

    Korzystam z Eclipse, w którym debugger nie działa mi i nie wiem dlaczego, czytałem gdzieś że dużo problemów z nim jest.
    Mnie wyskakuje błąd:
    java.lang.NullPointerException ;/ ale to nie temat tej dyskusji.

    Nie ma możliwości aby DAC źle liczył CRC8, chyba że jest upalony ale to nie wchodzi w gre z prostej przyczyny, że reszta śmiga w najlepsze, poza tym nie dałem mu żadnego powodu na odmówienie współpracy ze mną ;)
    Dodatkowy bajt crc8 jest postrzegany jako dodatkowy bajt ramki (rysunek poniżej).

    Poniżej zamieszczam skan z noty prezentujący 2 możliwe transmisje po SPI z DACiem.
    CRC8 w C: Błąd w algorytmie transmisji SPI z wielomianem x8 + x2 + x + 1
  • #10 5301612
    szelus
    Poziom 34  
    Posty: 1508
    Pomógł: 315
    Ocena: 53
    A jesteś pewien, że to FCS to CRC-8 liczone wg tego właśnie wielomianu? Co to za przetwornik?
  • #11 5302163
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Korzystam z przetwornika firmy Analog Devices AD5363. Podana powyżej funkcja powinna obliczać tablicę właśnie dla wielomianu CRC8 (x8 + x2 + x + 1), przynajmniej jej autor tak twierdzi. Właśnie w tym tkwi mój problem, że nie wiem co jest pewne ;/ niby mam tablicę, która w kilku miejscach była podpisana powyższym wielomianem, ale nikt nie może mi tego potwierdzić ;/ Z algorytmem jest podobna sprawa.

    Od wczoraj walczę z "metodą tablicową". Tablica jest dostępna powyżej a funkcje zamieszczam poniżej. Transmisja przebiega w trybie DMA, uP ARM7 (AT91SAM7S128), ale to w sumie nie ważne. Sprawa tak wygląda, że jeśli number_of_data=3 to wysyłam dane bez CRC8 i wtedy wszystko OK, jeśli number_of_data=4 to wysyłam również CRC8 i wtedy sygnał błedu jest aktywny (logiczne 0, co jest równoważne wyłączeniu diody LED).

    Część kodu, jaka sprawia mi problem, jest pomiędzy /*--------*/

    void DAC_send_crc(unsigned char dat2, unsigned char dat1, unsigned char dat0) 
    {
        unsigned int *wskaznik;
        unsigned int tablica[4];
        unsigned char crc8 = 0;
    /*--------------------------------------------------*/
        /*Obliczanie sumy kontrolnej CRC 8*/
        crc8= CRC8_TABLE[crc8^dat2];
        crc8= CRC8_TABLE[crc8^dat1];
        crc8= CRC8_TABLE[crc8^dat0];
    /*--------------------------------------------------*/
        /*Przypisanie adresow kolejnym 4 bajtom do wysylki w trybie DMA*/
        tablica[1]=dat2;
        tablica[2]=dat1;
        tablica[3]=dat0;
        tablica[4]=crc8;
    
        /*Ustawienie wskaznika na pierwszym bajcie tablicy oraz liczba bajtow do wysylki*/
        wskaznik = &tablica[1];
        unsigned int number_of_data=3; 
    
        while(!(BASE_SPI->SPI_SR & AT91C_SPI_ENDTX));        
        BASE_SPI->SPI_TPR =(unsigned int)wskaznik; 
        BASE_SPI->SPI_TCR = number_of_data; 
    
        clear_output(N_SYNC);	//start ramki 24 lub 32bitowej
    
        BASE_SPI->SPI_PTCR= AT91C_PDC_TXTEN;   //wlacz transmisje DMA
    wroc:
        if (!(BASE_SPI->SPI_SR & AT91C_SPI_ENDTX)) goto wroc;	//zaczekaj na wysylke wszystkich bajtow
        set_output(N_SYNC);		//koniec ramki 24 lub 32bitowej
    	        
        BASE_SPI->SPI_PTCR= AT91C_PDC_TXTDIS; 	//wylacz transmisje DMA
    	        
        if ((BASE_PIOA->PIO_ODSR & 1<<N_PEC))
            {
            set_output(LED);		//N_PEC==1 to LED ON
            }
        else
            {
            clear_output(LED);
            }
    }
    

    Może komuś się przyda ten kawałek kodu ;)
  • REKLAMA
  • #12 5302354
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    przeważnie licząc crc zaczyna się od stanu z samymi ustawionymi bitami, a kończąc neguje się stan.
  • #13 5302770
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    BoskiDialer, tego też już próbowałem ;/
    ---
    Jeszcze raz popatrzyłem do noty. Poniżej screen:

    CRC8 w C: Błąd w algorytmie transmisji SPI z wielomianem x8 + x2 + x + 1

    W sumie to chyba błędnie myślałem, że CRC jest liczone z wszystkich 3 bajtów osobno. CRC8 raczej powinno być liczone z całych 24bitów.
    Znajoma podrzuciła mi link do strony:
    http://4programmers.net/Algorytmy/Obliczanie_sum_kontrolnych_CRC-32

    Dziwne, że prędzej sam tej strony nie potrafiłem znaleźć ;/ Jest tutaj przykład obliczenia CRC zmiennej 32 bitowej, zarówno obliczenie tablicy jak i odczyt z niej. Wieczorem postaram się powalczyć w tym temacie. W sumie 8 zer i 24bity mojej ramki daje 32bity... ;)

    ps. macie może gotowe funkcje obrócenia najmłodszych 8bitów 32bitowego słowa ?
  • #14 5302828
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    To jest na pewno suma crc8 tak jak jest opisana, więc nie ma potrzeby liczenia crc32. Jeśli masz możliwość sprawdzenia czy dana suma kontrolna jest poprawna, to można zrobić taki test: funkcja pobierająca 3 bajty (pierwsze bajty do wysłania) i próbująca każdą z 256 możliwości crc w celu znalezienia tej poprawnej, funkcja by ją zwracała. Wtedy można by przebadać układ jak dokładnie jest liczona suma kontrolna poprzez przetestowanie szeregu wartości testowych (same zera, 24, każdy z jednym bitem ustawionym w innym miejscu, kilka losowych). Na podstawie tych danych można by ustalić dokładny sposób liczenia sum kontrolnych.
  • #15 5302881
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Tak jak mówisz, postaram się wysłać 24bity z każdym z bajtów CRC i może się uda w końcu. Ale to będzie rzeź ;//

    Trochę kiepsko kombinować jak jest liczona suma ;/ To musi być jakiś trik, na który nie zwracam uwagi albo zapominam o nim. Wiadomo nie od dziś, że najciemniej pod latarnią, no i najtrudniejsze są najprostrze błędy ;/
    pozdrawiam
  • #16 5303173
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    Rzeź to nie będzie, tylko proste szukanie właściwego sposobu liczenia crc. Crc jest na tyle przewidywalne, że mając poprawne crc dla samych zer oraz zmianę crc dla każdego jednego bitu można generować wszystkie poprawne sumy. Działa tutaj ten sam mechanizm, co w twojej tablicy CRC8_TABLE, przez który dla dowolnych a i b zachodzi: T[a] ^ T[b] = T[a^b] przez co można generować wszystkie sumy mając tylko wartości dla pojedynczych bitów. Ostatecznie same dane pozwalają na ustalenie generatora: w tej tablicy bit najmłodszy jest przetwarzany jako ostatni, a więc komórka T[1] zawiera generator. Inne komórki można wykorzystać do ustalenia np kierunku przesuwania bitów i innych operacji. Jak wyślesz poprawne sumy kontrolne do tych zestawów danych które napisałem (zera, 24 z jedynkami, z 10 losowych) to postaram się wyznaczyć właściwy algorytm.
  • #17 5307064
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Niestety okazało się, że przetwornik "nie łyka" ani jednego kodu crc8 ;//
    Jestem zmuszony przenieść tę dyskusję na forum uP ARM. Chociaż bardzo jestem przekonany, że kod odpowiedzialny za przesyłkę danych jest ok to zamieszczę go do sprawdzenia. Jeśli tamci Koledzy mi nie pomogą to znaczy, że jednak DAC jest felerny ;/
    Gdy zamieszczę nowy temat, wkleję go tutaj dla zainteresowanych.

    Dodano po 1 [godziny] 32 [minuty]:

    Jak pisałem, tak robię:
    Zapraszam
  • #18 5319475
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Witam ponownie ;)
    Znalazłem przyczynę błędnej transmisji z CRC8 (x8 + x2 + x + 1). Oczywiście było to tak proste, że tylko się można zapaść pod ziemię ;/
    Mianowicie nie dawałem zbytnio czasu aby przetwornik sobie policzył crc i porównał obie sumy ;/ Prędzej dawałem mu już około 1000 taktów zegara, ale dopiero 1500 taktów pozwoliło na poprawną transmisję.
    Wiem już jak policzyć crc8 "na kartce" binarnie.
    Czy moglibyście mi tę metodę napisać w C ?
    Algorytm jest następujący:

    -wielomian przez który mnożę to 1 0000 0111 (0x17) -wynika z (x8 + x2 + x + 1)
    -moja liczba 3 bajtowa to np. 0x010104,
    binarnie to wygląda tak:
    00000001 00000001 00000100

    teraz dodaję z prawej 8 zer:
    00000001 00000001 00000100 00000000

    w kolejnym kroku patrzę od lewej kiedy będzie jedynka...
    00000001 00000001 00000100 00000000

    w tym miejscu xoruję liczbę przez wielomian i znika mi najstarsza jedynka:
    00000001 00000001 00000100 00000000
    00000001 00000111
    =
    00000000 00000110 00000100 00000000

    w wyniku szukam pozycji najstarszej jedynki
    00000000 00000110 00000100 00000000

    xoruję przez wielomian:
    00000000 00000110 00000100 00000000
    00000000 00000100 000111
    =
    00000000 00000010 00011000 00000000
    00000000 00000010 00001110 00000000
    =
    00000000 00000000 00010110 00000000
    00000000 00000000 00010000 01110000
    =
    00000000 00000000 00000110 01110000
    00000000 00000000 00000100 00011100
    =
    00000000 00000000 00000010 01101100
    00000000 00000000 00000010 00001110
    =
    00000000 00000000 00000000 01100010 //wynik: 98 - suma crc8 dla 0x114
    Ostatnie xorowanie jest gdy 9. bit jest jedynką, czyli jeśli liczba jest mniejsza od 256 to koniec xorowania.
    Możecie mi pomóc z tym xorowaniem ? Ja się postaram to policzyć, aczkolwiek co kilka głów to nie jedna ;) Myślę, że ten post raz na zawsze wyjaśni sprawę CRC! ;)
  • Pomocny post
    #19 5319630
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    Twoje obliczenia na kartce można zapisać w postaci pętli. Na początku do stanu dodajesz bajt, wtedy zmienna crc jest wycinkiem z twoich obliczeń, najstarszy bit wysuwa się poza bajt, jeśli jest ustawiony, to dodajesz do stanu 0x07 (to jest 0x107, ale dodajesz(xor'em) tylko gdy wysunięty bit był ustawiony, w efekcie zostaje on wyzerowany). Działa to tak jak te twoje obliczenia na kartce, ale operujesz na wycinku wielomianu bazowego. Nie rozpisując się dokładniej kod będzie wyglądał (podobnie jak w pierwszym poście) tak:
    u8 crc8_update(u8 crc, u8 byte)
    {
    	crc ^= byte;
    	u8 i;
    	for(i=0; i<8; i++)
    		crc = (crc << 1) ^ ((crc & 0x80)?0x07:0);
    	return crc;
    }

    Obliczenia prowadzisz tak:
    u8 crc;
    crc = 0;
    crc = crc8_update(crc, pierwszy_bajt);
    crc = crc8_update(crc, drugi_bajt);
    crc = crc8_update(crc, trzeci_bajt);
    // tutaj zmienna crc zawiera poprawne crc

    Można funkcję crc8_update zoptymalizować, jeśli zauważy się, że pętla przekształca zmienną crc idzie stablicować, tutaj uzyskasz tablicę z siódmego postu, a funkcja crc_update będzie wyglądać tak:
    u8 crc8_update(u8 crc, u8 byte)
    {
    	return CRC8_TABLE[crc ^ byte];
    }
    .
    Tablica ta okazuje się być bardzo przewidywalna, jeśli ważniejsza dla Ciebie jest minimalizacja programu niż szybkość, można elementy tablicy liczyć w implementacji plasterkowej:
    u8 crc8_update(u8 crc, u8 byte)
    {
    	crc ^= byte;
    	crc ^= (crc >> 6) ^ (crc >> 7);
    	crc ^= (crc << 1) ^ (crc << 2);
    	return crc;
    }
  • Pomocny post
    #20 5319647
    master_pablo
    Poziom 16  
    Posty: 276
    Pomógł: 11
    Ocena: 30
    Implementacja algorytmu, tak jak zostal podany:
    
    #include <stdint.h>
    
    typedef union {
    	uint32_t Qword;
    	uint8_t Byte[ 4 ];
    } u_Four_Bytes;
    
    uint8_t DAC_CRC_Calc( const uint32_t Data )
    {
    	uint32_t CRC = Data;
    	uint32_t Mask = 0x80000000;
    	uint32_t Poly = 0x83800000; /* left-justified polymonial 0x107 ( x^8 + x^2 + x + 1) */
    	
    	while ( CRC >= 256 )
    	{
    		if ( CRC & Mask )
    			CRC ^= Poly; /* if masked bit equal one, then XOR data with polymonial */
    		Mask >>= 1; /* shift mask one position right */
    		Poly >>= 1; /* shift polymonial one position right */
    	}
    	
    	return ( uint8_t ) CRC;
    }
    
    int main( void )
    {
        /* ...some code...*/
        
    	u_Four_Bytes Data;
    	uint8_t CRC;
    	
    	Data.Byte[ 3 ] = 0x01;
    	Data.Byte[ 2 ] = 0x01;
    	Data.Byte[ 1 ] = 0x04;
    	Data.Byte[ 0 ] = 0; /* LSB always zeroed */
        
    	CRC = DAC_CRC_Calc( Data.Qword );
    	
    	/* sending etc. */
    	
    	return 0;
    }
    
  • #21 5319672
    alex2c
    Poziom 13  
    Posty: 133
    Ocena: 4
    Panowie!
    Bardzo dziękuję, wszystko działa jak należy!
    Oczywiście POMOGLI ;)
    pozdrawiam!
    <szczęśliwy>
  • #22 5319774
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    Co teraz zauważyłem przeglądając temat, w poście z "01 Lip 2008 13:10:28" w kodzie odwołujesz się do komórek "tablica" o indeksach od 1 do 4, podczas gdy tablica ta ma rozmiar 4 komórek, a więc sa one o indeksach od 0 do 3 więc możesz nadpisywać inną zmienną w pamięci. Jeśli nadal korzystasz z tego kodu, to popraw to.

Podsumowanie tematu

✨ Dyskusja dotyczy problemów z implementacją algorytmu CRC8 (wielomian x⁸ + x² + x + 1) w transmisji SPI do przetwornika DAC firmy Analog Devices model AD5363, sterowanego mikrokontrolerem ARM7 (AT91SAM7S128). Autor zgłaszał błędy w transmisji przy dołączaniu CRC8, mimo poprawnej transmisji bez CRC. W toku rozmów zwrócono uwagę na poprawność typów zmiennych, kolejność bajtów, sposób inicjalizacji CRC oraz interpretację algorytmu generowania tablicy CRC. Sugerowano testowanie wszystkich możliwych wartości CRC dla danych testowych w celu ustalenia właściwego algorytmu. Ostatecznie przyczyną błędów okazał się zbyt krótki czas oczekiwania na obliczenie i weryfikację CRC przez przetwornik (wymagane minimum 1500 taktów zegara). Zaproponowano i potwierdzono działanie implementacji algorytmu CRC8 w C, opartej na przesuwaniu bitów i XOR z wielomianem 0x07, zgodnie z ręcznym obliczeniem CRC na 24-bitowej ramce danych rozszerzonej o 8 zer. Przedstawiono przykładowy kod funkcji crc8_update oraz alternatywną implementację operującą na 32-bitowej zmiennej z przesuwaniem maski i wielomianu. Wskazano również na konieczność poprawnego indeksowania tablic i unikania nadpisywania pamięci. Po zastosowaniu poprawionego algorytmu i wydłużeniu czasu oczekiwania transmisja z CRC8 działa poprawnie.
Wygenerowane przez model językowy.
REKLAMA