Forum: Mikrocontroller und Digitale Elektronik Schalterabfrage / Entprellen


von newbiee (Gast)


Lesenswert?

Hallo *,

ich habe ein kleines Problem, bei dem ich denke, das ich "Betriebsblind" 
bin. Ist zwar mein erstes Projekt, aber in der Simulation funzt alles 
und in der Hardware .... :-)

Wie oben schon erwähnt, meine Schaltung funktioniert im AVR Studio, aber 
wenn ich den Code in den ATMEGA8 lade, dann ist alles irgendwie 
invertiert.

Hier einmal der Teil des Codeschnipsel, der Probleme bereitet (der 
Schalter soll Low Active sein.

unsigned short entpreller = 100;
unsigned short switch = 0;
DDRB = 0x50;
PORTB = 0xA0;

if bit_is_set (PINB, 7)
{
  if (switch!=2000)
    {             //Entprellen Schalter
      if (switch<entpreller) switch ++;
      else switch = 0;
                 //LED ON if switch is active
      if (switch == entpreller)
      {
        PORTB |= (1 << 6);
        switch = 2000;
      }
    }
}
else
{
switch = 0;
PORTB &= ~(1 << 6);  // PORTB Bit 6 auf low
}

Laut Studio, sollte der Ausgang PB6 auf high sein (LED an), wenn PB7 
gegen GND geschaltet wird.

Mein Problem in Hardware: Ich muss PB7 gegen Masse schalten, damit das 
LED aus ist.

Wie gesagt, ich sehe im Code das Problem nicht wirklich.

Danke schon mal im Vorraus.

von Thomas B. (detritus)


Lesenswert?

Einfach
1
PORTB &= ~(1 << 6);

mit
1
PORTB |= (1 << 6);

im code vertauschen?

und das hier:
1
PORTB = 0xA0;
ersetzen durch
1
PORTB = 0xA2;
Damit die LED erstmal aus ist.

Ich geh auch mal davon aus, dass du damit

>Mein Problem in Hardware: Ich muss PB7 gegen Masse schalten, damit das
>LED aus ist.

auch den PB6 meinst, also Schalter an PB7 und LED von Plus runter auf 
PB6.

Dann wird der PB6 aber nicht als Ausgang deklariert, wenn ich das 
richtig sehe:
1
DDRB = 0x50;
macht ja den DDRB.6 zu Null, d.h. als Eingang...
1
DDRB = 0x52;
So wäre das Ding ein Ausgang.

von newbiee (Gast)


Lesenswert?

Hi,

danke. Ich denke das kann gehen. Aber was ich nicht verstehe, wieso 
macht der Atmega8 das?

So wie ich den Code verstehe, sollte doch folgendes passieren:

- PB7 abfragen (Schalter LowActive). Ist PB7 gegen GND ->
- Inkrementieren eines Counter
- Bedingung erreicht -> PB6 auf High (LED an)

Das sollte jedenfalls passieren.

Warum muss ich jetzt aber PB7 auf GND ziehen um PB6 auf high zu setzen?

Danke!

von Rahul D. (rahul)


Lesenswert?

>Warum muss ich jetzt aber PB7 auf GND ziehen um PB6 auf high zu setzen?

Weil das Programm (der Algorithmus, das was sich der Ersteller 
ausgedacht hat), es so will.

Alles andere hängt mit der Hardware zusammen.
Die LED ist gegen Masse geschaltet => der Pin muß high sein, damit sie 
leuchtet.
Die Taste ist mit dem einen Kontakt am Controller-Pin und mit dem 
anderen an Masse. Da man immer zwischen zwei Spannungen umschaltet, wird 
der interne Pulup-Widerstand eingeschaltet, um dem Pin High-Pegel zu 
liefern, wenn der Taster nicht betätigt wird.

von newbiee (Gast)


Lesenswert?

Hi,

sorry! Ich war ein wenig durch den Wind!

Also erstellt habe ich dieses Prog.

Das Prog. sollte das machen was ich eben mit einem Fragezeichen versehen 
hatte.

Soll: PB7 auf Masse, PB6 active (LED an)
Ist:  PB7 auf Masse, PB6 AUS !

Das ist mein Problem.

Und das LED sollte richtig angeschlossen sein (jedenfalls leuchtet an 
5V)

Sorry nochmals für die Verwirrung.

von Rahul D. (rahul)


Lesenswert?

1
      if (switch<entpreller) switch ++;
2
      else switch = 0;
3
                 //LED ON if switch is active
4
      if (switch == entpreller)

Das beisst sich!
wenn switch grüsser oder gleich entpreller ist, wird switch = 0 gesetzt.
Dadurch kann die folgende Abfrage nie wahr werden.

Besser:
1
      if (switch<entpreller) switch ++;
2
      else 
3
           {
4
            switch = 0;
5
            PORTB |= (1 << 6);
6
           }

weiterhin wird sich vermutlich short nicht mit 2000 vereinbaren lassen 
(ausser short ist 16Bit breit).

Mal dir mal am besten ein Ablaufdiagramm auf.

von Johannes M. (johnny-m)


Lesenswert?

Das müsste beim Compilieren ne ganze Stange Fehlermeldungen liefern. 
"switch" ist immerhin ein Schlüsselwort, was man in Rahuls formatiertem 
Code sehr schön sehen kann...

von newbiee (Gast)


Lesenswert?

Hi,

zu Johannes: Du hast recht. In meinem Code heisst die Variable auch 
etwas anders. Nicht "Switch". Steht noch etwas davor. -> Keine Stange 
von Fehlermeldungen. Allerdings mit der 2000 hast recht. Da hat mir der 
Compiler keinen Fehler angezeigt. Komisch :-(

@rahul:

Das ist mein Entprellen des Taster.

Ich lasse einen Zähler laufen, der bei gesetzten PB7 zählt. Für den Fall 
PB7 öffnet wird der Zähler auf 0 gesetzt. Ist der Kontakt richtig zu, 
dann zählt der Zähler hoch und setzt nach den erreichen von der 
Variablen "entpreller" diese auf einen Wert der nie erreicht werden 
kann. -> geht nicht mehr in die Schleife -> Schalterzustand ist 
Eingeschwungen
Dann kann der Port gesetzt werden.

Über allem steht die Abfrage
if bit_is_set (PINB, 7)
Wird der Schalter geöffnet, dann wird alles auf 0 gesetzt. Und alles 
kann beim Schalter schließen von vorne beginnen.

Trotdem verstehe ich im Moment meine Inversion nicht?

Werde jetzt mal die 2000 fixen, bzw. den Vairiablentyp ändern.

von Johannes M. (johnny-m)


Lesenswert?

Rahul Der trollige wrote:
> weiterhin wird sich vermutlich short nicht mit 2000 vereinbaren lassen
> (ausser short ist 16Bit breit).
Wieso? short ist lt. C-Standard immer mindestens 16 Bit breit, sollte 
also mit 2000 kein Problem geben...

von newbiee (Gast)


Lesenswert?

Hi,

hat jemand eine Idee, warum die Hardware inveriert ist? Der Code sollte 
stimmen, oder?

Code: PB7 auf Low -> PB6 auf high

Hardware: PB7 ungeschaltet, PB6 auf high

Danke, nochmals

Gruß

von Thomas B. (detritus)


Lesenswert?

>die Hardware invertiert

Deine LED hängt über nen Widerstand an 5V und mit dem anderen Bein am 
Controller, hast du zumindest oben so geschrieben. Das heisst, damit die 
LED leuchtet, muss der Strom durch die LED in den Controller Richtung 
Masse fliessen. Und das erreichst du wie in meinem Post von heute 
morgen, dass du den Portpin auf 0 setzt, wenn das Teil leuchten soll und 
auf 1, wenn es aus sein soll.

von newbiee (Gast)


Lesenswert?

Hallo Thomas,

das habe ich ja auch zuerst Gedacht, das ich es "falsch" angeschlossen 
habe.

Meine Hardware ist aber an GND.

D.h. GND-LED-Vorwiderstand-Ausgang Mega8

Und dann habe ich das von mir beschriebene Verhalten! Nicht an 5V. Dann 
würde ich es ja auch verstehen.

Und nun ? Idee?

Kleine Frage: Ist denn der Code so von mir geschrieben, das der 
Controller den PB6 auf 5V schaltet, wenn PB7 gegen Masse liegt ?

Ich sag mal ja, aber im Moment habe so meine Zweifel an allem was ich 
bisher gemacht habe. Wenn der Code richtig sein sollte, dann kann es nur 
an der Hardware liegen. Aber selbst dann wüsste ich nicht wo das sein 
sollte, da z.Zt. nur der Controller und das LED auf dem Steckerboard 
sind.

von Thomas B. (detritus)


Lesenswert?

Ahso... dann mach mal aus
1
if bit_is_set (PINB, 7)

das hier:
1
if bit_is_clear (PINB, 7)


Wenn du den Taster drückst, liegt der PinB7 auf Masse, das Bit ist also 
gelöscht und nicht gesetzt.

von newbiee (Gast)


Lesenswert?

Danke!

Das könnte es gewesen sein. Das auf GND ziehen habe ich erst später 
gemacht und nicht mehr an den Code gedacht.

Das sollte es gewesen sein.

Gruß

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.