Avatar billede cooraz Nybegynder
20. juli 2011 - 10:36 Der er 11 kommentarer og
1 løsning

problem med crc8

jeg forsøger at lave en crc8 checksum på en serial forbindelse mellem et c# .net mf kit og et 8051 kit

jeg har ikke den store kendskab inden for crc så har derfor fundet et eksempel i C# som jeg kunne bruge:
public static class Crc8 {
    static byte[] table = new byte[256];
    // x8 + x7 + x6 + x4 + x2 + 1
    const byte poly = 0xd5;

    public static byte ComputeChecksum(params byte[] bytes ) {
        byte crc = 0;
        if ( bytes != null && bytes.Length > 0 ) {
            foreach ( byte b in bytes ) {
                crc = table[crc ^ b];
            }
        }
        return crc;
    }

    static Crc8( ) {
        for ( int i = 0; i < 256; ++i ) {
            int temp = i;
            for ( int j = 0; j < 8; ++j ) {
                if ( ( temp & 0x80 ) != 0 ) {
                    temp = ( temp << 1 ) ^ poly;
                } else {
                    temp <<= 1;
                }
            }
            table[i] = (byte)temp;
        }
    }
}


Denne komde ser ud til at virke fint, men når jeg forsøger at konvertere koden til C, er det som om der går noget galt.... jeg får ikke den samme checksum som i c# og hvis jeg prøver at printe tabellen ud på mit display til 8051 kittet kan jeg se slet ikke indeholder det samme som c# modellen

min C kode ser pt. sådan ud:

void createtable()
{
    unsigned int poly = 0xD5;
        for(i = 0; i < 256; i++)
        {
        unsigned int temp = i;
            for(j = 0; j < 8; j++)
            {
                if((temp & 0x80) != 0)
                {
                temp = (temp << 1) ^ poly;
                }
                else {
                temp <<= 1 ;
                }
            table[i] = (unsigned int)temp;
            cursor(1,1);
            printf("value %u", temp);
            for(j=0; j < 40000; j++);
            }
        }
}

unsigned char computechecksum(unsigned char hej[4]){
  unsigned char crc = 0;
  if(hej != 0)
  {
  for(i = 0; i < 4; i++)
  {
          crc = table[crc ^ hej[i]];
        cursor(2,1);
        printf("table value %X",crc);
        for(j=0; j< 20000; j++);
  }
  return crc;
  }

}

håber der er nogen der kan hjælpe mig til at se hvad der er galt...
Avatar billede arne_v Ekspert
20. juli 2011 - 19:01 #1
[div}
using System;

namespace E
{
    public static class Crc8 {
        static byte[] table = new byte[256];
        // x8 + x7 + x6 + x4 + x2 + 1
        const byte poly = 0xd5;
   
        public static byte ComputeChecksum(params byte[] bytes ) {
            byte crc = 0;
            if ( bytes != null && bytes.Length > 0 ) {
                foreach ( byte b in bytes ) {
                    crc = table[crc ^ b];
                }
            }
            return crc;
        }
   
        static Crc8( ) {
            for ( int i = 0; i < 256; ++i ) {
                int temp = i;
                for ( int j = 0; j < 8; ++j ) {
                    if ( ( temp & 0x80 ) != 0 ) {
                        temp = ( temp << 1 ) ^ poly;
                    } else {
                        temp <<= 1;
                    }
                }
                table[i] = (byte)temp;
            }
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            byte[] b = { 1, 2, 3, 4 };
            Console.WriteLine(Crc8.ComputeChecksum(b));
            Console.ReadKey();
        }
    }
}
[/div]

og


#include <stdio.h>

typedef unsigned char DOTNETBYTE;

DOTNETBYTE table[256];
DOTNETBYTE poly = 0xD5;

void createtable()
{
    int i, j;
    for(i = 0; i < 256; i++)
    {
        int temp = i;
        for(j = 0; j < 8; j++)
        {
            if((temp & 0x80) != 0)
            {
                temp = (temp << 1) ^ poly;
            }
            else
            {
                temp <<= 1 ;
            }
        }
        table[i] = (DOTNETBYTE)temp;
    }
}

DOTNETBYTE computechecksum(DOTNETBYTE *hej, int n)
{
    int i;
    DOTNETBYTE crc = 0;
    if(hej != NULL && n > 0)
    {
        for(i = 0; i < n; i++)
        {
            crc = table[crc ^ hej[i]];
        }
    }
    return crc;
}

int main()
{
    unsigned char b[] = { 1, 2, 3, 4 };
    createtable();
    printf("%d\n", computechecksum(b, sizeof(b)));
    return 0;
}


udskriver det samme hos mig.
Avatar billede arne_v Ekspert
20. juli 2011 - 19:01 #2
naa - der smutte lige en forkert bracket - om igen:


using System;

namespace E
{
    public static class Crc8 {
        static byte[] table = new byte[256];
        // x8 + x7 + x6 + x4 + x2 + 1
        const byte poly = 0xd5;
 
        public static byte ComputeChecksum(params byte[] bytes ) {
            byte crc = 0;
            if ( bytes != null && bytes.Length > 0 ) {
                foreach ( byte b in bytes ) {
                    crc = table[crc ^ b];
                }
            }
            return crc;
        }
 
        static Crc8( ) {
            for ( int i = 0; i < 256; ++i ) {
                int temp = i;
                for ( int j = 0; j < 8; ++j ) {
                    if ( ( temp & 0x80 ) != 0 ) {
                        temp = ( temp << 1 ) ^ poly;
                    } else {
                        temp <<= 1;
                    }
                }
                table[i] = (byte)temp;
            }
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            byte[] b = { 1, 2, 3, 4 };
            Console.WriteLine(Crc8.ComputeChecksum(b));
            Console.ReadKey();
        }
    }
}
Avatar billede cooraz Nybegynder
21. juli 2011 - 13:04 #3
ja det gør jeg også... begge giver værdien 117
men hvis jeg så tager din kode og smide ind i resten af min c kode og over på kittet skriver den -252 på displayet... hele koden er her:


#include <reg66x.h>                       
#include <stdio.h>
#include "dispport.h"
//#define poly = 0xD5;
unsigned int i;
//unsigned int j;
//unsigned char xdata table[256];

typedef unsigned char DOTNETBYTE;

DOTNETBYTE xdata table[256];
DOTNETBYTE poly = 0xD5;

void createtable()
{
    unsigned int j, k;
    for(i = 0; i < 256; i++)
    {
        int temp = i;
        for(j = 0; j < 8; j++)
        {
            if((temp & 0x80) != 0)
            {
                temp = (temp << 1) ^ poly;
            }
            else
            {
                temp <<= 1 ;
            }
        }
        table[i] = (DOTNETBYTE)temp;
    /*    cursor(1,1);
            printf("value %X", (DOTNETBYTE)temp);
            for(k=0; k < 45000; k++);  */
    }
}

       

DOTNETBYTE computechecksum(DOTNETBYTE *hej, int n)
{
    int i;
    DOTNETBYTE crc = 0;
    if(hej != NULL && n > 0)
    {
        for(i = 0; i < n; i++)
        {
            crc = table[crc ^ hej[i]];
        }
    }
    return crc;
}

unsigned char ReceiveSerial() {

    unsigned char c;
    /*TMOD = 0x20;    /* configure timer for the correct baud rate */
        /*TH1 = 0xe6;    /* 1200 bps for 12 MHz clock */
        TCON = 0x00;    /* Set timer to not running */

    S0CON = 0x50;    /* Set Serial IO to receive and normal mode */
    TR1 = 1;    /* start timer to Receive */   
    while( (S0CON & 0x01) == 0 ) /* wait for receive data */;
    c = S0BUF;
    return c;
}

main()
{
    init_display();
//Enable serial port with baud rate 9600
    SM0 = 0;
    SM1 = 1;
    TMOD = TMOD & 0x0F;
    TMOD = TMOD | 0x20;
    TH1 = 0xFA;
    PCON = PCON & 0xBF;
    TR1 = 1;
    createtable();
        while(1)
        {
            unsigned char gg;
            unsigned char test[] = { 1, 2, 3, 4 };
            /*unsigned char test[4];
            test[0] = ReceiveSerial();
            test[1] = ReceiveSerial();
            test[2] = ReceiveSerial();
            test[3] = ReceiveSerial(); */
            gg = computechecksum(test, sizeof(test));
            cursor(1,1);
            printf("sendt data %d",gg);

            S0BUF = gg; 
            while(!TI);
            TI = 0;
            for(i = 0; i < 30000; i++);
    }


}
Avatar billede arne_v Ekspert
21. juli 2011 - 17:43 #4
Der laeser du 4 bytes fra seriel port.

Nogen grund til at checksum ikke skulle vaere -252?

%u eller %x fremfor %d ville maaske vaere paenere.
Avatar billede cooraz Nybegynder
21. juli 2011 - 19:19 #5
nej det er udkommenteret... test indeholder kun 1,2,3,4:
unsigned char test[] = { 1, 2, 3, 4 };

så burde den jo også give de 117?
Avatar billede arne_v Ekspert
21. juli 2011 - 19:24 #6
ah - jo

hm - lidt mystisk

lad mig taenke lidt
Avatar billede cooraz Nybegynder
24. juli 2011 - 16:50 #7
hvis jeg får den til at skrive det ud den smider ind i table står der på displayet 16bit som hex... altså f.eks D500... det er kun de første 8bit der ændre sig.

kan det have noget med det at gøre?
Avatar billede arne_v Ekspert
25. juli 2011 - 02:00 #8
Kunne du proeve at erklaere temp som unsigned long fremfor int?
Avatar billede cooraz Nybegynder
25. juli 2011 - 15:19 #9
det har umiddelbart ikke gjort nogen forskel

har lavet lidt små ændringer, dig mest på serial kommunikationen men det virker stadig ikke... her er den opdaterede kode:

#include <reg66x.h>                       
#include <stdio.h>
#include "dispport.h"

typedef unsigned char DOTNETBYTE;

DOTNETBYTE xdata table[256];
DOTNETBYTE poly = 0xD5;

void createtable()
{
    unsigned int j, i,k;
    for(i = 0; i < 256; i++)
    {
        unsigned long temp = i;
        for(j = 0; j < 8; j++)
        {
            if((temp & 0x80) != 0)
            {
                temp = (temp << 1) ^ poly;
            }
            else
            {
                temp <<= 1 ;
            }
        }
        table[i] = (DOTNETBYTE)temp;
            //cursor(1,1);
            //printf("value %X", (DOTNETBYTE)temp);
            //for(k=0; k < 4500; k++); 
    }
}   

DOTNETBYTE computechecksum(DOTNETBYTE *hej, int n)
{
    int i, j;
    DOTNETBYTE crc = 0;

    if(hej != NULL && n > 0)
    {
        for(i = 0; i < n; i++)
        {
            crc = table[crc ^ hej[i]];
        }
    }

    return crc;
}

unsigned char ReceiveSerial() {

    unsigned char c;
   
    while(!RI) /* wait for receive data */;
    RI = 0;
    c = S0BUF;
    return c;
}

main()
{
    int i;
    init_display();

    S0CON = 0x4C;
    TMOD = TMOD & 0x0F;
    TMOD = TMOD | 0x20;
    TH1 = 0xFA;
    TR1 = 1;

    cld();
    createtable();
        while(1)
        {
            unsigned char gg;
            unsigned char test[] = { 7, 8, 4, 9 };
           
            /*unsigned char test[4];
            test[0] = ReceiveSerial();
            test[1] = ReceiveSerial();
            test[2] = ReceiveSerial();
            test[3] = ReceiveSerial(); */
            gg = computechecksum(test, sizeof(test));
            //cld();
            cursor(1,1);
            printf("sendt data %d",gg);

            S0BUF = gg; 
            while(!TI);
            TI = 0;
            for(i = 0; i < 30000; i++);
    }


}


hvis jeg skriver det ud som %d giver det -252 og hvis jeg skriver det ud som %x så giver det FF04... og det underlige er også at den giver den samme værdi selvom jeg har ændret tallene...

på serial kommunikationen giver det bare et "ÿ" tilbage hvilket sikkert er pga den prøver at sende de 16bit på en gang...
Avatar billede cooraz Nybegynder
26. juli 2011 - 20:19 #10
så fandt vi endelig fejlen!
det viste sig at det var fordi xdata skulle initialiseres...
AUXR = AUXR & 0xFC;

det gjorde at vi nu får den rigtige værdi!

dog er der stadig problemer hvis jeg aktivere det receive serial igen... så giver den en anden værdi
Avatar billede cooraz Nybegynder
26. juli 2011 - 20:42 #11
fejlen er fundet nu, giv et svar så får du point... selvom du ikke fandt løsning har du stadig været til stor hjælp
Avatar billede arne_v Ekspert
01. august 2011 - 03:55 #12
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester