Forum: Mikrocontroller und Digitale Elektronik Drehschalter auslesen


von Mark (Gast)


Lesenswert?

Hallo zusammen,
ich habe ein kleines Problem und sehe den Fehler dabei nicht.
ich habe einen Hex-Drehschalter mit 4 Ausgängen an einen Attiny2313 
angeschlsosen(Bitwertigkeit 1 an PD2,...,Bitwertigkeit 8 an PD5) und 
möchte je nach Schalterstellung einen anderen Programmteil bearbeiten. 
Allerdings funktioniert das Auslesen im Controller nicht richtig. Es 
werden alle Pins als high-Zustand obwohl KEIN Pull-up aktiviert ist.

Hier mein Quellcode:

int main(void)
{
   uint8_t temp;
   DDRD &= ~((1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5));
   PORTD &= ~((1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5));
   for(;;)
   {
     temp = PIND;

     if(temp && PD2)
     {
     mache dein Zeug
     }
     ...usw
   }

}

von Timmo H. (masterfx)


Lesenswert?

if(temp & (1<<PD2))
...

ich würde aber das ganze auf ein Nibble schieben und den rest rausunden 
um dann mit 0x00-0x0F zu arbeiten.

von Peter D. (peda)


Lesenswert?

Mark schrieb:
> Es
> werden alle Pins als high-Zustand obwohl KEIN Pull-up aktiviert ist.

Das ist eben so, floatende Pins können beliebige Zustände haben, z.B. 
auch high.


Peter

von Mark (Gast)


Lesenswert?

Also kann ich ohne externen Pull-Up bzw. Pull-Down das Problem nicht 
lösen?

von Peter D. (peda)


Lesenswert?

Siehs mal so:
Es wäre schon äußerst merkwürdig, daß man extra interne Pullups einbaut, 
wenn sie niemand benötigen würde.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Mark schrieb:
> Also kann ich ohne externen Pull-Up bzw. Pull-Down das Problem nicht
> lösen?

Kommt drauf an, wie du deinen Drehschalter verkabelt hast.
Wenn der einfach einen Pin von den 4-en nach Masse durchschaltet und die 
internen Pullup aktiviert sind, dann geht das wunderbar.

Du baust deinen Schalter so ein, wie du 4 Taster einbauen würdest. Nur 
dass die alle eben bereits im Drehsschalter selber auf einen gemeinsamen 
Pin zusammengeführt sind, der dann an Masse verkabelt wird.


(Und geh von dem unbedingten "Ich will die eine Auswahl unbedingt als 1 
Bit sehen" weg. Das ist eine 'Anforderung' die kein Mensch braucht, die 
sich in Software ganz leicht auch anders rum berücksichtigen lässt und 
die die Dinge nur kompliziert macht. Alle sind 1, nur der eine 
ausgewählte ist 0. So wie man das bei Tastern auch macht.)

von Uwe (de0508)


Lesenswert?

Hallo Mark,

hier ist noch eine weiter Hilfe,
mit
1
PORTD &= ~((1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5));

schaltet man die internen Pullup aus.

Demzufolge mit
1
PORTD |= (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5);

ein.

Das würde ich auch noch auf negative Logic (low aktiv) ändern:
1
   for(;;)
2
   {
3
     temp = ~PIND;
4
5
     if( temp & (1<<PD2) )
6
     {
7
     mache dein Zeug
8
     }
9
     ...usw
10
   }

Super jetzt geht es.

von Bernhard S. (b_spitzer)


Lesenswert?

Der Fehler liegt hier:
1
if(temp && PD2)
Der 8-Bit Wert temp wird mit dem 1-Bit-Wert PD2 verundet. Dabei kommt 
seltsames raus. In C ist nämlich bei einer logischen Verknüpfung alles 
TRUE, was nicht 0 ist. Also wird bei irgend einem gesetzten Pin an Port 
D der temp-Teil immer als TRUE interpretiert.

tschuessle
Bernhard

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.