wie Code verbessern?

OP #2376823
Lesenswert?

Schönen guten Abend,

ich habe mir einen Code geschrieben, um aus einem Taster, einen Schalter 
zu machen.
Kann man diesen Code noch irgendwie verbessern?

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

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

    while(1)
    {
        if( PINC &(1<<PC0)){
             PORTB=PORTB ^ 1;
            _delay_ms(50);
            _delay_ms(50);
        }
    }

        return 0;
    }

Das Programm funktioniert soweit...aber manchmal blinkt die LED am 
Ausgang! Kann man das irgendwie umgehen per Software oder mithilfe von 
Hardware?

Gruß Robin
OP #2376883
Lesenswert?

Danke Uli!

Meinst du es so?

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

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

    while(1)
    {
        if( PINC &(1<<PC0)){
            _delay_ms(5);
            PORTB=PORTB ^ 1;
            _delay_ms(50);
            while(2)
            {
                (PINC &(1<<PC0));
            }
            _delay_ms(50);
            }
    }

        return 0;
}
Wenn ja, dann passt das nicht! So bleibt die LED nach dem Tasten druck 
dauerhaft leuchten und lässt sich nicht mehr beim zweiten drücken  aus 
schalten.

Gruß Robin
Persönliche Seite #2376900
Lesenswert?

Klar, Du hast ja auch eine Endlosschleife gebaut. In den Klammern hinter 
While steht nämlich die Bedingung, unter der die Schleife wiederholt 
wird - und alles außer 0 (=FALSCH) ist WAHR. Also wird deine 
While(2)-Schleife nie verlassen. Und das in der While-Schleife ist auch 
ziemlicher Käse. Schau dir doch mal an, was ein Flag und was Entprellung 
ist. Und was ein Timer ist.


Gruß
Jonathan
Persönliche Seite #2376905
Lesenswert?

Jonathan Strobl schrieb:
> Und das in der While-Schleife ist auch
> ziemlicher Käse.

Zumindest dort, wo Du ihn hingeschrieben hast - nicht, dass sich Ulrich 
Radig noch auf den Schlips getreten fühlt ;)

So hat er das gemeint:
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
int main()
5
{
6
    DDRB=0xff;
7
    DDRC=0x00;
8
    PORTB=0x00;
9
    PORTC=0x00;
10

11
    while(1)
12
    {
13
        if( PINC &(1<<PC0)){
14
            PORTB=PORTB ^ 1;
15
            _delay_ms(50);
16

17
           while(PINC&(1<<PC0)) {}
18

19
            _delay_ms(50);
20
        }
21
    }
22

23
        return 0;
24
    }
#2376914
Lesenswert?

Nimm dein Originalprogramm
1
    while(1)
2
    {
3
        if( PINC &(1<<PC0)){
4
             PORTB=PORTB ^ 1;
5
            _delay_ms(50);
6
            _delay_ms(50);
7
        }
8
    }

und teste es:
Drück auf die Taste und bleib mit dem Finger auf der Taste und halte sie 
gedrückt. Deine LED wird wie verrückt blinken.

Warum?

Weil dein Code innerhalb des then-Zweiges vom if ausgeführt wird SOLANGE 
eine Taste gedrückt ist. Das willst du aber nicht. Du willst einen 
Tastendruck erkennen. Wenn also die Taste den Übergang von nicht 
gedrückt zu gedrückt macht.

Dazu gibt es 2 Möglichkeiten
* entweder du lässt das Programm aus dem if-Zweig solange nicht herraus, 
solange die Taste immer noch gedrückt ist
* oder aber, du vergleichst den Pinzustand mit demselben Pinzustand im 
unmittelbar vorhergehenden Durchlauf durch die while Schleife. Dazu 
musst du dir diesen Zustand natürlich merken. Wenn du in einer Zimmer 
reinschaust und da brennt das Licht drinnen und du WEISST, dass es eine 
halbe STunde vorher (als du das letzte mal nachgesehen hast) nicht 
gebrannt hat, dann muss in der Zwischenzeit wohl jemand das Licht 
aufgedreht haben.
Gast #2376952
Lesenswert?

Wenn du mit dem µC noch andere Dinge vorhast, als ihn in den 
Delay-Zeittotschlageschleifen vollzeit mit dem Taster zu beschäftigen, 
solltest du über einen Timer nachdenken, der per IRQ regelmäßig einen 
Blick auf die Tasten wirft und die Tasten auch gleich entprellt.
http://www.mikrocontroller.net/articles/Entprellung#Interrupt-Verfahren_.28nach_Peter_Dannegger.29
Beitrag "Tasten entprellen - Bulletproof"

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