CRC Hesaplama

Başlatan mistek, 24 Nisan 2016, 00:13:13

mistek

Uarttan 8 byte veri ve sonunada CRC ekleyip göndereceğim.

Stm32f03 modelinde 32bit CRC olduğu yazıyor. CRC ile yeni uğraşmaya başladım terimler karışabilir kusura bakmayın.

Benim data uzunluğum 3 byte olacak maksimum. Bölerek yolluyorum.

Şimdi sorum şu. 8Bit CRC hesaplamakla 16bit veya 32Bit CRC hesaplamak bana ne sağlıyor? ST Stdlib de 8bit CRC hesaplayan fonksiyonun açıklamasında sadece stm32f072 modelinde kullanılabilir diye not düşülmüş geri kalanında 32bit olacak sanırım.

Var mı CRC uygulaması yapıpta bana basit düzeyde konuyu anlatabilecek olan? Kafam basmıyor hala... Teşekkürler.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

MrDarK

#1
Hocam selamlar;

CRC size datanın bir noktadan bir noktaya transferi esnasında doğrulama kodu olarak gönderildiğinden oldukça faydalı bir yapı. STM32 serilerinde genellikle 32 Bitlik donanımsal CRC hesaplayan çevre birimi mevcut. Eğer siz 8 bitlik CRC istiyorsanız yazılımsal yapmanız gerekir ki ben tavsiye etmiyorum işlemciye zaman kaybı getirir.

Crc çeşitlerini aşağıdaki crc hesaplayıcı linkte bulabilirsin ;
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
Picproje Eğitim Gönüllüleri ~ MrDarK

mistek

Peki Hocam 8byte veri mi 32bit CRC donanıma verdiğimde 32bit CRC sonucu alıyorum.
8bit veriyi 32bit donanımla hesaplamanın yanlış bir tarafı var mı?
Karşı taraf bu CRC nin kontrolünü yaparken nasıl yapıyor? Ben karşı tarafa polinomu göndermiyorum.
Alıcı taraftada stm32 olması mı gerekir?

Örneğim Şu:
"STM32 Projesi CRC Uygulama" string ifadesini karşı tarafa yolluyorum. ST nin örneklerinden CRC 32bit uygulamasında hesaplanan
CRC değeri: 0x00 98 5F 86

Yukarıdaki web sitesine giriş data kısmını aynı stringi yapıştırıyorum. Ürettiği sonuç 0x94 94 1A 94

Nerede hata yapıyorum acaba. Yanlış mı yorumluyorum?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

z

CRC'de aynı sonucu alabilmen için polinomun ve polinomda alınan terimler de aynı olmalı.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

MrDarK

Hocam merhaba;

Sıra ile sorularınızı cevaplamaya çalışacağım;
Soru = 8bit veri mi 32bit CRC donanıma verdiğimde 32bit CRC sonucu alıyorum. 
Cevap = Hocam string ifadeler bir char array olarak görebiliriz. Bu char arrayi ister byte byte crcye sokun istersenizde 4byte (4 karakteri) birleştirerek crc hesabına koyabilirsiniz. Eğer 8bitlik bir crc sonucu istiyorsanız yazılımsal 8 bit hesaplayan crc fonksiyonları kullanmalısınız.

Soru = Karşı taraf bu CRC nin kontrolünü yaparken nasıl yapıyor? Ben karşı tarafa polinomu göndermiyorum. Alıcı taraftada stm32 olması mı gerekir?
Cevap = Eğer karşı tarafa CRC gönderiyor iseniz karşı tarafın bunu biliyor olması gerekir. Karşı tarafta STM32 olması gerekmez. Karşı taraf sizin kullandığınız CRC'nin türünü ve polinomu biliyor olması CRC'yi hesaplayabilmesi için yeterlidir.

STM32'deki CRC hesabında kullanılan polinom değeri = 0x04C11DB7;
Picproje Eğitim Gönüllüleri ~ MrDarK

mistek

Hocam çok teşekkürler. 8bit olsun istemiyorum 32 olsada olur ben sadece nasıl olduğunu merak ettim. Byte byte CRC hesaplatıp 32bit crc yi tümüyle göndereceğim.

ve ek olarak 0x04C11DB7 değerinide karşıya gönderip buna göre hesapla dersem sanırım bir problem olmayacak.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

mistek

Aynı örneği ve String ifadesini Stm32f072 ve Stm32f030 çiplerinde ayrı ayrı çalıştırıyorum.

Stm32f030 da oluşan CRC sonucu: 73 E1 6A C1

Stm32f072 de oluşan CRC sonucu: C0 B4 22 33

Anlamadım konuyu.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

Faruk53

Hocam kolay gelsin. Ben genellikle Crc hesaplarken şu siteyi kullanıyorum.

http://www.lammertbies.nl/comm/info/crc-calculation.html

MrDarK hocamında dediği gibi 8 bitlik bir CRC hesaplatıcaksam onu yazılımsal olarak hesaplıyorum. Onu da şu şekilde yapıyorum. Örneğin gönderilecek string bilgi "PICPROJE" her bir bytın ascii karşılığını toplayıp modulis olarak 256 böldüğüm zaman bana kalan olarak verdiği sonuç gönderilecek 8 Bytın CRC karşılığı oluyor.
PICPROJE için sırasıyla Ascii değerlerinin Decimal karşılıkları toplanırsa = 80+73+67+80+82+79+74+69= 604%256 = 92(256 ile bölümden kalan).

Umarım bi faydası olur hocam kolay gelsin.

mistek

Sağolun hocam. Öncelikli olarak donanımı kullanmaya, anlamaya çalışıyorum. 8bit crc de kullanılabilir tabi ki. Ben şuan CRC nin işleyiş sistemini anlamaya çalışıyorum. Sürekli farklı sonuçlar alınca kafam karıştı.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

MrDarK

@mistek;

CRC hesaplama kodunu örnekleri ile buraya atabilir misin ? Bizde bir deneyelim bu şekilde zor oluyor.

Girdi ve çıktı byte'larını da const bir string üzerinden eklersen sevinirim.
Picproje Eğitim Gönüllüleri ~ MrDarK

mistek

#10
@MrDarK hocam stm32f0 std lib. örneklerinde
ComputedCRC = CRC_CalcBlockCRC((uint32_t *)CRCBuffer, BUFFER_SIZE);

fonksiyonunu kullanarak byte byte hesap yapıyordum sonuç yanlış çıkıyordu sürekli.

ComputedCRC=CRC_CalcCRC(CRCBuffer[0]);

fonksiyonu olduğunu gördüm bununla diziyi byte byte hesap yapınca 32bit crc sonucu üretiyor ve doğru sonuç çıkıyor.

İki işlemcide de denedim sorun yok. Kusura bakmayın. Sağolun.

Uygulamayı toparlayıp konuya ekleyeceğim örnek olarak burada da bulunsun.

Stm32f072RB ve Stm32f030R8 için derleyip yükledim. CRC Sonucu: 0x9C B8 25 5F

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "serial.h"

/** @addtogroup STM32F0xx_StdPeriph_Templates
  * @{
  */
void Delay(uint32_t nCount)
{
  while(nCount--)
  {
  }
}

extern uint8_t GelenData;

uint32_t MaskeCrc=0;
uint32_t GeciciCrc=0;
uint8_t GidecekVeri[4] = {0};

uint8_t i=0;

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define countof(a)             (uint8_t)(sizeof(a) / sizeof(*(a)))
#define BUFFER_SIZE            (countof(CRCBuffer))

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
const uint8_t CRCBuffer[] =
  {
		"STM32 Projesi CRC Uygulama"
  };
	
	GPIO_InitTypeDef  GPIO_InitStructure;

__IO uint32_t ComputedCRC = 0;
uint32_t ExpectedCRC = 0xEBF5058C; /* The expected CRC value of CRCBuffer using the
                               polynomial X32 + X26 + X23 + X22 + X16 + X12 + X11 + 
                                              X10 +X8 + X7 + X5 + X4 + X2+ X + 1 */

/* Private function prototypes -----------------------------------------------*/
static void CRC_Config(uint32_t poly);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f0xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f0xx.c file
     */

  /* Initialize LEDs available on STM32072B-EVAL board */
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  /* Configure PC10 and PC11 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);
	

	UART1_init ();
	UART2_init ();

  /* Configure the CRC peripheral to use the polynomial X32 + X26 + X23 + X22 + 
                          X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1 */
  CRC_Config(0x4C11DB7);

  /* Compute the CRC value of the 8-bit buffer: CRCBuffer */


	for(i=0; i<= BUFFER_SIZE; i++)
	{
		
		ComputedCRC = CRC_CalcCRC(CRCBuffer[i]);
	
	}

  /* Check if the computed CRC matches the expected one */
  if (ComputedCRC != ExpectedCRC)
  {
    /* Turn on LD3 */
  }
  else
  {
    /* Turn on LD1 */
    
  }
	
	GeciciCrc=ComputedCRC;
	
	GidecekVeri[0] = GeciciCrc;
	
	GidecekVeri[1] = (GeciciCrc >> 8);
	
	GidecekVeri[2] = (GeciciCrc >> 16);
	
	GidecekVeri[3] = (GeciciCrc >> 24);
	
  /* Infinite loop */
  while(1)
  {
		Delay(1921111);
		USART_SendData(USART2, 0xBB);
		Delay(1021111);
		USART_SendData(USART2, GidecekVeri[3]);
		Delay(1021111);
		USART_SendData(USART2, GidecekVeri[2]);
		Delay(1021111);
		USART_SendData(USART2, GidecekVeri[1]);
		Delay(1021111);
		USART_SendData(USART2, GidecekVeri[0]);
		
		
		
  }
}


/**
  * @brief  Compute CRC value for input message
  * @param  data: pointer at uint8_t
  * @param  size: the size of the input message
  * @retval The computed CRC value
  */
static void CRC_Config(uint32_t poly)
{
  /* Enable CRC AHB clock interface */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);

  /* DeInit CRC peripheral */
  CRC_DeInit();
  
  /* Init the INIT register */
  CRC_SetInitRegister(0);
  
  /* Select 32-bit polynomial size */
  CRC_PolynomialSizeSelect(CRC_PolSize_32);
  
  /* Set the polynomial coefficients */
  CRC_SetPolynomial(poly);
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

KABO

       Ben modbus haberlesmesi yaparken CRC hesaplamayı bu alt program ile yapıyorum.Umarım işinize yarar
     
int ModRTU_CRC(short buf[], int len)
{
  int crc = 0xFFFF;
  short pos;
  int i; 
  for (pos = 0; pos < len; pos++)
  {
     
    crc ^= ((int)buf[pos]);          // XOR byte into least sig. byte of crc 
   
    for (i = 8; i != 0; i--)
   {    // Loop over each bit
      if ((crc & 0x0001) != 0)
     {      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
   
   crc_l=crc&0xff;
   crc >>=8;
   crc_h=crc &0xff ;
   return crc;
}

BILGI PAYLASTIKCA COGALIR...

burak54

Merhaba,
Fonksiyonu kullanırken 2 Byte bilgi Return den nasıl donmesini sagladınız sadece yarısı dönüyor ? Teşekkürler.