Forum: Mikrocontroller und Digitale Elektronik 2 Eingänge abfragen


von Achim S. (achims)


Lesenswert?

Hallo
seit 2 h Stunden lese ich mein C Buch und versteh es nicht. 
Wahrscheinlich nur ein Denkfehler.
Es sollen 2 Eingänge abgefragt werden. Nur wenn beide eingänge entweder 
H oder L haben soll geschaltet werden. Bisher habe ich dazu:
1
if (!(PINB & (1<<PINB6) && (1<<PINB7) ))
2
    return 1;
3
    else
4
    return 0;
Kann mir jemand auf die Sprünge helfen?
achim

von Peter X. (peter_x)


Lesenswert?

Nicht einzeln, sondern maskiert abfragen?

von MWS (Gast)


Lesenswert?

Ein AND & ist kein EXOR ^.

von Achim S. (achims)


Lesenswert?

ja

von Cian Xang Re (Gast)


Lesenswert?

MWS schrieb:
> Ein AND & ist kein EXOR ^.

Warum nicht?

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


Lesenswert?

1
PINB & (1<<PINB6) && (1<<PINB7)
Sowas sollte man nur dann machen, wenn man ganz ausgezeichnet die 
Prioritäten der Operatoren & und && weiß, und somit wenigstens grob 
abschätzen kann, was dabei herauskommt...

Achim Seeger schrieb:
> Es sollen 2 Eingänge abgefragt werden. Nur wenn beide eingänge entweder
> H oder L haben soll geschaltet werden.
Dann würde ich dir Vorschlagen, erst einmal jeden Einzelnen der beiden 
Eingänge einzulesen. Und anschließend in einem getrennten 
Rechenschritt auszuwerten. Also etwa so:
1
 if (PINB & (1<<PINB6)) e1 = 1;
2
 else                   e1 = 0;
3
4
 if (PINB & (1<<PINB7)) e2 = 1;
5
 else                   e2 = 0;
6
7
 if (e1==e2) Schalten();
Das kapiert jeder...

: Bearbeitet durch Moderator
von Achim S. (achims)


Lesenswert?

Hallo Lothar
wollte es in einer Zeile hinbekommen. Möchte damit einen Codierschaltzer 
auswerten. Der hat bis zu 4 Ausgänge. 1,2,4,8 zu 10 pol.
Dadurch muss ich bis zu 4 Pins gleichzeitig abfragen.
Dachte dabei an

if ( PINB5 & PINB 6 & PINB7 & PIN ? )(Vereinfacht)
achim

von Achim S. (achims)


Lesenswert?

Sorry vergesen bzw nicht richtig geschrieben. Entweder H oder L nicht 
beide

von MWS (Gast)


Lesenswert?

Cian Xang Re schrieb:
> MWS schrieb:
>> Ein AND & ist kein EXOR ^.
>
> Warum nicht?

Warum ist Grün nicht Rot?
Und doof nicht intelligent?
Fragen über Fragen...

von MWS (Gast)


Lesenswert?

Achim Seeger schrieb:
> Es sollen 2 Eingänge abgefragt werden. Nur wenn beide eingänge entweder
> H oder L haben soll geschaltet werden.

Achim Seeger schrieb:
> Sorry vergesen bzw nicht richtig geschrieben. Entweder H oder L
> nicht beide

Deine Problembeschreibung ist wirr.
Möglicherweise beschreibst Du besser, was es am Ende machen soll.

von Achim S. (achims)


Lesenswert?

Ganz einfach
Habe Taster 1 und Taster 2 am PB6 und PB7 angeschlossen. Liegen über 
einen Widerstand nach Vcc. Wenn ich beide taster betätige (nach Masse) 
soll if schalten. Dabei ist es nicht wichtig ob sie entprellt oder 
gleichzeitig gedrückt werden

von Grummel (Gast)


Lesenswert?

Achim Seeger schrieb:
> Ganz einfach
> Habe Taster 1 und Taster 2 am PB6 und PB7 angeschlossen. Liegen über
> einen Widerstand nach Vcc. Wenn ich beide taster betätige (nach Masse)
> soll if schalten. Dabei ist es nicht wichtig ob sie entprellt oder
> gleichzeitig gedrückt werden

Eine UND Verknüpfung mit NICHT ODER?

von c.m. (Gast)


Lesenswert?

hm…
1
return (PINB6 ^ PINB7)

richtig?

von MWS (Gast)


Lesenswert?

c.m. schrieb:
> hm…
> return (PINB6 ^ PINB7)

Jetzt wird's langsam albern.

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


Lesenswert?

Achim Seeger schrieb:
> wollte es in einer Zeile hinbekommen
Tja, dann wirst du wohl ein wenig mehr Nachdenken müssen. Probier mal 
aus, ob du folgen kannst:
Dein Schalter wird in geschickter so an dem Port angeschlossen, dass die 
Bitwertigkeiten aufsteigend sind. Also z.B. 1-PB4, 2-PB5, 4-PB6 und 
8-PB7. Dann liest du den Port ein, markierst das obere Nibble aus und 
schiebst den Wert um 4 Bits nach rechts. Fertig.

Wenn du beim Schaltplan nicht aufgepasst hast, musst du die Bits eben 
überall her zusammenklauben.

Und vergiss einfach diese "alles-in-einer-Zeile" Programmiererei. Das 
ergibt nur obfuscated Code, den nicht mal du selbst nach 3 Monaten noch 
kapierst.

von achim (Gast)


Lesenswert?

Hallo Lohtar
Die Hardware gibt es noch nicht. Dadurch kann ich alles noch machen.
Da bleibt  mir wohl nur die zweite Version. Ein paar gute Sachen stehen 
drin. Werde mal alles testen. Danke für deine Hilfe
achim

von MWS (Gast)


Lesenswert?

1
!((PINB & (1<<PINB6)) || (PINB & (1<<PINB7)))

von Ingo (Gast)


Lesenswert?

Ginge nicht auch das hier?
1
if ( ((PINB & PINB6)>>PINB6) == ((PINB & PINB7)>>PINB7) )
2
     return 1;
3
return 0;


Ingo

von asterix (Gast)


Lesenswert?

Ingo schrieb:
> Ginge nicht auch das hier?if ( ((PINB & PINB6)>>PINB6) == ((PINB &
> PINB7)>>PINB7) )
>      return 1;
> return 0;
>
> Ingo

das wäre eine elegane Lösung ;-)

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


Lesenswert?

Wenn man jetzt schon mit unnötig kryptischen C-Code um sich schmeißen 
muss, dann schlage ich das vor:
1
return !!(PINB & PINB6) == !!(PINB & PINB7);
Aber Achtung: bei all diesen "Einzeilern" ist ausser an der 
Übersichtlichtkeit an nichts gespart. Der erzeugte und ausgeführte 
Code ist gleich umständlich oder noch umständlicher...

: Bearbeitet durch Moderator
von Grummel (Gast)


Lesenswert?

Steht denn schon eigentlich unzweideutig fest, wann jetzt bei if 
geschaltet werden soll? Eine Wahrheitstabelle wäre doch jetzt hier mal 
angebracht.

von achim (Gast)


Lesenswert?

Wenn beide Taster gedrückt werden oder sogar 3 Taster

von Ingo (Gast)


Lesenswert?

Grummel schrieb:
> Steht denn schon eigentlich unzweideutig fest, wann jetzt bei if
> geschaltet werden soll?

Achim Seeger schrieb:
> Nur wenn beide Eingänge entweder H oder L haben soll geschaltet werden

von MWS (Gast)


Lesenswert?

Lothar Miller schrieb:
> return !!(PINB & PINB6) == !!(PINB & PINB7);

Na, Lothar, so ganz sicher nicht. Fehlt da nicht etwas? ;-)

von Marek L. (mareklew)


Lesenswert?

achim schrieb:
> Wenn beide Taster gedrückt werden oder sogar 3 Taster
1
#define TasterPort PINB
2
3
//Taster 1 an PORTB Pin 1, nach Masse schaltend
4
#define Taster1 1
5
6
//Taster 2 an PORTB Pin 2, nach Masse schaltend
7
#define Taster2 2
8
9
//Taster 1 an PORTB Pin 4, nach Masse schaltend
10
#define Taster3 4
11
12
13
// ist "True" wenn alle Schalter gleichzeitig gedrückt worden sind:
14
#define SCHALTEN (!(TasterPort & ((1<<Taster1) | (1<<Taster2) | (Taster3))))
15
16
17
...
18
19
if SCHALTEN 
20
 schere_an();

darum gings?

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:
> Grummel schrieb:
>> Steht denn schon eigentlich unzweideutig fest, wann jetzt bei if
>> geschaltet werden soll?
>
> Achim Seeger schrieb:
>> Nur wenn beide Eingänge entweder H oder L haben soll geschaltet werden


Was Ingo meint:

Ja, was denn jetzt?
Wenn beide Taster gedrückt wurden, oder wenn beide Eingänge denselben 
Zustand haben.
Das ist nicht dasselbe. Denn die beiden Eingänge haben auch dann 
denselben Zustand, wenn die beiden Taster nicht gedrückt sind.

Ehe man etwas programmiert sollte einem die zu erzielende Logik klar 
sein. Denn sonst kommt man ganz unweigerlich mit den && bzw. || 
durcheinander, mit denen man Teilausdrücke miteinander verknüpft.

Ganz abgesehen davon sollte man sich darüber im klaren sein, dass so 
etwas wie '2 Taster gleichzeitig gedrückt' immer eine etwas knifflige 
Sache ist. Denn für deinen µC sind Zeiten kleiner als Millisekunden 
überhaupt kein Problem. Für dich als Mensch ist es aber praktisch 
unmöglich, 2 Taster in exakt derselben Hunderstel-Sekunde zu drücken. 
D.h. für deinen µC wird es immer so aussehen, dass zuerst die eine Taste 
gedrückt wird und erst dann die andere Taste. Wenn also bereits ein 
einfacher Tastendruck einer der beiden Tasten jeweils eine Aktion 
auslöst, dann wirst du praktisch immer in dieser Einzelaktion landen, 
weil du es nicht schaffst, die beiden Tasten so zu drücken, dass der µC 
sie als tatsächlich gleichzeitig niedergedrückt erkennt.
Ausser natürlich du spickst dein Programm mit diversen Delays. Aber auch 
dann ist es mehr zufällig, ob das klappt oder nicht. Ganz abgesehen 
davon, dass man die Delays nicht haben will.

: Bearbeitet durch User
von Achim S. (achims)


Lesenswert?

Habe eine relativ einfache Methode gefunden. Alles in einer Zeile drin.
1
//if (!(PINB & 0b11000000 ))
2
    if (!(PINB & 0xc0 ))
3
    
4
    return 1;
5
    else
6
    return 0;
Es müüsen beide Tasten gedrückt sein damit return 1 ist. Drücke ich nur 
eine Taste, hat es keinen Einfluss.
Die beiden ersten Zeilen sind gleich, nur anders geschrieben. Damit kann 
ich ohne Problem auch andere Eingänge einbinden.
achim

von Marek L. (mareklew)


Lesenswert?

Achim Seeger schrieb:
> Habe eine relativ einfache Methode gefunden. Alles in einer Zeile

Nun sollst Du meinen letzten Post genau lesen und über den Unterschied 
zwischen den beiden Schreibweisen gleichen Ausdrucks nachdenken ;-)
Gruß,
Marek

von Michael S. (rbs_phoenix)


Lesenswert?

Wenn beide Taster immer gleichzeitig gedrückt werden müssen (z.B. um 
eine Presse runter zu lassen) kann man auch einfach beide Taster in 
Reihe schalten. Quasi eine Hardware-Und-Verschaltung ;) Die Hardware 
steht ja noch nicht.

Geht natürlich nicht, wenn auch beim Drücken einer Taste was passieren 
soll.

von Mike M. (mikeii)


Lesenswert?

Achim Seeger schrieb:
> Habe eine relativ einfache Methode gefunden. Alles in einer Zeile drin.
>
1
> //if (!(PINB & 0b11000000 ))
2
>     if (!(PINB & 0xc0 ))
3
> 
4
>     return 1;
5
>     else
6
>     return 0;
7
>
> Es müüsen beide Tasten gedrückt sein damit return 1 ist. Drücke ich nur
> eine Taste, hat es keinen Einfluss.
> Die beiden ersten Zeilen sind gleich, nur anders geschrieben. Damit kann
> ich ohne Problem auch andere Eingänge einbinden.
> achim

Damit man aber noch lesen kann, welcher Pin gemeint ist:
1
if (  !(PINB &   ((1<<PINB6)|(1<<PINB7))   )  )
2
    return 1;
3
    else
4
    return 0;

((1<<PINB6)|(1<<PINB7)) ergibt dein Bitmaske 0b11000000

if(<Aussage>)
  return 1;
else
  return 0;

kannst du immer zu return <Aussage> vereinfachen.

Also hier:
1
return !(PINB & ((1<<PINB6)|(1<<PINB7)) )

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


Lesenswert?

Achim Seeger schrieb:
> Es müüsen beide Tasten gedrückt sein damit return 1 ist.
Das ist aber ganz was Anderes als das, was dort gefordert war:
Achim Seeger schrieb:
> Nur wenn beide eingänge entweder H oder L haben soll geschaltet werden.
Also muss geschaltet werden, wenn beide H sind und wenn beide L 
sind...

Du solltest bei der Problembeschreibung ein wenig weg kommen vom 
Umgangssprachlichen und definierte Angaben machen.

MWS schrieb:
> Lothar Miller schrieb:
>> return !!(PINB & PINB6) == !!(PINB & PINB7);
> Na, Lothar, so ganz sicher nicht. Fehlt da nicht etwas? ;-)
Uuups, ich korrigiere und schreibe dazu noch alles ohne Leerzeichen:
1
  // Wenn beide gleich: 1 zurückgeben. Wenn ungleich: 0
2
  return !!(PINB&(1<<PINB6))==!!(PINB&(1<<PINB7));

von Paul Baumann (Gast)


Lesenswert?

Lothar Miller schrieb:
> Also muss geschaltet werden, wenn beide H sind und wenn beide L
> sind...

Das wird schwer, denn entweder hat eine Eingang H oder L -aber beides
zur gleichen Zeit?

Achim schrieb:
> Nur wenn beide eingänge entweder H oder L haben soll geschaltet werden.


Das ist ein XNOR.

MfG Paul

von Achim S. (achims)


Lesenswert?

Danke für eure Hilfe. Hatte es schon gesagt, mache es nur wenn beide H 
haben nicht L, ist leichter und Eindeutig
achim

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.