Cyclic Redundancy Check (CRC Control)

Haberleşmede toplu veri transferinin vazgeçilmezi olan CRC oldukça faydalı ve onay görmüş bir hata tespit etme yöntemidir. Modbus CanBus ve bir çok haberleşme paketlerinde kullanılan bu yapı veride bozulma varsa bunu tespit etmemize yarıyor. Genellikle 8, 16, 32 bit olarak hesaplanan türlerinden ziyade 15 bitlik halde hesaplanan durumlarda mevcut. Bende CRC ye tasarlayacağım haberleşme paketinde ihtiyaç duydum. Büyük verilerin transferinde CRC şiddetle öneriliyormuş.

Boyut olarak 16 CRC kullandım. CRC boyutu düştükçe çakışma durumu oluşabileceğinden 16 bit’i tercih ettim.Unutmadan söylemek gerekirse CRC her zaman hatayı fark edemeyebilir. Bunu detaylı incelemek isterseniz bir örnek şu kaynakta mevcut : CRC

Ben ModBus’ın polinom değerini ele alarak fonksiyon hazırladım. Siz tasarlayacağınız sisteme göre bunu değiştirebilirsiniz. Aşağıda bir dizi verinin 16 bitlik CRC’sini hesaplayan bir C programı mevcut.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define CRC16_POLYNOMIAL        (0xA001)

uint16_t CRC16_Calc(uint8_t Data)
{
    uint16_t CRC = 0xFFFF;
            
    CRC ^= (uint16_t)Data;
    
    for (uint8_t i = 8; i > 0; i--)
    {
        if (CRC & 0x0001)
            CRC = (CRC >> 1) ^ CRC16_POLYNOMIAL;
        else
            CRC >>= 1;
    }
    return (CRC);
}

uint16_t CRC16_ArrayCalc(uint8_t buf[], uint8_t len)
{
    uint16_t crc = 0xFFFF;

    for (int pos = 0; pos < len; pos++) 
    {
        crc ^= (uint16_t)buf[pos];

        for (uint8_t i = 8; i != 0; i--) 
        {
            if ((crc & 0x0001) != 0) 
            {
                crc >>= 1;
                crc ^= CRC16_POLYNOMIAL;
            }
            else                           
                crc >>= 1;               
        }
    }
    return crc;  
}

int main(void) 
{
    uint8_t dataArray[8] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};
    uint16_t CRC;
    
    printf("CRC Calculation\n\n\r");
    printf("Polynomial = 0x%04X\n\r", (uint16_t)CRC16_POLYNOMIAL);
    printf("Data Array = ");
    for (uint8_t i = 0; i < 8; i++)
        printf("0x%02X, ", dataArray[i]);
    
    CRC = CRC16_ArrayCalc(dataArray, 8);
    
    printf("\n\rCRC1 = 0x%04X\n\r", CRC);
    
    for (;;) 
    {
        
    }
}

Basit bir örnek ile yazıyı burada tamamlayalım. Esen kalın !

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir