IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Crc 16 M_o_d_b_u_s - Kde je problém?

Aktivity
Avatar
Veil
Člen
Avatar
Veil:13.5.2021 12:17

Ahoj, snažím se spočítat crc podle jednoho vzorové příkladu v c.

#define POLY 0x8005
unsigned short crc16(unsigned short crc, unsigned char* buf, size_t len)
{
while (len--) {
crc ^= *buf++;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
}
return crc;
}
int main(void)
{
unsigned short crc;
unsigned char buf[] = { 0, 0, 0, 0, 0, 6, 0, 0x64, 0, 2, 0, 0x33 };
crc = crc16(0, buf, sizeof(buf));
printf("%04x\n", crc);
return 0;
}

Will print the example result is 20c8

Zkusil jsem: Můj kus kódu je :

using System;

namespace test
{
    class Program
    {
        const uint POLY = 0x8005;

        public static uint CRC16Modbus(uint crc,byte[] data)
        {
            for(int i = 0; i < data.Length; i++)
            {
                crc |= data[i];
                if ((crc & 0x0001) != 0)
                {
                    crc >>= 1;
                    crc ^= POLY;
                }
                else
                    crc >>= 1;


            }
            return crc;
        }
        static void Main(string[] args)
        {
            uint crc;
            byte[] buffer_bin = { 0, 0, 0, 0, 0, 6, 0, 0x64, 0, 2, 0, 0x33 };
            crc = CRC16Modbus(0, buffer_bin);
            string Text = "0x" + crc.ToString("X4");
            Console.WriteLine(Text);
        }
    }
}

Chci docílit: Ale s mým programem to hodí crc A41C a ne 20C8 jak má být. Navede mě někdo, kde dělám chybu?

 
Odpovědět
13.5.2021 12:17
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Veil
DarkCoder:13.5.2021 18:41

V prvním příkazu uvnitř for cyklu používáš bitový OR namísto bitového XOR a pak Ti úplně chybí výpočetní roura nad proměnnou crc.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
13.5.2021 18:41
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Veil
Člen
Avatar
Odpovídá na DarkCoder
Veil:13.5.2021 20:54

Díky za nasměrování, už vše funguje jak má :-)
To OR za XOR jsem si taky mohl všimnout :-)

using System;

namespace test
{
    class Program
    {
        const uint POLY = 0x8005;

        public static uint CRC16Modbus(uint crc, byte[] data)
        {
            for (int i = 0; i < data.Length; i++)
            {

                crc ^= data[i];
                for (int j = 0; j < 8; j++)
                {
                    if ((crc & 0x0001) != 0)
                    {
                        crc >>= 1;
                        crc ^= POLY;
                    }
                    else
                        crc >>= 1;
                }
            }
            return crc;
        }
        static void Main(string[] args)
        {
            uint crc;
            byte[] buffer_bin = { 0, 0, 0, 0, 0, 6, 0, 0x64, 0, 2, 0, 0x33 };
            crc = CRC16Modbus(0, buffer_bin);
            string Text = "0x" + crc.ToString("X4");
            Console.WriteLine(Text);
        }
    }
}
 
Nahoru Odpovědět
13.5.2021 20:54
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.