Forum: Mikrocontroller und Digitale Elektronik Anfängerfehler mit LED an und ausschalten


von C. B. (dapcfreek)


Lesenswert?

Hallo,

also, zu aller erst: Ich bin ganz neu bei dem Programmieren mit 
Microcontrollern, also bitte nicht schimpfen, wenn das eine wirklich 
doofer Frage ist. Ich habe auch schon online gesuch, aber leider nichts 
gefunden.

Also, ich versuche "bloß" eine LED mit einem Taster anzuschalten und 
dann mit bei einem erneuten Tasterndruck wieder auszuschalten.
Wenn ich mein Programm starte, dann kann ich mit dem Taster die LED 
einschaltne, aber sobal ich den Taster wieder los lasse, geht die LED 
auch wieder aus. Was mache ich falsch?

Programm:
1
#include <avr/io.h>
2
3
#define  Taster1 3
4
#define  Taster2 4
5
6
void setze_LED2 ()
7
{
8
  PORTD |= (1<<PD6);
9
}
10
void loesche_LED2 ()
11
{
12
  PORTD &= ~(1<<PD6);
13
}
14
15
int main(void)
16
{
17
  //Ports richtig einstellen
18
  DDRD = 0b11100000;
19
  
20
  
21
  
22
  
23
    while(1)
24
    {
25
    if (PIND & (1<<Taster1))
26
    {
27
           setze_LED2();
28
    }
29
    if (PIND & (1<<Taster1))
30
    {
31
      loesche_LED2();
32
    }
33
  }  
34
}

Danke schon mal an alle, di emir helfen.

von Mehlhuhn (Gast)


Lesenswert?

Spätestens
C. B. schrieb:
>     while(1)
>     {
>     if (PIND & (1<<Taster1))
>     {
>            setze_LED2();
>     } <---------------HIER
>     if (PIND & (1<<Taster1))
>     {
>       loesche_LED2();

musst du den Taster wieder losgelassen haben damit die LED anbleibt. Was 
glaubst du wohl wie lange es dauert die obere Bedingung und den 
Funktionsaufruf abzuarbeiten? Ein paar µs. So kurz kannst du deinen 
Taster gar nicht drücken.

So oder ähnlich müsste es gehen:

while(1)
{
if(PIND&(1<<Taster1))
{
  PORTD ^= (1<<PD6); //toogeln
  _delay_ms(50); //entprellen
  while(PIND&(1<<Taster1)); //warten bis Taster wieder losgelassen
}
}

Elegant ist das aber nicht.

von Ralf G. (ralg)


Lesenswert?

C. B. schrieb:
>     if (PIND & (1<<Taster1))
>     {
>            setze_LED2();
>     }
>     if (PIND & (1<<Taster1))
>     {
>       loesche_LED2();
>     }

Hier passiert erstmal gar nicht viel. Müsste die LED nicht immer 
leuchten? (So mit halber Kraft)

von Ralf G. (ralg)


Lesenswert?

Ralf G. schrieb:
> Hier passiert erstmal gar nicht viel. Müsste die LED nicht immer
> leuchten? (So mit halber Kraft)

Muss mal korrigieren:
Nach Programmstart -> LED aus
Taste drücken -> LED an (aber nicht richtig, geht ja immer an und aus)
Taste loslassen -> LED entweder 'richtig' an oder aus, je nachdem welche 
if-Abfrage als letztes erreicht wird

Ein 'Taste loslassen' wird nicht ausgewertet.

Edit: Ablauf bei Taster mit Widerstand nach Plus!

von Wilhelm F. (Gast)


Lesenswert?

C. B. schrieb:

> Also, ich versuche "bloß" eine LED mit einem Taster anzuschalten und
> dann mit bei einem erneuten Tasterndruck wieder auszuschalten.

Hier mal ein Beispiel, es stammt aus einem externen 8051-Interrupt für 
Software-Single-Step, und entprellt die Interrupt-Taste:
1
        ACALL   WL              ; warte auf Low-Pegel
2
        ; hier könnte eine Aktion statt finden, wie LED einschalten
3
        ACALL   WH              ; warte auf High-Pegel
4
        ; hier könnte eine Aktion statt finden, wie LED ausschalten
5
        ACALL   WL              ; warte auf Low-Pegel
6
        ACALL   WH              ; warte auf High-Pegel
7
        CLR     IE0             ; l”oesche INT0-Request-Flag
8
        RETI
9
10
WH:     MOV     A,#250          ; Software-Entprellung:
11
WHA:    JNB     P3.2,WH         ; warten, bis Int-Eingang
12
        NOP                     ; wieder auf Highpegel
13
        NOP
14
        NOP
15
        DJNZ    ACC,WHA
16
        RET
17
18
WL:     MOV     A,#250          ; Software-Entprellung:
19
WLA:    NOP                     ; jetzt auf Lowpegel warten
20
        NOP                     ; Wartezeit durch NOPs
21
        NOP
22
        JB      P3.2,WL
23
        DJNZ    ACC,WLA
24
        RET

Das Programm läßt sich für einen Anfänger zum Test aber auch prima im 
Hauptprogramm ohne Interrupt ausführen. Es ist eine Direkt-Entprellung 
der Taste am Ort des Geschehens.

Das kann jetzt etwas schräg sein. Aber: Viele Wege führen nach Rom.

Sorry, 8051-Assembler. Sollte in C genau so gut gehen.

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.