Forum: Mikrocontroller und Digitale Elektronik C Schleife um alle 8 Bits im Byte zu setzen


von verBITtert (Gast)


Lesenswert?

Hilfe, ich hab ein Brett vor'm Kopf.
Ich will alle Bits setzen.
Das Schieben im letzten Durchgang versaut's (0x7F statt 0xFF):
1
#include <stdio.h>
2
#include <stdint.h>
3
int main() {
4
  uint8_t c=0;
5
  for(uint8_t n = 0; n<8; n++){
6
    c |= 0b10000000;
7
    c >>= 1;
8
  }
9
  printf("%x",c);
10
  return 0;
11
}

7 mal Schieben und einmal manuell?
Jedes mal den Schleifenindex prüfen?
Das Schieben in der Schleifenbedingung ausführen?

von Nop (Gast)


Lesenswert?

verBITtert schrieb:

> 7 mal Schieben und einmal manuell?

Die beiden Zeilen innerhalb der Schleife vertauschen.

von HildeK (Gast)


Lesenswert?

verBITtert schrieb:
1
 for(uint8_t n = 0; n<8; n++){
2
     c >>= 1;
3
     c |= 0b10000000;
4
   }
Vielleicht habe ich dein Problem nicht ganz verstanden, aber wenn doch: 
einfach die beiden Zeilen vertauschen ...

Müssen die nacheinander gesetzt werden?

verBITtert schrieb:
> Ich will alle Bits setzen.
In dem Fall mache ich das dann so:
1
  c=0xff;

von H.Joachim S. (crazyhorse)


Lesenswert?

Was spricht gegen die einfache Variante:
c=0xff;
?

von Alex D. (daum)


Lesenswert?

Einfach schieben vorm verodern, dann sollte es gehen.

Gibt es einen bestimmten Grund warum so eine Funktion sinnvoll / 
benötigt ist?

von Kern L. (Gast)


Lesenswert?

1:
c=0xff;


2:
Bau mal zwei prints in der Schleife, jeweils nach den Setzen der 
Variable ein, dann siehst du was schiefläeuft.

Christian

Beitrag #6612578 wurde von einem Moderator gelöscht.
von Zeno (Gast)


Lesenswert?

Wenn man alle Bits eines Bytes setzen möchte, dann veranstalte ich doch 
keine Orgie mit Bitschiebereien. Da kann man den Wert doch einfach zu 
weisen.
1
unsigned char c;
2
c = 0xFF;

Hat es einen Grund warum es per Schiebeoperation gemacht werden soll.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

verBITtert schrieb:
> Hilfe, ich hab ein Brett vor'm Kopf.
> Ich will alle Bits setzen.
> Das Schieben im letzten Durchgang versaut's (0x7F statt 0xFF):
>
1
> #include <stdio.h>
2
> #include <stdint.h>
3
> int main() {
4
>   uint8_t c=0;
5
>   for(uint8_t n = 0; n<8; n++){
6
>     c |= 0b10000000;
7
>     c >>= 1;
8
>   }
9
>   printf("%x",c);
10
>   return 0;
11
> }
12
>
>
> 7 mal Schieben und einmal manuell?
> Jedes mal den Schleifenindex prüfen?
> Das Schieben in der Schleifenbedingung ausführen?

Einfach so:
1
#include <stdio.h>
2
#include <stdint.h>
3
int main() {
4
   uint8_t c = 0;
5
   for(uint8_t n = 0; n < 8; n++){
6
      c |= 1 << n;
7
   }
8
   printf("%x",c);
9
   return 0;
10
}

oder wahlweise so:
1
#include <stdio.h>
2
#include <stdint.h>
3
int main() {
4
   uint8_t c = 0;
5
   for(uint8_t n = 0; n < 8; n++){
6
      c |= 0x80 >> n;
7
   }
8
   printf("%x",c);
9
   return 0;
10
}

Mehr siehst du natürlich wenn du das printf in der Schleife aufrufst...

: Bearbeitet durch User
von Teo D. (teoderix)


Lesenswert?

Tim T. schrieb:
> oder wahlweise so:

n-- ?! ... Sorry ;)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Tim T. schrieb:
1
 c |= 1 << n;
Auf µCs ohne Barrel-Shifter (wie z.B. AVRs) ist dies eine aufwendige 
Operation. Hier ist
1
c >>= 1;
wesentlich effektiver.

von verBITtert (Gast)


Lesenswert?

Nop schrieb:
> Die beiden Zeilen innerhalb der Schleife vertauschen.

Alex D. schrieb:
> Einfach schieben vorm verodern, dann sollte es gehen.

Danke!


> c=0xff;

Da postet man schon Minimalcode, dann passt das auch nicht ;-)
Natürlich gibt es einen Grund, aber der spielt keine Rolle, denn es geht 
um die Schleife. Der Titel ist Sch.., aber ich wusste nicht, wie ich das 
präziser formulieren konnte: "Im letzen Schleifendurchgang etwas nicht 
tun?" ?

von verBITtert (Gast)


Lesenswert?

Frank M. schrieb:
> Auf µCs ohne Barrel-Shifter (wie z.B. AVRs) ist dies eine aufwendige
> Operation.

Ja, ist AVR, Schieben mit Konstante sollte schon sein.

Aber: Problem gelöst, vielen Dank an alle und guten Abend.

von MaWin (Gast)


Lesenswert?

Beim left shift ist es übersichtlicher. Oft haben Controller 
Konstantenregister für 0, 1, 0xFFF.. Dann geht s schneller auf der 
Maschine.
1
#include <stdio.h>
2
#include <stdint.h>
3
4
int main() {
5
  uint8_t c;
6
7
  for(uint8_t n = 0, c = 0; n < 8; n++){
8
    c <<= 0x01;
9
    c |= 0x01;
10
  }
11
12
  printf("%x",c);
13
  return 0;
14
}

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Frank M. schrieb:
> Tim T. schrieb:
>
1
>  c |= 1 << n;
2
>
> Auf µCs ohne Barrel-Shifter (wie z.B. AVRs) ist dies eine aufwendige
> Operation. Hier ist
>
1
> c >>= 1;
2
>
> wesentlich effektiver.

Wenn ich auf nem µC ohne Barrel-Shifter bin, benutze ich auch kein 
printf...

von verBITtert (Gast)


Lesenswert?

MaWin schrieb:
> Beim left shift ist es übersichtlicher. Oft haben Controller
> Konstantenregister für 0, 1, 0xFFF.. Dann geht s schneller auf der
> Maschine.

Sehe ich mir an, Danke.

Tim T. schrieb:
> Wenn ich auf nem µC ohne Barrel-Shifter bin, benutze ich auch kein
> printf...

Das Testen auf einem "richtigen" Rechner geht für mich schneller.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

verBITtert schrieb:
> MaWin schrieb:
>> Beim left shift ist es übersichtlicher. Oft haben Controller
>> Konstantenregister für 0, 1, 0xFFF.. Dann geht s schneller auf der
>> Maschine.
>
> Sehe ich mir an, Danke.
>
> Tim T. schrieb:
>> Wenn ich auf nem µC ohne Barrel-Shifter bin, benutze ich auch kein
>> printf...
>
> Das Testen auf einem "richtigen" Rechner geht für mich schneller.

Also wenns wirklich auf nen µC geht, ist
1
c <<= 0x01;
2
c |= 0x01;
1
LDI       R25,0x08       Load immediate (n=8)
2
LDI       R24,0x00       Load immediate (c=0)
3
4
LSL       R24            Logical shift left (c<<=1)
5
ORI       R24,0x01       Logical OR with immediate (c|=0x01)
6
SUBI      R25,0x01       Subtract immediate (n--)
7
8
BRNE      PC-0x03        Branch if not equal (Schleife bis n(R25)==0)

bzw.
1
c >>= 0x01;
2
c |= 0x80;
1
LDI       R25,0x08       Load immediate (n=8)
2
LDI       R24,0x00       Load immediate (c=0)
3
4
LSR       R24            Logical shift right (c>>=1)
5
ORI       R24,0x80       Logical OR with immediate (c|=0x80)
6
SUBI      R25,0x01       Subtract immediate (n--)
7
8
BRNE      PC-0x03        Branch if not equal (Schleife bis n(R25)==0)

natürlich besser.

: Bearbeitet durch User
von verBITtert (Gast)


Lesenswert?

@tim_taylor:

OT: welchen Disassembler oder was hast du da benutzt (mit Erklärungen)?

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

verBITtert schrieb:
> @tim_taylor:
>
> OT: welchen Disassembler oder was hast du da benutzt (mit Erklärungen)?

Kurzer Blick in den AVR Studio Disassembler und Erklärungen hab ich dazu 
geschrieben.

von verBITtert (Gast)


Lesenswert?

Danke.

von Thomaz (Gast)


Lesenswert?

Ist ganz einfach mit dieser Schleife:
1
 
2
#include <stdio.h>
3
#include <stdint.h>
4
int main() {
5
  uint8_t c=0;
6
  for(uint8_t n = 0; n<8; n++){
7
    c =  0xFF;
8
  }
9
  printf("%x",c);
10
  return 0;
11
}

von verBITtert (Gast)


Lesenswert?

Thomaz schrieb:
> Ist ganz einfach mit dieser Schleife:

Findet niemand lustig, aber wenn du Aufmerksamkeit brauchst, hier hast 
du sie.

Beitrag #6612914 wurde von einem Moderator gelöscht.
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Checker vom Neckar schrieb im Beitrag #6612914:
> xD un meine frage hat keiner beanwortet

Die Frage klang auch so einfach, dass niemand auf die Idee kam, dass Du 
diese Frage durch eigene Recherche nicht selbst innerhalb weniger 
Sekunden hättest beantworten können. Allein schon diese Antwort zu 
schreiben dauert länger. Klar, so eine Frage hier reinzusetzen ist ja 
auch einfacher als selbst danach zu suchen.

Checker vom Neckar schrieb im Beitrag #6612578:
> wird da beim shiften eigentlich mit nullen oder einsen aufgefüllt? Ist
> ja uint

uint: Mit Nullen.

Welchen Sinn hätten denn Einsen? Keinen. Da hättest Du sogar selbst ohne 
Recherche drauf kommen können.

: Bearbeitet durch Moderator
von Peter D. (peda)


Lesenswert?

Tim T. schrieb:
> Wenn ich auf nem µC ohne Barrel-Shifter bin, benutze ich auch kein
> printf...

Was hat das eine mit dem anderen zu tun?

Sobald man nicht MCs mit extrem wenig Flash (ATtiny13) benutzt, spricht 
nichts gegen printf.

von H.Joachim S. (crazyhorse)


Lesenswert?

Peter D. schrieb:
> Was hat das eine mit dem anderen zu tun?

Gehört hier für einige zum guten Programmiererstil printf nicht zu 
benutzen :-)

Ich nehm es i.a. immer. Und falls es mal knapp wird mit dem flash kann 
man da immer noch ran.

von Teo D. (teoderix)


Lesenswert?

H.Joachim S. schrieb:
> Gehört hier für einige zum guten Programmiererstil printf nicht zu
> benutzen :-)

Ich wüste nur nicht für was ich das verwenden sollte, was nich in ein 
paar Codezeilen "hingerozt" ist!?
OK, ich programmiere allerdings auch NUR µC in C und müsste wegen der 
Syntax nachschlagen.... Ob ichs aus Faulheit... KA :D

von H.Joachim S. (crazyhorse)


Lesenswert?

Teo D. schrieb:
> und müsste wegen der Syntax nachschlagen

wahrscheinlich ist das das Problem :-), ging mir auch mal so und bin da 
fast verzweifelt dran weil ich immer wieder nachschauen musste.

von Einer K. (Gast)


Lesenswert?

H.Joachim S. schrieb:
> nachschauen musste
Ist das nicht der Sinn/Zweck einer Doku?

Tipp:
Mit ein wenig Übung bleibt auch mal was hängen.....

Teo D. schrieb:
> Ich wüste nur nicht für was ich das verwenden sollte, was nich in ein
> paar Codezeilen "hingerozt" ist!?
(s)printf und seine Schwestern, die Scanner, haben schon ihre Vorteile!

OK, man kann u.U. auch mit einer Kaffeetasse einen Nagel in die Wand 
kloppen.

von Teo D. (teoderix)


Lesenswert?

H.Joachim S. schrieb:
> Teo D. schrieb:
>> und müsste wegen der Syntax nachschlagen
>
> wahrscheinlich ist das das Problem :-)

Nein, ich brauchs einfach nicht.
Ich bin da halt etwas simpler gestrickt in meinen Basteleien. Wenn 
überhaupt kommt mal ein HD44780 kompatibles Display zum Einsatz. Und das 
hängt dann, wegen genügend Vorrat, an einem PIC16F84 o. 18F25K22. Sonnst 
kommen eigentlich nur noch PIC10/12 zum Einsatz.....
Und Fixpunkt hat bisher auch IMMER ausgereicht. Ich hab mir aber auch 
noch kein Segway oä. selbst gebaut. ;)

Und für die "Anderen" Ich verwende "C" NUR auf µCs!³

von A. S. (Gast)


Lesenswert?

Teo D. schrieb:
> Nein, ich brauchs einfach nicht.

Ja, dass kenne ich. Und dann geht es doch über eine serielle zum 
debuggen raus und dann mache ich mir doch eine Zahlenumwandlung, dann 
auch in hex, ein WriteLn mit der 10 am Ende usw. ...

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
Noch kein Account? Hier anmelden.