-
        

Ergebnis 1 bis 8 von 8

Thema: Bitmanipulation: Problem

  1. #1

    Bitmanipulation: Problem

    Anzeige

    Hallo an alle,
    wir haben ein paar Schwierigkeiten mit der Bitmanipulation auf einem RNmega2560. Folgendes Problem:
    Eine Funktion fragt den Entfernungswert eines SRF10 ab. Zurückgegeben werden soll aber sowohl die Entfernung als auch eine Zahl zwischen 0 - 5 (falls mit der Kommunikation etwas nicht geklappt hat). Wir haben in der Funktion also nun drei 8 Bit Variablen (lsb, msb und die Kontrollzahl). Die Rückgabe der Funktion muss nun 24 Bit groß sein, da das aber nicht geht, nehmen wir 32bit. Die Zahlen werden nun so zusammengesetzt (wir nennen die Variablen jetzt mal returnvar, lsb_srf und msb_srf)

    result = ((returnvar << 16) + (lsb_srf << 8 ) + msb_srf);

    Ist das soweit richtig?

    Wir könnten jetzt mit dem Zerlegen anfangen, aber anscheinend funktioniert nicht mal das Zusammensetzen. Wenn man folgende Werte für die drei Variablen einsetzt:

    returnvar = 0b00000101;
    lsb_srf = 0b00000111;
    msb_srf = 0b11010110;

    ist das Ergebnis, das von der Funktion zurückgegeben wird, Dezimal 2006, was Binär wiederum [0000000000000000[00000]]11111010110 ist. returnvar wurde dem also gar nicht hinzugefügt.
    Jetzt nochmal zum Zusammensetzen:

    So sollte man eigentlich returnvar wieder rausbekommen:

    returnvar = ((result & 0xff0000) >> 16);

    und so das 16 Bit Ergebnis des SRF10:

    srf10 = (result & 0xffff);

    Da hat sich nun bewiesen, dass nur das msb und lsb zusammengesetzt wurden, denn returnvar ist immer 0, egal, was man dafür einsetzt und die Entfernungsmessung funktioniert.
    Woran liegt das?
    Danke schon mal und
    Grüße
    Jan
    teamohnename


    EDIT: Anscheinend ist das Ergebnis 2006, da das Display nur 16 Bit Variablen ausgeben kann. returnvar wurde also bei der Displayausgabe einfach abgeschnitten. Außerdem musste returnvar als 32bit Variable deklariert werden. Uns ist gerade aufgefallen, dass vorher die Warnung
    warning: left shift count >= width of type
    Ausgegeben wurde. Aber warum braucht die Variable, die um 16 bit verschoben wird so viel Platz, während die 8bit Variable, die um 8 bit verschoben wird, nicht 16 bit groß sein muss?
    Geändert von teamohnename (02.01.2013 um 11:01 Uhr)

  2. #2
    Erfahrener Benutzer Begeisterter Techniker Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    41
    Beiträge
    398
    Das ist prinzipiell richtig gedacht, du must nur eines bedenken. "returnvar << 16" wird auf dem Datentyp von returnval ausgeführt. Ist returnvar ein uint16_t kommt danach einfach "0" raus. returnvar sollte 32 Bit breit sein, damit das klappt. Am besten alle 4 beteiligten Variablen vorher nach 32 Bit konvertieren.

    Am besten auch die Ergebnisse verodern und nicht + .

    Gruß
    Georg

  3. #3
    Das habe ich mir schon gedacht, warum funktioniert das Ganze aber dann mit der 8bit Variable lsb_srf? Die wird dann ja eigentlich auch aus dem Datenbereich ,,geschoben" und müsste somit mindestens 16bit groß sein.
    Danke für Deine Hilfe!

  4. #4
    Erfahrener Benutzer Begeisterter Techniker Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    41
    Beiträge
    398
    Aus dem obigen "Listing" kommt leider der Datentyp nicht raus. Prinzipiell kann das durchaus sein, das deine Variable auch ein 2 byte Integer ist und kein Byte. Wie sind deine Variable definiert?

    result = ((returnvar << 16) + (lsb_srf << 8 ) + msb_srf);


    würde ich so schreiben:

    Code:
    uint32_t result = returnvar; // convertion to 32 bit
    result = result << 16; // shift by 16 bit and build result
    result |= uint32_t(lsb_srf) << 8; // conversion to 32 bit and shift by 8 bit and build result
    result |= uint32_t(msb_srf); // conversion to 32 bit and build result
    Gruß
    Georg

    EDIT: Code

  5. #5
    Vorher waren alle als uint8_t deklariert. Es funktioniert mit lsb als uint8_t, msb als uint8_t und returnvar als uint32_t. Jetzt ist es deklariert mit lsb als uint8_t, msb als uint16_t und returnvar als uint32_t, damit funktioniert auch alles problemlos.
    Dieser Ausschnitt sieht so aus:

    Code:
    uint32_t getValue(uint8_t adr) 
    {
    	uint8_t lsb_srf = 0;
    	uint16_t msb_srf = 0;
    
    	uint32_t returnvar = 0;
    
    	[herausfinden von msb/lsb (I²C) und returnvar]
    
    	return ((returnvar << 16) | (lsb_srf << 8) | msb_srf);
    }
    und so wird es wieder ,,zerlegt":

    Code:
    gM_srf = getValue(ADDRESS);
    								
    gM_check = ((gM_srf & 0xff0000) >> 16);
    
    if(gM_check == 0)
    {
    	srf10_l = (gM_srf & 0xffff);
            [...]
    }

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    "lsb_srf << 8" funktioniert mit lsb_srf als uint8_t weil die Operation '<<' (wie auch alle anderen Operationen) in C mindestens in int (also hier 16-Bit) durchgeführt wird.

    Nachtrag:
    damit funktioniert auch alles problemlos.
    Obiges bedeutet aber auch, dass das Ergebnis von "lsb_srf << 8" dann signed ist. Probiere deinen Code mal mit einem Wert für lsb_srf bei dem das höchste Bit gesetzt ist, und bestaune dann das Ergebnis.
    Geändert von sternst (02.01.2013 um 17:49 Uhr)
    MfG
    Stefan

  7. #7
    Danke, nun hab’ ich es verstanden!

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Zitat Zitat von schorsch_76 Beitrag anzeigen
    "returnvar << 16" wird auf dem Datentyp von returnval ausgeführt. Ist returnvar ein uint16_t kommt danach einfach "0" raus.
    Nicht nur: Es kommt auch eine Compilerwarnung raus

    "Shift count exceeds with of type" o.ä. Warnungen beachten, und schon hat man 90% Fehler weniger
    Disclaimer: none. Sue me.

Ähnliche Themen

  1. problem mit bitmanipulation
    Von _maddin im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 30.07.2008, 00:37
  2. Bitmanipulation
    Von raoul4 im Forum Assembler-Programmierung
    Antworten: 6
    Letzter Beitrag: 03.04.2007, 13:54
  3. Anschlussbelgung anpassen mit Bitmanipulation
    Von waldi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 19.12.2006, 13:04
  4. Bitmanipulation in ASM
    Von teslanikola im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 11.04.2006, 13:19
  5. Bitmanipulation
    Von teslanikola im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 29.08.2005, 21:28

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •