Forum: Mikrocontroller und Digitale Elektronik Taster mit mehreren Funktionen


von ole (Gast)


Lesenswert?

Nabend,

ich habe ein kleines Problem.
Unzwar habe ich mir ein kleines Programm geschrieben, was ihre Aufgaben 
soweit erfüllt.
Es soll mit dem Programm verschiedene Funktionen mithilfe eines Tasters 
geschalten werden. Ein klick = Blinklicht, Zwei klick = Lauflicht, etc.
So jetzt habe ich es hin bekommen, das ich bei jedem Tastendruck eine 
verschiedene Funktion habe....jetz habe ich aber bei einem Blinklicht 
z.b. das Problem das die LEDs nur einmal auf blinken...demnach fehlen 
die Schleifen...jetzt habe ich es mithilfe dieser Seite 
http://www.peacesoftware.de/ckurs11.html versucht eine Endlos Schleife 
in die Bedingung ein zu binden. Das klappt auch, nur jetzt geht das 
Programm nicht mehr aus die schleife raus, wenn ich den Taster erneut 
drücke.

Hier das Programm mal mit einer Endlos Schleife:

#include<avr/io.h>
#include<util/delay.h>

int main(void)
{
    DDRB=0xff;
    DDRC=0x00;
    PORTB=0x00;
    PORTC=0x00;

    unsigned int x;

    while(1){
    if ( PINC &(1<<PC0))
    {
        PORTB=0x00;
    }

    if ( PINC &(1<<PC0))
    {
        PORTB=0xff;
    }

    if ( PINC &(1<<PC0))
    {
        for(;;){
        PORTB=0xff;
        _delay_ms(100);
        PORTB=0x00;
        _delay_ms(100);
    }
    }
    if ( PINC &(1<<PC0))
    {

        for (x=0;x<=4;x++)
        {
            PORTB=(1<<x);
            _delay_ms(100);
            PORTB=0x00;
    }
    }
    }
    return 0;
}

Ich steh auf dem Schlauch und krieg es einfach nicht hin, die Schleife 
wieder zu verlassen wie kann ich das Problem lösen? Bitte um Hilfe

Gruß

von till (Gast)


Lesenswert?

Ein Problem ist, dass Tasten beim Drücken prellen (siehe z. B. hier 
http://www.mikrocontroller.net/articles/Entprellung). Dagegen ist dein 
Programm nicht abgesichert. Du könntest den Taster auch als externen 
Interrupt verwenden...

Du ziehst den Taster nicht auf Masse oder?

Ich hätte einen Vorschlag für dein Programm: Nimm eine int-Variable die 
du bei jedem Tastendruck um eins erhöhst bis z. B. 4 und dann wieder von 
vorne anfangen. Dann machst du in deiner Endlosschleife eine if-Abfrage. 
Je nach Wert der Variablen lässt du die LED blinken oder machst das 
Lauflicht usw...

Das Lauflicht könntest du so machen:

if (var == 2) //Variable ist z. B. 2
{
        PORTB ^= 0xFF; //Toggeln
        _delay_ms(100);
}

Ist das verständlich was ich meine?

von Volkmar D. (volkmar)


Lesenswert?

Vielleicht solltest Du das besser mit einer State Machine machen. Mit 
jedem Tastendruck springt das Programm in den nächsten State. Dies wurde 
in einem anderen Thread durchgearbeitet: 
Beitrag "Anfängerfrage zu switch case"

Und wie schon geschrieben: Taster entprellen!

Volkmar

von ole (Gast)


Lesenswert?

Ah okey Danke vielmals! Ich werde mich nachher gleich dran setzen und 
versuchen es zu verwirklichen :)

till schrieb:

> Du ziehst den Taster nicht auf Masse oder?

Doch ich zieh den Taster auf Masse.

Ich werde mich heute Nachmittag nochmals melden und meine Ergebnisse 
präsentieren ;).

Bis dahin einen schönen Tag.
Gruß

von Tom (Gast)


Lesenswert?

ole schrieb:
> for(;;){
>         PORTB=0xff;
>         _delay_ms(100);
>         PORTB=0x00;
>         _delay_ms(100);
>     }

In deiner Blinkschleife machst du eine Endlos-Vollbeschäftigung für den 
Prozessor, ohne den Taster abzufragen. Klar das das Programm dann nicht 
weiter auf den Taster reagieren kann.

Statt der Delays könntest du besser einen Timer im 100 ms Rhythmus einen 
Interupt auslösen lassen und in der ISR den Tasterzustand abfragen und 
ggf. die LED ein- bzw. ausschalten.

von till (Gast)


Lesenswert?

Mit "PORTC=0x00" aktiviest du doch pulldown. D. h. wenn der Taster nicht 
gedrückt ist, liegt eine Null am Eingang...

Mit "if (PINC &(1<<PC0))" fragst du ab ob der Pin auf 1 
(Versorgungsspannung) gezogen wurde oder? Wenn du abfragen willst ob der 
Taster auf Masse gezogen wurde müsste es doch z. B. so heißen: if 
(!(PINC &(1<<PC0)))

von Karl H. (kbuchegg)


Lesenswert?

till schrieb:
> Mit "PORTC=0x00" aktiviest du doch pulldown.

Bei den AVR gibt es keine Pulldown.
Er schaltet die Pullup Widerstände ab. Das heißt aber nicht, dass 
deswegen Pulldowns aktiv wären.

> D. h. wenn der Taster nicht
> gedrückt ist, liegt eine Null am Eingang...

Wenn der Taster nicht gedrückt ist, hat der Eingang keinen definierten 
Pegel (sofern nicht ein externer Pullup oder Pulldown Widerstand 
vorhanden ist)

> Mit "if (PINC &(1<<PC0))" fragst du ab ob der Pin auf 1
> (Versorgungsspannung) gezogen wurde oder? Wenn du abfragen willst ob der
> Taster auf Masse gezogen wurde müsste es doch z. B. so heißen: if
> (!(PINC &(1<<PC0)))

Richtig.

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.