Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

crc

Başlatan fyper, 09 Haziran 2005, 19:47:53

fyper

dallas ın 1 wire cihazlarında kullanılan crc yi ccs te hesaplamak istiyorum.
dallas app note 27 den anladığım kadarıyla iki tür crc hesabı var
1)Kaydırmalı hesap
2) tablo

tablo yöntemi basit. 256 byte lık bir tablo var. Siz tablodan durmadan basit bir formülle veri çekerek istediğiniz CRC değerine ulaşıyorsunuz.

kaydırmalı hesap ta ise işler biraz karışık ccs te crc.c diye bir hazır c dosyası mevcut
/////////////////////// Driver to generate CRC //////////////////////////
////                                                                 ////
////  generate_8bit_crc(data, length, pattern)                       ////
////        Generates 8 bit crc from the data using the pattern.     ////
////                                                                 ////
////  generate_16bit_crc(data, length, pattern)                      ////
////        Generates 16 bit crc from the data using the pattern.    ////
////                                                                 ////
////  generate_32bit_crc(data, length, pattern)                      ////
////        Generates 32 bit crc from the data using the pattern.    ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services         ////
//// This source code may only be used by licensed users of the CCS  ////
//// C compiler.  This source code may only be distributed to other  ////
//// licensed users of the CCS C compiler.  No other use,            ////
//// reproduction or distribution is permitted without written       ////
//// permission.  Derivative programs created using this software    ////
//// in object code form are not restricted in any way.              ////
/////////////////////////////////////////////////////////////////////////

#define CRC_16    0x8005      //bit pattern (1)1000 0000 0000 0101
#define CRC_CCITT 0x1021      //bit pattern (1)0001 0000 0010 0001
#define CRC_32    0x04C11DB7  //bit pattern (1)0000 0100 1100 0001 0001 1101 1011 0111


int generate_8bit_crc(char* data, int16 length, int pattern)
{
   int   *current_data;
   int   crc_byte;
   int16 byte_counter;
   int   bit_counter;

   current_data = data;
   crc_byte = *current_data++;

   for(byte_counter=0; byte_counter < (length-1); byte_counter++)
   {
      for(bit_counter=0; bit_counter < 8; bit_counter++)
      {
         if(!bit_test(crc_byte,7))
         {
            crc_byte <<= 1;
            bit_test(*current_data, 7 - bit_counter) ?
               bit_set(crc_byte,0) : bit_clear(crc_byte,0);
            continue;
         }
         crc_byte <<= 1;
         bit_test(*current_data, 7 - bit_counter) ?
            bit_set(crc_byte,0) : bit_clear(crc_byte,0);
         crc_byte ^= pattern;
      }
      current_data++;
   }
   for(bit_counter=0; bit_counter < 8; bit_counter++)
   {
      if(!bit_test(crc_byte,7))
      {
         crc_byte <<= 1;
         continue;
      }
      crc_byte <<= 1;
      crc_byte ^= pattern;
   }
   return crc_byte;
}


int16 generate_16bit_crc(char* data, int16 length, int16 pattern)
{
   int   *current_data;
   int16 crc_Dbyte;
   int16 byte_counter;
   int   bit_counter;

   current_data = data + 2;
   crc_Dbyte =  make16(data[0], data[1]);

   for(byte_counter=0; byte_counter < (length-2); byte_counter++)
   {
      for(bit_counter=0; bit_counter < 8; bit_counter++)
      {
         if(!bit_test(crc_Dbyte,15))
         {
            crc_Dbyte <<= 1;
            bit_test(*current_data, 7 - bit_counter) ?
               bit_set(crc_Dbyte,0) : bit_clear(crc_Dbyte,0);
            continue;
         }
         crc_Dbyte <<= 1;
         bit_test(*current_data, 7 - bit_counter) ?
            bit_set(crc_Dbyte,0) : bit_clear(crc_Dbyte,0);
         crc_Dbyte ^= pattern;
      }
      current_data++;
   }

   for(bit_counter=0; bit_counter < 16; bit_counter++)
   {
      if(!bit_test(crc_Dbyte,15))
      {
         crc_Dbyte <<= 1;
         continue;
      }
      crc_Dbyte <<= 1;
      crc_Dbyte ^= pattern;
   }

   return crc_Dbyte;
}

int32 generate_32bit_crc(char* data, int16 length, int32 pattern)
{
   int   *current_data;
   int32 crc_Dbyte;
   int16 byte_counter;
   int   bit_counter;

   current_data = data + 4;
   crc_Dbyte =  make32(data[0], data[1], data[2], data[3]);

   for(byte_counter=0; byte_counter < (length-4); byte_counter++)
   {
      for(bit_counter=0; bit_counter < 8; bit_counter++)
      {
         if(!bit_test(crc_Dbyte,31))
         {
         crc_Dbyte <<= 1;
         bit_test(*current_data, 7 - bit_counter) ?
            bit_set(crc_Dbyte,0) : bit_clear(crc_Dbyte,0);
            continue;
         }
         crc_Dbyte <<= 1;
         bit_test(*current_data, 7 - bit_counter) ?
            bit_set(crc_Dbyte,0) : bit_clear(crc_Dbyte,0);
         crc_Dbyte ^= pattern;
      }
      current_data++;
   }

   for(bit_counter=0; bit_counter < 32; bit_counter++)
   {
      if(!bit_test(crc_Dbyte,31))
      {
         crc_Dbyte <<= 1;
         continue;
      }
      crc_Dbyte <<= 1;
      crc_Dbyte ^= pattern;
   }

   return crc_Dbyte;
}

bu kodu kullanmış birisi var mı? bu kod dallas cihazlarının crc hesaplamasında kullanılabilir mi? nasıl kullanılır? (data kısmını 56 biti komplemi yazmalı , pattern ne olmalı)

fyper

tablo yontemi için yaptığım programda burada
ccs 128 byte tan uzun tabloları kabul etmediği için iki parçalı tablo kullandım.

byte CONST tablo1[128]={
0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,157,
195,33,127,252,162,64,30,95,1,227,189,62,96,130,220,35,125,
159,193,66,28,254,160,225,191,93,3,128,222,60,98,190,224,2,92,
223,129,99,61,124,34,192,158,29,67,161,255,70,24,250,164,39,121,
155,197,132,218,56,102,229,187,89,7,219,133,103,57,186,228,6,
88,25,71,165,251,120,38,196,154,101,59,217,135,4,90,184,230,167,
249,27,69,198,152,122,36,248,166,68,26,153,199,37,123,58,100,134,
216,91,5,231,185};
byte CONST tablo2[128]={140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,
205,17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,175,241,19,
77,206,144,114,44,109,51,209,143,12,82,176,238,50,108,142,208,83,13,
239,177,240,174,76,18,145,207,45,115,202,148,118,40,171,245,23,73,8,86,
180,234,105,55,213,139,87,9,235,181,54,104,138,212,149,203,41,119,244,
170,72,22,233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,116,
42,200,150,21,75,169,247,182,232,10,84,215,137,107,53};


byte crckontrol(){
   byte crceski,crc,hesap;
   i=0;
   crceski=0;
   while(i<8){
      hesap=crceski^buffer[i];
      if(hesap>=128){
         crc=tablo2[hesap-128];
      }
      else{
         crc=tablo1[hesap];
      }
      crceski=crc;
      i++;
   }
   if(buffer[8]==crc) return(TRUE);
   else{return(FALSE);}
}


ds1820 nin gönderdiği "scratchpad" inin sağlamlığını buradan kontrol edebilirsiniz. gelen veri 9 byte olduğu için sabit uzunluk kontrol ediyor

fonksiyonu bir değişkene eşitlenirse gelen verinin doğru yada yanlış olup olmadığını size söyler

selvi

crc ve tablo mantigi nedir.islevi nedir.biraz aciklansa iyi olacak .ugrasmak ve program yazmak isteyen birisine daha fazla bilgi gerekiyor..yararanalicak turkce kaynak mevcut mu.
Yaşam anlamlandırıldıkça kutsaldır....

xenitis

/*************************************************************************/
/*************************************************************************/
/*** 8-bit CRC check, X8+X5+X4+1, to check the data get from DS18B20. ****/
/******* Inputs are the data need do a crc check and *********************/
/********************* length of value. **********************************/
/*************************************************************************/
/*************************************************************************/

unsigned char ow_crc_check (unsigned char* value, unsigned char length) {
	
	unsigned char i;
	unsigned char crc_org;
	
	crc_org = 0x00;

	while (length--) {
		for (i = 0x01; i != 0; i <<= 1) {
			if ((crc_org & 0x01) != 0) {// LSB of crcorg
				crc_org >>= 1;
				crc_org ^= 0x8C;
			}
			
			else {
				crc_org >>= 1;
			}

			if (((* value) & i) != 0) {
				crc_org ^= 0x8C;
			}
		}
		
		value++;
	}
	
	return crc_org;
}


buyrun benim kullandığım fonksiyon dallasın crc doğrulamasında çalışıyor bununla hem scratchpad hem de rom doğrulaması yapabilirsiniz ben microchip c18 derleyicisini kullanıyorum ufak tefek değişiklik yapmanız gerekebilir
muhtemelen sizin fonksiyon da 0x8C pattern'i ile kullanılabilir


kolay gelsin

fyper

Alıntı yapılan: "selvi"crc ve tablo mantigi nedir.islevi nedir.biraz aciklansa iyi olacak .ugrasmak ve program yazmak isteyen birisine daha fazla bilgi gerekiyor..yararanalicak turkce kaynak mevcut mu.
crc, veri doğrulaması için kullanılır. karşıdaki sistem (burada ds ailesi oluyor) yapısı gereği gönderdiği her veri grubunun sonunda birde crc byte ı hesaplayıp koyar .
sizde aynı veri yi dallasın verdiği tablo veya formül metodundan geçirip aynı crc byte ını yakalamayı denersiniz. sizin hesapladığınız crc byte ile size gelen  crc byte aynı ise tüm paket hatasız olarak alınmış demektir. yani veriniz doğrudur demektir.

gelen verilerin doğruluğu sizin için önem arz ediyorsa  veri doğrulama yöntemi(crc hesabı gibi) kullanmanız gerekir.

Macera

Crc doğrulaması için kulandığım kod aşağıdaki gibidir.
Sonuç doğruysa sıfır değer olarak geri geliyor.
Alıntı Yap#define CRC8INIT    0x00
#define CRC8POLY    0x18              //0X18 = X^8+X^5+X^4+X^0

uns8 crc8 ( uns8 *data_in, uns8 nobytsread )
{
   uns8   crc , lpcnt , bitcnt , data , fbckbit;
   crc = CRC8INIT;
   for (lpcnt = 0; lpcnt != nobytsread; lpcnt++)
   { data = data_in[lpcnt];
     bitcnt = 8;
     do
      { fbckbit = (crc ^ data) & 0x01;
        if ( fbckbit == 0x01 ) crc = crc ^ CRC8POLY;
        crc = (crc >> 1) & 0x7F;
        if ( fbckbit == 0x01 ) crc = crc | 0x80;
        data = data >> 1;
        bitcnt--;
      }
     while (bitcnt > 0);
   }
  return crc;
}

Zannedersem Xenitis arkadaşımızın kullandığı kodla epey benzeşiyor.
"Art without engineering is dreaming; engineering without art is calculating." -- Steven K. Roberts

M.s.d

Yanlış anlamış olabilirim başta belirteyim ama kontrol için hem gelen datayı hemde karşıdan gönderilen crc datasını alarak karşılaştırma yapmak gerekmiyor mu?
Bu kodda neyle karşılaştırıyor da doğruysa 0 döndürüyor. CRC8INIT   e gelen crc byte ını mı atamak gerek.