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 }
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.
Stephan R schrieb: > if(wert1 > ((2 ^ (8 - count) )- 1)) ^ ist in C die EXOR Operation und nicht 'hoch'
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?
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 | }
|
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 | }
|
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
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.
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!
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.
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!
@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
Da geht doch noch was:
1 | void byte_to_bit(unsigned char wert1) |
2 | {
|
3 | char count; |
4 | for( count = 7; count >= 0; count--, wert1 >>= 1) |
5 | x.bit[count] = wert1 & 1; |
6 | }
|
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?
So:
1 | void SetFanPorts(void) |
2 | {
|
3 | unsigned char Count; |
4 | unsigned char FanStatus = 0; |
5 | for (Count = 0; Count < 8; Count++) |
6 | {
|
7 | FanStatus <<= 1; |
8 | FanStatus |= x.bit[Count]; |
9 | }
|
10 | PORTD = FanStatus; |
11 | }
|
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...
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.