Forum: Compiler & IDEs bit schieben mittels schalter in C


von Anfänger (Gast)


Lesenswert?

halli hallo hab ein problem dass das bit nicht geschoben wird sonder 
immer nur binär codiert könnt ihr mir helfen??

int x;



   while (true)                      // Mainloop
   {
      for (x = 1; x < 64; x=x*2 )    //Schleife

        if (!( PIND & 0b00000100))   // wenn Taster gedrückt eins weiter
           {
            x++;
            PORTB = x;               //x am PORTB ausgeben

           }
   }


mfg

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Bits sind üblicherweise immer binär codiert, das liegt in ihrem Wesen 
;-)

Es ist kontraproduktiv, wenn du an 2 Stellen am x herumschraubst.
Soll wohl ein Lauflicht sein, das mit einer Taste weitergeschaltet wird?
Probiers mal so:
1
   x = 1;
2
   while (true) {                        // Mainloop
3
      if (!( PIND & 0b00000100)) {       // Taster gedrückt -> eins weiter
4
          x = x<<1;                      // wie x=x*2, nur etwas binärer
5
          if(x>63) x=1;
6
          while (!( PIND & 0b00000100)); // warten, solange Taster gedrückt 
7
      }
8
      PORTB = x;                         // x ausgeben
9
   }

von Florian P. (db1pf)


Lesenswert?

Hallo,

1. Bitte schreib in ein oder zwei Sätzen was das Programm im ganzen 
eigentlich machen soll. Ich werde aus deiner Beschreibung nicht ganz 
schlau. Dann kann ich dir evt auch eher bei deinem Problem helfen.

2. Der Kommentar zur for-Schleife ist überflüssig, das es sich hier um 
eine Schleife handelt sieht man.

3. Es ist ein schlechter Stil, die for-Variable (hier x) im Codebereich 
der for-Schleife zu ändern. Das kann sehr schnell zu einem seltsamen 
Verhalten führen.

4. Du wirst von der Funktion der Schaltung nicht viel sehen: Der 
Controller ist sehr schnell, jeder Durchlauf der Schleife dauert nur ein 
paar µSekunden. Auch wenn der Code korrekt sein sollte, so werden 
(scheinbar) alle LED's leuchten. Wenn du den AVR-GCC verwendest, dann 
füge ein #include <util/delay.h> ganz oben ein und du kannst dann die 
funktionen _delay_ms( zeit ) verwenden.


Grüße,
Florian

von Anfänger (Gast)


Lesenswert?

danke erstmal für die schnellen antworten

nun zur funktion will einen Lautstärkeregelung machen indem man mit 
einen taster nach oben schaltet und mit einen nach unten schalten 
sozusagen ein lauflicht was man schritt für schritt immer weiterschalten 
(zurückschaltet)



P.S.: das mit einer pause (delay) hab ich auch schon probiert aber 
leider ohne erfolg.

mfg

von Anfänger (Gast)


Lesenswert?

hab mit euren tipps ein bischen probiert und es geschafft

vielen vielen dank für eure tipps

von Mano W. (Firma: ---) (manow)


Lesenswert?

> nun zur funktion will einen Lautstärkeregelung machen indem man mit
> einen taster nach oben schaltet und mit einen nach unten schalten
> sozusagen ein lauflicht was man schritt für schritt immer weiterschalten
> (zurückschaltet)
1
      for (x = 1; x < 64; x=x*2 )    //Schleife

Versteh ich dass dann richtig, dass Du eigentlich die Zahl 64 ändern 
möchtest, denn dass ist ja die Abbruchbedingung. z.B.
1
      for (x = 1; x <= y; x=x*2 )    //Schleife

y kann man durch die Zahlen 1, 2, 4, 8, 16, 32, 64 schalten.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

@  Mano Wee (Firma ---) (manow)
x=x*2    entspricht     x=x<<1     entspricht     x<<=1
Das ist effektiv nur ein Bitshift

von Mano W. (Firma: ---) (manow)


Lesenswert?

@ Lothar Miller

> x=x*2    entspricht     x=x<<1     entspricht     x<<=1

Das ist mir schon klar...


@ von mir selber

> Versteh ich dass dann richtig

Anscheinend hab ich das nicht richtig verstanden...

von einer (Gast)


Lesenswert?

oder x=x+x
oder x+=x  (da zucken die grauen zellen)

c ist echt klasse

von Anfänger (Gast)


Lesenswert?

@ Mano Wee

die 64 ist das höchste bit was ich ausgeben will sprich es soll von 
1,2,4,8,16,32,64 schalten und die obergrenze ist 64

du mich zur zeit nur ein bischen hart mit den schleifen ect.. weil ich 
ja c erst angefangen hab !!!


für was ist eigentlich die while schleife bei Lothar miller??
        while (!( PIND & 0b00000100)); // warten, solange Taster 
gedrückt

versteh nicht für was das ist weil abgefragt wird es ja schon vorher 
vielleicht kann mir ja jemand helfen!

mfg

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

@  Anfänger (Gast)
Nachdem du ein Programm ohne Tasterentprellung und Flankenerkennung 
zuwege gebracht hast, hatte ich gedacht, es wäre doch schön, wenn der 
Zähler nicht hochzählt solange eine Taste gedrückt wird. Denn genau 
das wird hier gemacht:
1
   x = 1;
2
   while (true) {                        // Mainloop
3
      if (!( PIND & 0b00000100)) {       // Taster gedrückt -> eins weiter
4
          x = x<<1;                      // wie x=x*2, nur etwas binärer
5
          if(x>63) x=1;
6
      }
7
      PORTB = x;                         // x ausgeben
8
   }
Ist die Taste gedrückt, wird x um eins weiter geschoben. Danach wird x 
am Port B ausgegeben. Dann beginnt die Mainloop von vorne. Bis hierher 
sind ca. 1-5µs vergangen, und die Taste ist garantiert immer noch 
gedrückt. Also wird x um 1 nach links geschoben, dann wird x an Port B 
ausgegeben, dann...
Ein µC ist (für menschliche Verhältnisse) rasend schnell ;-)

Mit dieser Zeile zusätzlich
>   while (!( PIND & 0b00000100)); // warten, solange Taster gedrückt
wird gewartet, solange der Taster noch gedrückt ist.

Was das Programm damit aber immer noch nicht macht, ist, den Taster zu 
entprellen. Da werden dir etwas später noch die Augen aufgehen ;-)

Ich würde das eher so machen (immer noch ohne Tastenentprellung)
1
   int x = 1;
2
   char t, talt;
3
   while (true) {                   // Mainloop
4
      t=!(PIND & 0b00000100);       // Taster einlesen
5
      if ((t!=talt) && (talt=t)) {  // Flankenauswertung
6
          x = x<<1;                 // wie x=x*2, nur etwas binärer
7
          if(x>63) x=1;
8
      }
9
      PORTB = x;                    // x ausgeben
10
   }

von Anfänger (Gast)


Lesenswert?

mit dem entprellen hab ich mich schon eine ganze weile beschäftigt hab 
nur nicht verstanden wie der uC versteht das die flanke nach oben oder 
nach unten gerade geschalten wird.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>    if ((t!=talt) && (talt=t)) {  // Flankenauswertung
In dieser Zeile steht:
1
if(         Wenn 
2
(t!=talt)   der aktuelle Tastenpegel (t) ungleich dem vorherigen (talt) ist
3
&&          und
4
(talt=t)    das Ergebnis aus der Zuweisung von t nach talt ungleich 0 ist (also Taster betätigt)
5
) {         dann mach das Folgende...

Ich könnte das funktionsgleich auch so schreiben:
1
   int x = 1;
2
   char t, talt;
3
   while (true) {                   // Mainloop
4
      t=!(PIND & 0b00000100);       // Taster betätigt --> t = 1
5
      if ((t!=talt) && (t!=0)) {    // Flankenauswertung
6
          x = x<<1;                 // wie x=x*2, nur etwas binärer
7
          if(x>63) x=1;
8
      }
9
      talt = t;                     // Zustand von Taster merken für Flankenauswertung
10
      PORTB = x;                    // x ausgeben
11
   }

von Anfänger (Gast)


Lesenswert?

aaaaaah so jetzt hab i des verstanden is nur manchmal schwer es zu 
verstehen mit den = und ! und und und weiß zwar was sie bedeuten aber es 
ist am anfang schwierig sie richtig einzusetzen!!!
weil beim tutorial ist es wirklich kompliziert geschrieben zumindest für 
anfänger (ein kollege der einen C++ kurs vor einigen jahren gemacht hat 
hat es auch nicht verstanden)

vielen dank du bist echt spitze!!

ich hoff ich kann dich wieder mal fragen wenn ich was brauche

mfg

von Anfänger (Gast)


Lesenswert?

Was bedeutet   while(PIND&(1<<2));. ich kann damit nicht sonderlich was 
anfangen und brauche jemanden der mir das mal erklären kann. ich danke 
euch schon mal im vorraus

von Stefan E. (sternst)


Lesenswert?


von Malte (Gast)


Lesenswert?

Hallo,

wenn du eine 1, was ja auch 0b00000001 ist, um zwei Stellen nach links 
schiebt bekommst du 0b00000100. Also ist das selbe wie deine Bedingung
( PIND & 0b00000100 ).

Also man könnte auch schreiben  PIND & 4 , PIND & 0x04  oder
 PIND & (1<<PD2). Welche Version die schönste ist, ist meiner Meinung 
nach Geschmacksache.

Gruß Malte

von Bascomfehler (Gast)


Lesenswert?

Sollte der Anfänger nicht erst ein mal C lernen?

http://www.guardian-online.de/c-kurs/index_c.html

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> while(PIND&(1<<2));
1. PIND ist das Pin-Register des uC.
2. Eine 1 lässt sich auch als binär 00000001 schreiben
3. Ein <<2 ist ein bitweises Links-Schieben um 2 Stellen
   aus 1. und 2. ergibt sich: (1<<2) = 00000100
4. Ein while() tut das, was danach kommt,
   solange die Abfrage in der Klammer ungleich 0 ist.
5. Das while(...); lässt sich auch so schreiben: while(...){};
   und somit tut es einfach nichts,
   als dauernd die Bedingung auswerten und warten

PIND wird UND-verknüpft mit 00000100,
solange bis das das Ergebnis ungleich 0 ist,
bis also am PinD2 high anliegt.

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.