Taster mit mehreren Funktionen

Gast #2402306
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ß
Gast #2402366
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?
Gast #2402497
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ß
Gast #2402518
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.
Gast #2402791
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)))
#2403046
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren