bit schieben mittels schalter in C

Gast #995097
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
Moderator (Firma: Titel) Persönliche Seite #995140
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
   }
#995141
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
Gast #995250
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
#995311
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.
Gast #996186
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
Moderator (Firma: Titel) Persönliche Seite #996415
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
   }
Moderator (Firma: Titel) Persönliche Seite #997084
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
   }
Gast #997745
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
Gast #1195861
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
Moderator (Firma: Titel) Persönliche Seite #1196464
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.

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