Announcement

Collapse
No announcement yet.

Teile eines Array auswerten

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Teile eines Array auswerten

    Hallo

    Vielleich hat jemand von euch eine Idee oder Hinweis.


    Ich bekomme aus eine Microcontroller Datenpakete. Diese liegen zwischen 1 und 4 Bytes. Aus diesen soll ab einen Startbit (BitOffset) auf eine Länge (BitSize) Daten herausgeschnitten werden.


    Beispiel (Bytes=2, BitOffset=4,BitSize=4)
    00110010 01011011 -> 0010



    Mein bisheriger Code

    Code:
    unsigned long ByteToLong( byte const *bp, byte BitOffset, byte BitSize)
    {
    
      //**** Ermittelt Anzahl der Byte auf Basis des Startbits und der Laenge der Bitstring
      byte c=((BitOffset+BitSize)/8);
      (c) - (int)(c) > 0.0 ? (int)(c) + 1 : c;
    
    
      //**** Init Long
      unsigned long value = 0;   
    
    
      //**** Kopiert Byts in Long 
      memcpy( &value, bp, c );
    
      
      //**** Bitverschiebung
      value<<=32-(BitOffset+BitSize);
      value>>=32-BitSize;
    
      return(value);
    }

    1. Ein Array wird an *bp übergeben.
    2. Aus BitOffset und BitSize die notwendige Länge der Bytes welche verwendet wird (BUG)
    3. memcpy kopiert alles in eine ulong
    4. Bitverschiebung mit Basis 32 da es sich um eine Long handelt.


    Das ganze klappt so nicht, wer hat eine Tipp für mich wie es richtig funktioniert (oder eine Quellcode) - vielleicht denke ich zu umständlich.

    vielen Dank im Voraus.

  • #2
    Wo ist da ein Array?

    Wo ist der Unterschied zu

    http://entwickler-forum.de/showthread.php?t=68342
    Christian

    Comment


    • #3
      Danke für deine Rückmeldung:

      Wo ist der Unterschied, zu meiner damaligen Anfrage.
      (Leider muss ich mit jedem Byte geizen-da nur 32kBYTE Speicher zur Verfügung stehen)

      Diese Version ist eine stark entschlackte.
      1) Per memcpy direkt die Bytes in die long kopiert (statt byte b[]={0,8,16,24} und dann per schleife abarbeiten).
      2) Per (c) - (int)(c) > 0.0 ? (int)(c) + 1 : c; versuche ich die maximal notwendige Anzahl an Bytes festzustellen, welche zu bearbeiten sind.

      Leider weiss ich nicht wie ich die Anzahl der Elemente von *bp festellen kann - könnte ich statt 2) nehmen. Mit sizeof() klappt es nicht.


      Das Array
      Code:
      byte test01[4]={0x30,0x33,0x22,0x11};
      Serial.println(ByteToLong(test01,1,8),BIN);

      Comment


      • #4
        Bin jetzt etwas weiter gekommen - hier ein Test - allerdings für ATMEL MC:

        Code:
        /**
        * ATMEL - MC Bitextraction
        * V0.1
        */
        
        
        //byte test01[]={33};
        byte test01[4]={0x22,0x11};
        //byte test01[4]={0x33,0x22,0x11};
        //byte test01[4]={0x00,0x33,0x22,0x11};
        
        
        void setup()
        {  
          Serial.begin(9600);
          
          Serial.print(test01[0],BIN);Serial.print("-");
          Serial.print(test01[1],BIN);Serial.print("-");
          Serial.print(test01[2],BIN);Serial.print("-");
          Serial.println(test01[3],BIN);
          
          Serial.println("Ergebnis(BitOffset=3,BitSize=4): ");
          
          Serial.println(ByteToLong01(test01,3,4),BIN);
        }
        
        void loop()
        {}
        
        
        /** 
        * Version 01
        */
        unsigned long ByteToLong01( byte const *bp, byte BitOffset, byte BitSize)
        { 
          unsigned long value=0;
          byte c = ( BitOffset + BitSize ) / 8;
          c * 8 == BitOffset + BitSize ? 0 : c++;
         
          memcpy ( &value, bp, c );
          
          value >>= (BitOffset-BitSize);
          return value & ((1<<BitSize)-1);
        
        }

        Bis memcpy klappts.
        Mit der Bitverschiebung klappt es noch nicht - stehe auf der Leitung.

        Comment


        • #5
          Die Lösung (Zusammenfassung):

          USE CAse:
          Aus einen Array von 1-4 Bytes werden Abschnitte mit Startbit (BitOffset)
          und Länge (BitSize) herrausgeschnitten. Der Wert wird als uL ausgegeben.



          Die Minimalcode Variation:
          Code:
          /**
          * Wandel Array zwischen 1-4 Bytes in Long und schneidet Bit Abschnitte von diesen heraus
          * @V0.3      2011.09.20
          */
          unsigned long ByteToLong( byte const *bp, byte BitOffset, byte BitSize)
          { 
            unsigned long value=0;
            byte c = ( BitOffset + BitSize ) / 8;
            c * 8 == BitOffset + BitSize ? 0 : c++;
           
            memcpy ( &value, bp, c );
          
            value <<= ( sizeof ( value ) - c ) * 8 + BitOffset;
            value >>= 8 * sizeof ( value ) - BitSize;
          
            return value;
          }

          Danke an Christian für die bisherige Unterstützung. Falls es eine noch kleiner Methode gibt, bitte Posten.

          Comment

          Working...
          X