Byte verbittet sich das Verbitten

Gast #1855108
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
}
Gast #1855118
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?
#1855119
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.
1
void byte_to_bit (unsigned char wert1)
2
{
3
  unsigned char mask;
4
  unsigned char count;
5

6
  mask = 0x80;
7

8
  for( count = 0; count < 8; count++ )
9
  {
10
    if( wert1 & mask )
11
      x.bit[count] = 1;
12
    else
13
      x.bit[count] = 0;
14

15
    mask >>= 1;
16
  }
17
}
#1855124
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
Persönliche Seite #1855127
Lesenswert?

Skript Kiddy schrieb:
> Ich hätte das so gelöst.
>
>
1
> void byte_to_bit (char wert1)
2
> {
3
> int count;
4
>   for(count = 0; count < 8; count++)
5
>   {
6
>     x.bit[count] = (  wert & (1 << count)  )  >>  count;
7
>   }
8
>  }
9
>

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.
Gast #1855132
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!
Gast #1855142
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!
Gast #1855174
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren