Skocz do zawartości

[C] Obliczanie CRC w HTU21D.


dawid75_75

Pomocna odpowiedź

Szanowni Forumowicze,
Zagłębiając się w temat znalazłem funkcję liczącą CRC w bibliotece na arduino do tego czujnika. Dowiedziałem się też, że jest biblioteka o nazwie crc16.h w katalogu util. Pierwotnie chciałem z niej korzystać, ale wymaga argumentów 8-bitowych, a z tego, co zrozumiałem z datasheet'a czujnika i patrząc na funkcję z biblioteki arduino muszę zlepić ze sobą dane pomiarowe z czujnika, czyli otrzymam 16-bitową liczbę. Postać funckji z crc16.h:

static __inline__ uint8_t  _crc_ibutton_update (uint8_t __crc, uint8_t __data)

Funkcja z biblioteki arduino:

#define SHIFTED_DIVISOR 0x988000 //This is the 0x0131 polynomial shifted to farthest left of three bytes
uint8_t check_crc(uint16_t message_from_sensor, uint8_t check_value_from_sensor)
{
//Test cases from datasheet:
//message = 0xDC, checkvalue is 0x79
//message = 0x683A, checkvalue is 0x7C
//message = 0x4E85, checkvalue is 0x6B

uint32_t remainder = (uint32_t)message_from_sensor << 8; //Pad with 8 bits because we have to add in the check value
remainder |= check_value_from_sensor; //Add on the check value

uint32_t divsor = (uint32_t)SHIFTED_DIVISOR;

for (int i = 0 ; i < 16 ; i++) //Operate on only 16 positions of max 24. The remaining 8 are our remainder and should be zero when we're done.
{

	if( remainder & (uint32_t)1<<(23 - i) ) //Check if there is a one in the left position
	remainder ^= divsor;

	divsor >>= 1; //Rotate the divsor max 16 times so that we have 8 bits left of a remainder
}

return (uint8_t)remainder;
}

Użycie w programie:

[...]
               uint8_t byte0 = twiMaster.readData[0];
	uint8_t byte1 = twiMaster.readData[1];
	uint8_t byte2 = twiMaster.readData[2];

	printf("Kontrola strumienia.\n\n\r");
	printf("Wartosci odebranych bajtow: ");
	printf(" %d %d\n\r", byte0, byte1);
	itoa(byte2, binBuffer, 2);
	printf("Checksum: %s\n\r", binBuffer);
	uint16_t data = 0;
	data = (byte0 << 8) | byte1;
	uint8_t crc = check_crc(data, byte2);
	printf("CRC: %d\n\r", crc);[...]

Starałem się analizować to co piszą w DS do czujnika jednocześnie czytając kod funkcji. I mam problem z tym, że nie do końca rozumiem początek:

calculation

To compute an n-bit binary CRC, line the bits representing the input in a row, and position the (n+1)-bit pattern

representing the CRC's divisor (called a "polynomial") underneath the left-hand end of the row.

This is first padded with zeroes corresponding to the bit length n of the CRC.

If the input bit above the leftmost divisor bit is 0, do nothing. If the input bit above the

Podejrzewam, że tu ma uzasadnienie to:

#define SHIFTED_DIVISOR 0x988000 //This is the 0x0131 polynomial shifted to farthest left of three bytes

W bibliotece arduino jest odnośnik do wiki: http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks

ale dalej nie wiem skąd SHIFTED_DIVISOR. Widzę, że 0x988 to przesunięcie w prawo o trzy 0x0131 z dopisanymi 12ma zerami z prawej, ale skąd u diabła akurat takie wartości? Ma to związek z wielomianem X^8 + X^5 + X^4 + 1, który jest podany w DS czujnika?

Proszę uprzejmie o wskazówki i pozdrawiam,
Dawid.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.