www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Byte verbittet sich das Verbitten


Autor: Stephan R (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin!

Ich versuche, ein über die serielle SS empfangenes Byte, was zuvor am 
Bildschirm auf acht Bits individuell zusammengestzt wurde und geschickt 
wurde, wieder in 8 Bits zu zerlegen.

Dazu verwende ich folgende, handwerklich liebevoll zurechtgeschusterte 
Funktion, jedoch kommen unsinnige Werte bei heraus. Die "gleiche" 
Funktion in VB6 funktioniert. Findet jemand einen Schreib-/Denkfehler? 
Falls es eine einfachere Lösung des Problems gibt.. bin für alles offen. 
Ausser für politische Kommentare.

Schönen Gruß- Stephan

//ersteinmal die Bits definieren ++++++++++++++++++++++++++++++++++++

struct
{
unsigned bit[10];
}x;

//dann meine Funktion +++++++++++++++++++++++++++++++++++++++++++++++

void byte_to_bit (char wert1)
{
int count;
  for(count = 1; count <= 8; count++)
  {
    if(wert1 > ((2 ^ (8 - count) )- 1))
    {
      x.bit[count-1] = 1;
      wert1 = wert1 - (2 ^ (8 - count));
    }
    else
    {
      x.bit[count-1] = 0;
    }
        }

}
//anschließend die "Auswertung"  +++++++++++++++++++++++++++++++++++++++

if (x.bit[1] == 1)           //Beispielhaft: beigesetztem Bit 1
{
  fan_on;               //Beispielhaft: fan einschalten
}
else
{
  fan_off;              //Beispielhaft: fan ausschalten
}

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm. Die Funktion sieht komisch aus. Bits testet man üblicher weise mit 
dem boolschen AND-Operator.
Ansonste: Gib mal ein kompilierbares Beispiel und nicht so ein Schnipsel 
und das sogar ohne Syntax Highlighting.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan R schrieb:

>     if(wert1 > ((2 ^ (8 - count) )- 1))

^ ist in C die EXOR Operation und nicht 'hoch'

Autor: Stephan R (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin gern bereit etwas Etabliertes zu verwenden.  Meinst Du Boolscher 
AND-Operator a´la Registerbits setzen? Kenn ich. Aber wie überträgt Mann 
das auf die Aubfrage von Bits einer char- variablen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du machst das zu kompliziert.

Ein paar Anmerkungen:

  for(count = 1; count <= 8; count++)

in C wird bei 0 angefangen zu zählen! Das hat seinen guten Grund, viele 
Dinge werden einfacher, wenn man das tut.

Den Datentyp char reservierst du ausschliesslich für Texte bzw. 
Buchstaben. Für ein Byte nimmst du immer den Datentyp unsigned char bzw. 
uint8_t. Damit passieren dir dann keine seltsamen Dinge, wenn auf deinem 
Compiler ein char ein Vorzeichen hat.
void byte_to_bit (unsigned char wert1)
{
  unsigned char mask;
  unsigned char count;

  mask = 0x80;

  for( count = 0; count < 8; count++ )
  {
    if( wert1 & mask )
      x.bit[count] = 1;
    else
      x.bit[count] = 0;

    mask >>= 1;
  }
}

Autor: Oliver Ju. (skriptkiddy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätte das so gelöst.
void byte_to_bit (char wert1)
{
int count;
  for(count = 0; count < 8; count++)
  {
    x.bit[count] = (  wert & (1 << count)  )  >>  count;
  }
 }

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan R schrieb:
> Ich bin gern bereit etwas Etabliertes zu verwenden.  Meinst Du Boolscher
> AND-Operator a´la Registerbits setzen?

nicht setzen.
Ein Bit wir dmit einer ODER Operation gesetzt.
Mit einem UND kann man Bits löschen (also gezielt auf 0 setzen).
Man kann daher ein UND dazu benutzen, alle nicht interessierenden Bits 
gezielt auf 0 zu setzen. Wenn dann etwas übrig bleibt, was nicht 0 ist, 
dann war an der interessierenden Stellen eine 1 :-)

http://www.mikrocontroller.net/articles/Bitmanipulation

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Skript Kiddy schrieb:
> Ich hätte das so gelöst.
>
>
> void byte_to_bit (char wert1)
> {
> int count;
>   for(count = 0; count < 8; count++)
>   {
>     x.bit[count] = (  wert & (1 << count)  )  >>  count;
>   }
>  }
> 

Ja, Karl Heinzes Methode ist aber besser. Bei dir wird in einer Zeile 
zwei mal um nicht-konstante Anzahl geshiftet. Das ist Langsam auf den 
meisten 8 Bit Prozessoren.
Dann lieber ein if/else. Auch wenn deine Methode auf den ersten Blick 
"schöner" aussieht.

Autor: Stephan R (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> ^ ist in C die EXOR Operation und nicht 'hoch'

Tückisch! Drei Programmiersprachen aber nur ein Kopf.

Karl heinz Buchegger schrieb:
> in C wird bei 0 angefangen zu zählen!

Normal tu ich das, aber aus irgendeinem Grund, den ich nun nicht mehr 
finde, hatt ich ne Ausnahme gemacht...


Habt vielen dank, ich werd Eure Vorschläge mal austesten. Prost!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon K. schrieb:

> Ja, Karl Heinzes Methode ist aber besser. Bei dir wird in einer Zeile
> zwei mal um nicht-konstante Anzahl geshiftet. Das ist Langsam auf den
> meisten 8 Bit Prozessoren.

Muss nicht sein.
Auf einem AVR ist sie das aber. Der AVR hat keine Assembler Instruktion 
für einen Bitshift mit einer variablen Anzahl an Stellen.

Autor: Oliver Ju. (skriptkiddy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Prost.

Autor: Stephan R (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alter!
Immer wenn mal wieder ein Lämpchen aus einem anderen, (von mir 
gewünschten Grund) angeht, denk ich: yeah, ich bin geil, C ist ein 
Klacks! Dann lässt hier wieder einer einen Kommentar los, dessen 
Vokabular mir nicht mal ganz klar ist, und ich fühl mich wie ein 
Dreijähriger beim Zahnriemenwechseln!

Autor: Paul Baumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stephan R.

O.T.
Ich kann Dir zwar bei der Fehlersuche nicht helfen, weil ich kein
"C"
versteh.

Deinen Thread-Titel finde ich aber wirklich Spitze !
:-))
MfG Paul

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da geht doch noch was:
void byte_to_bit(unsigned char wert1)
{
  char count;
  for( count = 7; count >= 0; count--, wert1 >>= 1)
    x.bit[count] = wert1 & 1;
}

Autor: Stephan R (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, helfen brauchste auch nicht mehr, das Kernproblem ist gelöst.

Eine andere, weiterführende, notwendige Optimierung:

um die Bits schließlich in Aktionen umzusetzen (es wird eine Art 
Override- Steuerung: jeder durch den Controller gesteuerte Aktor muss 
per Bitwahl am Monitor, auch über den Kopf des uC heraus, beeinflusst 
werden können) gehe ich folgendermassen vor (bin nicht stolz drauf)

erst Definitionen definieren:

   #define motor1_on PORTD |= (1<<PD3);
   #define motor1_off PORTD &= ~(1<<PD3);


später alle auf einmal nacheinanderabfragen:


if (x.bit[0] == 1)
{
    fan_on
}
else
{
    fan_off
}

if (x.bit[1] == 1)
{
    fan_on
}
else
{
    fan_off
}


Das ist doch Kinderkacke. Wie tut Mann das?

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So:
void SetFanPorts(void)
{
  unsigned char Count;
  unsigned char FanStatus = 0;
  for (Count = 0; Count < 8; Count++)
  {
    FanStatus <<= 1;
    FanStatus |= x.bit[Count];
  }
  PORTD = FanStatus;
}

Autor: Stephan R (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab versucht, umzubauen aber bei mir siehts so aus: etwa 10 Bytes kommen 
rein und jedes Bit entspricht einem Schaltzustände an jeweils völlig 
unterschiedlichen Ports...! Etwas wirr...

Autor: Oliver Ju. (skriptkiddy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon K. schrieb:
> Bei dir wird in einer Zeile zwei mal um nicht-konstante Anzahl geshiftet. > Das 
ist Langsam auf den meisten 8 Bit Prozessoren.

Stimmt. Weil die Dinger soweit ich weiß keine Barrelshifter haben. Hab 
den Code deshalb auch nicht als effizient verkauft.

Gruß Skriptkiddy

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.