Forum: Mikrocontroller und Digitale Elektronik Verständnisprobleme C Programmierung


von Philipp (Gast)


Lesenswert?

Hallo Leute,
ich versuche neuerdings Microcontroller zu programmieren allerdings habe 
ich damit leider so meine Schwierigkeiten.
In der Suche habe ich nichts gefunden daher hier meine Frage:
In einer Musterlösung einer Aufgabe habe ich folgenes gelesen:
PinA&(1<<PA0)
Dabei ist mir aufgefallen, dass ich scheinbar die Shift funktion nicht 
so ganz verstehe.
Ich würde diese Zeile so aufschlüsseln:
(1<<PA0)-> die 1 wird um die wertigkeit von PA0 nach links verschoben-> 
und dann wird das Ergebnis von(1<<PA0)[in meinen Augen wäre das dann 
eine 10] bitweise mit PinA verknüpft
Das gesamt Programm sieht in der Lösung dann folgendermaßen aus:


int main(){
  DDRA = 0x00;      // Eingänge
  DDRB = 0xFF;      //Ausgänge
  while(1)
  {
  if(PINA &(1<<PA0))
    {
    PORTB = 0xFF;
    }
  if(PINA &(1<<PA1))
    {
    PORTB = 0x00;
    }
  _delay_ms(300);
  }
}

Es soll folgende Funktion erfüllen:
Beim drücken des Tasters an Pa0 sollen alle LED's an Port B an gehen und 
beim drücken des Tasters an PA1 wieder ausgehen.

Ich hoffe meine Frage ist klar genug gestellt, dass auch einer außerhalb 
meines Kopfes sie verstehen kann.

Freue mich auf eure Antworten!

Viele Grüße

Philipp

von Stefan (Gast)


Lesenswert?

Ich sehe in deinem Programm keinen Fehler. Offensichtlich hast Du den 
SHift Operator schon (fast) richtig verstanden.

PA0=0, 1<<0 = 1
PA1=1, 1<<1 = 2 (dezimal) bzw 00000010 binär

Wie hast Du denn die Taster angeschlossen? Eventuell Pull-Down 
Widerstände vergessen?

von Silvan K. (silvan) Benutzerseite


Lesenswert?

Philipp schrieb:
> Ich würde diese Zeile so aufschlüsseln:
> (1<<PA0)-> die 1 wird um die wertigkeit von PA0 nach links verschoben->
> und dann wird das Ergebnis von(1<<PA0)[in meinen Augen wäre das dann
> eine 10] bitweise mit PinA verknüpft

Stimmt, wenn du davon ausgehst, dass PA0 die Wertigkeit 1 hat.

> bitweise mit PinA verknüpft

"Verknüpft" ist an dieser Stelle wohl der falsche Ausdruck. Sagen wir 
eher "verglichen".

PINA:     0000 0000   (ungedrückt)
(1<<PA0): 0000 0010
___________________
 & :      0000 0000   -> falsch


PINA:     0000 0010   (gedrückt)
(1<<PA0): 0000 0010
___________________
 & :      0000 0010   -> wahr

von prof.dr.schlau (Gast)


Lesenswert?

Silvan König schrieb:
> Philipp schrieb:

>
> PINA:     0000 0000   (ungedrückt)
> (1<<PA0): 0000 0010
> ___________________
>  & :      0000 0000   -> falsch
>
>
> PINA:     0000 0010   (gedrückt)
> (1<<PA0): 0000 0010
> ___________________
>  & :      0000 0010   -> wahr


PA0 ist mit 0 deklariert.
Also die niederwertigste Stelle des Bytes: 0000 0001

von Philipp (Gast)


Lesenswert?

Danke für die schnelle Antwort!

Ja das stimmt das Programm läuft, allerdings ist es mir nicht so ganz 
klar wiso eigentlich:

PinA hat doch die Wertigkeit 0?!
wenn also PA0=0, und dann und Verknüpft wird, dann gilt doch:
  PinA 0000
 &PA0  0001
--------------
       0000

von Karl H. (kbuchegg)


Lesenswert?

Philipp schrieb:
> Danke für die schnelle Antwort!
>
> Ja das stimmt das Programm läuft, allerdings ist es mir nicht so ganz
> klar wiso eigentlich:
>
> PinA hat doch die Wertigkeit 0?!

PINA ist der komplette EIngangsport. Alle 8 Bit

> wenn also PA0=0

Nicht 'wenn'. PA0 ist nur ein anderes Wort für 0

> und dann und Verknüpft wird, dann gilt doch:

>   PinA 0000
>  &PA0  0001

fast:  1 << PA0

> --------------
>        0000

In diesem Fall stimmt das auch. Ein 0-Bit UND ein 1-Bit ergibt getreu 
der Und-Verknüpfung

   A   B    Ergebnis A & B
 ----------------------------
   0   0  |     0
   1   0  |     0
   0   1  |     0
   1   1  |     1


nur dann eine 1, wenn an beiden Positionen eine 1 steht. In deinem 
Beispiel stehen keine 2 STück 1 Bits übereinander, daher ist das 
Ergebnis in allen Stellen eine 0.

Die Idee hinter   1<<PA0 ist es sich eine Maske zu bauen.
PA0 hat den Wert 0.
Was also ergibt 1<<PA0

nun, nimm eine binäre 1

    0b00000001

und die schiebst du jetzt 0-mal nach links ( << ... links schieben, PA0 
mal und PA0 ist ja 0)

Du erhältst   0b00000001

Nimmst du jetzt die 8 Bit, die du vom PINA einliest

    abcdefgh

und verundest die mit dieser Maske

    abcdefgh
    00000001
   ----------

dann kann an den Bitpositionen a, b, c, d, e, f, g schon mal keine 1 
rauskommen. Denn das 0 Bit in der Maske verhindert dies. D.h. die 
Ergebnisse an diesen Bitpositionen kennen wir: die sind auf jeden Fall 
0. Nur in der Spalte h kann, wegen dem 1 Bit in der Maske überhaupt ein 
1 Bit im Ergebnis entstehen, je nachdem ob das Bit h auf 0 oder auf 1 
ist

    abcdefgh
    00000001
   ----------
    0000000h

d.h. das binäre Ergebnis nach der Und-Operation hängt einzig und alleine 
von der Bitposition h, also dem Bit 0 vom PINA ab. Das Ergebnis ist 
entweder 0 (dann war auch das Bit 0) oder es ist nicht 0 (dann war auch 
das Bit h nicht 0). Und genau das testen wir

    if( PINA & ( 1 << PA0 ) )

der then-Teil von diesem if wird also immer dann genommen, wenn das Bit 
0 vom PINA auf 1 ist.

Und das wiederrum ist (scheinbar) auf deiner Platine 1, wenn der Taster 
gedrckt ist.

Beachte: Das Ergebnis der Auswertung hängt einzig und alleine von diesem 
einen Bit an der Position 0 ab. Und von nichts anderem! Dies ist 
wichtig, weil du ja 2 Taster an deinem Port hängen hast. Der 2.te Taster 
(am Pin 1) interessiert hier aber nicht. Hier ist nur der Taster am Bit 
0 interessant.

von Philipp (Gast)


Lesenswert?

Danke für diese ausführliche Beschreibung, ich glaube jetzt habe ich die 
Bitweise Verknüpfung verstanden.

Allerdings ist bei dem konkreten Fall immer noch bei mir eine Frage 
offen.

Wenn PA0=0 (Taster unbetätigt)

  PINA   0000.0000
& 1<<PA0 0000.0001
--------------------
         0000.0000

Wenn PA0=1 (Taster betätigt)

  PINA   0000.0001
& 1<<PA0 0000.0010        -> Hier müsste dann doch um eine Stelle nach
--------------------         links verschoben werden oder nicht?
         0000.0000

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

Philipp schrieb:
>   PINA   0000.0001
> & 1<<PA0 0000.0010        -> Hier müsste dann doch um eine Stelle nach
> --------------------         links verschoben werden oder nicht?
>          0000.0000

Ja.

>   PINA   0000.0001
> & 1<<PA0 0000.0001
> --------------------
>          0000.0001

von Philipp (Gast)


Lesenswert?

Philipp schrieb:
> Wenn PA0=0 (Taster unbetätigt)
>
>   PINA   0000.0000
> & 1<<PA0 0000.0001
> --------------------
>          0000.0000
>
> Wenn PA0=1 (Taster betätigt)
>
>   PINA   0000.0001
> & 1<<PA0 0000.0010        -> Hier müsste dann doch um eine Stelle nach
> --------------------         links verschoben werden oder nicht?
>          0000.0000

Das heißt aber doch das dieser Vergleich nicht funktinieren kann?!

von Karl H. (kbuchegg)


Lesenswert?

Philipp schrieb:
> Danke für diese ausführliche Beschreibung, ich glaube jetzt habe ich die
> Bitweise Verknüpfung verstanden.
>
> Allerdings ist bei dem konkreten Fall immer noch bei mir eine Frage
> offen.
>
> Wenn PA0=0 (Taster unbetätigt)
>
>   PINA   0000.0000
> & 1<<PA0 0000.0001
> --------------------
>          0000.0000
>
> Wenn PA0=1 (Taster betätigt)

Nein.

PA0 ist eine Zahlenkonstante! Das hat erst mal nichts mit einem Taster 
oder sonst irgendwas am Port zu tun. PA0 ist einfach nur ein anderes 
Wort für 0. Wenn du willst kannst du für  1<<PA0  genausogut auch 1<<0 
schreiben. Aber PA0 soll dem geneigten Leser verdeutlichen, dass hier 
vom Bit 0 die Rede ist. PA1 ... das Bit 1. PA2 ... das Bit mit der 
Nummer 2. PA6 ... das Bit 6 am Port.

von Philipp (Gast)


Lesenswert?

Das heißt also das bei der 2en if Abfrage PA1 mit 1 gelichzusetzten ist?

Dann kann die zweite if Abfrage nicht funktionieren.
da dann ja gilt

   PINA 0000.0001  -> bei Taster betätigt
1<< PA1 0000.0010
------------------
        0000.0000

von Karl H. (kbuchegg)


Lesenswert?

Philipp schrieb:
> Das heißt also das bei der 2en if Abfrage PA1 mit 1 gelichzusetzten ist?

ganz genau

> Dann kann die zweite if Abfrage nicht funktionieren.

Das weiß hier keiner, weil keiner weiß warum du PA1 geschrieben hast. 
Hier sind alle davon ausgegangen, dass du wohl 2 Taster an den Pins PA0 
und PA1 hängen haben wirst.

von Philipp (Gast)


Lesenswert?

genau richtig je PAx ein Taster

von Silvan K. (silvan) Benutzerseite


Lesenswert?

Philipp schrieb:
> Dann kann die zweite if Abfrage nicht funktionieren.
> da dann ja gilt
>
>    PINA 0000.0001  -> bei Taster betätigt
> 1<< PA1 0000.0010
> ------------------
>         0000.0000

Natürlich funktioniert sie nicht. Du hast ja in diesem beispiel den 
Taster an PA0 gedrückt.
Wenn du den Taster an PA1 drückst sieht das Register PINA so aus:

0000 0010

wenn du beide drückst:

0000 0011

von Philipp (Gast)


Lesenswert?

AHHH jetzt ist der Groschen gefallen....

Das Problem war das ich nicht (wie ihr es richtig analysiert habt)
beachtet habe das der zweite Taster ja auch ein anderes Bitmuster im
PINA "erzeugt".
D.h. dass für die zweite if abfrage dann
folgender Vergleich gemacht wird:

     PINA 0000.0010     -> der Taster an PA1 ist betätigt
&  1<<PA1 0000.0010
------------------------
          0000.0010

Super nach einem ewig langem hin und her denken dann endlich
die lang ersehnte Lösung!!

Vielen Dank an alle!

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.