mikrocontroller.net

Forum: Compiler & IDEs Taster Stromstoßschalter


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forum

Möchte mit einem ATmega32 einen Stromstoßschalter realisieren, d. h., 
wenn ich den Taster drücke sollen alle LEDs von PORTC leuchten. Bei 
nochmaltigen drücken des Tasters sollen alle LEDs wieder ausgehen.

Verwende einen externen PullDown für die Taster.

Habe schon einige Programme probert, jedoch ohne Erfolg.
Vermutlich handelt es sich um einen Denkfehler.

Hier mein derzeitiger Stand:
#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>



int main(void)
{
    DDRC = 0xFF;
    PORTC =0xFF;
 
    DDRD =0x00;
    //PORTD =0xFF;  // PullUp aktivieren!!

    while(1){
     
        if(PIND & (1<<PD0) && PORTC == 0xFF)  
        {           
        PORTC = 0;
        }          
        if(PIND & (1<<PD0) && PORTC == 0x00)  
        {           
        PORTC = 1;
        }  
    }   
}

Danke für eure Hilfe

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PORTC = 1;
==>
PORTC = 0xFF;

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Außerdem fehlt die Entprellung.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist wie diese elektronischen Würfel, wenn du nicht wartest, bis die 
Taste wieder losgelassen wurde (ggf. mit Entprellung, je nach Taster), 
bleibst du durch Zufall entweder im An oder Auszustand, da die beim 
Taste gedrückt-Zustand mehrere hundert Mal wechseln.

Autor: Michael M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das geht btw inkl entprellung mit 2 invertern...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da hab ich kürzlich was in der Codesammlung gesehen:

Beitrag "Entprellen für Anfänger"


Peter

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt's dich jetzt mehrfach? ;-)

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat den keiner eine Idee wie man einen Stromstoßschalter realisieren 
kann?

Autor: Michael M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
super beitrag!

Autor: noname (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann man mit einer state machine lösen.

state0 //Start
       Wenn Taster gedrückt, dann state1

state1 LEDs einschalten
       Wenn Taster losgelassen wird, dann state2

state2 Wenn Taster gedrückt wird, dann state3

state3 LEDs ausschalten
       Wenn Taster losgelassen wird, dann state4

state4 Wenn Taster gedrückt wird, dann state1

Versuchs mal!

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deinen Hinweis, aber ich weiß nicht wie ich deine Anweisung in 
C umsetzten soll. Vielleicht könntest du ein bisschen konkreter werden. 
Überlege schon den ganzen Tag, jedoch ohne Erfolg.

Autor: Michael M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast du eig die post davor wenigstens mal gelesen???
es werden dir mehrere möglichkeiten zur lösung genannt.

Autor: noname (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fang erst mal einfach an. Schreib ein Programm das die
LEDs einschaltet, wenn der Taster gedrückt ist und die
LEDs ausschaltet, wenn der Taster losgelassen ist.

Als zweiter Schritt kommt die state machine.
Eine Variable enthält den aktuellen state.
Z.B. mystate.

Jetzt wird fortlaufend abgefragt, welchen Wert mystate
hat. Dies ist in einer switch-Anweisung am übersichtlichsten.


while (1)
{
 switch (mystate)
 {
   case 0: if (/* Taste gedrückt */)
             mystate=1;
           break;
   case 1: /* LEDs einschalten */
           if (/* Taste losgelassen */)
             mystate=2;
           break;
   case 2:

   case 3:

   case 4:
 }
}

Ich habe nur die Kommentare eingefügt. Du musst dort
deine Tasterabfrage programmieren und die LEDs schalten.
Wie es nach case 1 weitergeht habe ich ja schon beschrieben.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Unterstützung. Habe das Programm nach deinen Anweisungen 
programmiert, doch es will nicht funktionieren.

Bitte um Korrektur meines Codes
while (1)
{
 switch (mystate)
 {
   case 0: if (PINB & (1<<PB0))
             mystate=1;
           break;
   case 1: PORTC =0x00;
           if (~PINB)
             mystate=2;
           break;
   case 2: if (PINB & (1<<PB0))
             mystate=3;
           break;
   case 3: PORTC =0xFF;
           if (~PINB)
             mystate=4;
           break;
   case 4: if (PINB & (1<<PB0))
             mystate=1;
           break;
 }
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noname schrieb:
> Das kann man mit einer state machine lösen.

Das ist aber nicht der optimale Ansatz, da dabei nicht das Prellen 
gelöst wird.
Besser ist eine Entprellroutine als erster Schritt und da fällt dann das 
Ereignis des Drückens nebenbei mit ab.
Und dann braucht man nur noch ne Toggle-Funktion (EXOR).

Aber das steht ja oben schon alles fix und fertig für 2 Tasten + 2 LEDs.


Peter

Autor: noname (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst zum Debuggen über die LEDs mystate anzeigen lassen.
Dann siehst du wo das Programm steht.
Es liegt vermutlich an ~PINB. Du must hier maskieren.
D.h. den Portpin (das Bit von PINB) auswerten.

Autor: No Name (nohelp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also 'ne State machine für diese popelige Aufgabenstellung ist doch 
reichlichst übertrieben. Richtig ist, man braucht eine Entprellung. Rest 
siehe Peter D.

Autor: noname (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muss man eigentlich eine Entprellroutine verwenden,
wenn der Taster gar nicht prellt?
(Einfach ein RC-Glied vor den AVR-Eingang schalten)
Ich denke das Prellen ist hier nicht das Problem
sondern das Abfragen eines Eingangs und die
Anfangsschwierigkeiten mit C.
Ich habe den Beitrag von P.D. noch nicht durchgelesen,
werde dies aber tun, wenn ich mal eine sehr gute
Entprellung benötigen sollte.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert


uint8_t TaOn;    // Flag




   void Entprell(uint16_t a)
  {
     while (a != 0)
     {
       a = a+1;  // oder irgend einen anderen Unsinn
       a = a-2;
     }
  }


int main(void)
{
    DDRC = 0xFF;
    PORTC =0xFF;
 
    //DDRD =0x00;
    PORTD |= (1<<PD0);  // nimm doch den internen PullUp



    while(1)
    {
     
        if(PIND & (1<<PD0))  
        { 
           // Taster Off
           
           if(TaOn)      // if(TaOn == 1)
           {
              // Taster war vorher an

              Entprell(500);        // Wert testen !!!

              TaOn = 0;
        
              PORTC = 0;
           }
        }
        else 
        {
            // Taster On

            if(!TaOn)       // if(TaOn == 0)
            {
                // Taster war vorher aus

                 Entprell(500);        // Wert testen !!!

                 TaOn = 1;

                 PORTC = 0xFF;
            }
        }
    }   
}


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jens

Danke für dein Programm, jedoch behandelt es nur die Prellzeit und nicht 
die eigentliche Funktion. Mein Anliegen ist einen Stromstoßschalter zu 
ralisieren.--> Wenn eine Taste gedrückt wird sollen alle LEDs leuchten, 
bei einem weiteren betätigen des Tasters sollen die LEDs wieder 
ausgehen. Vielleicht haben andere User einen Tipp.


Danke an alle für die Hilfe.

Autor: noname (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian

Hat das Programm: Taste gedrückt -> alle LEDs an
und Taste losgelassen -> alle LEDs aus
funktioniert?

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ nonqme

Nein leider nicht. Ich vermute auch, dass es an dem ~PINB liegt.
Weißt du was ich ausbessern könnte?

Danke

Autor: noname (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (!(PINB & (1<<PB0)))

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ noname

Danke für dein Programm, wäre nicht so schnell auf diese Variante 
gekommen.
Den letzten Eintrag von dir habe ich auch schon vorher probiert nur mit 
der ~. Wieder mal ein Denkfehler! Gibt es auch andere 
Programmiervarianten für den Stromstoßschalter?

Danke nochmal für deine Hilfe

Autor: Michael M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Gibt es auch andere
> Programmiervarianten für den Stromstoßschalter?

Peter Dannegger schrieb:
> Besser ist eine Entprellroutine als erster Schritt und da fällt dann das
> Ereignis des Drückens nebenbei mit ab.
> Und dann braucht man nur noch ne Toggle-Funktion (EXOR).
>
> Aber das steht ja oben schon alles fix und fertig für 2 Tasten + 2 LEDs.
>
>
> Peter

lies doch einfach mal, was man dir schreibt.
und wart nicht nur auf fertigen code, den du weder verstehst, noch zu 
100% per copy/paste übernehmen kannst.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert


uint8_t  TaOn,    // Flag für die Taste selbst
         LedsOn;   // Flag für die Leds




   void Entprell(uint16_t a)
  {
     while (a != 0)
     {
       a = a+1;  // oder irgend einen anderen Unsinn
       a = a-2;
     }
  }


int main(void)
{
    DDRC = 0xFF;
    PORTC =0xFF;
 
    //DDRD =0x00;
    PORTD |= (1<<PD0);  // nimm doch den internen PullUp



    while(1)
    {
        if(PIND & (1<<PD0))  
        { 
           // Taster Off
           
           if(TaOn)      // if(TaOn == 1)
           {
              // Taster war vorher an

              Entprell(500);        // Wert testen !!!

              TaOn = 0;
             
              // Aktion, wenn Taster losgelassen wird, brauchen wir nicht            
           }
        }
        else 
        {
            // Taster On

            if(!TaOn)       // if(TaOn == 0)
            {
                // Taster war vorher aus

                 Entprell(500);        // Wert testen !!!

                 TaOn = 1;

                // Nun folgt die Aktionen, wenn der Taster gedrückt wird

                 if(LedsOn)
                 {
                   LedsOn=0;
                   PORTC = 0;  // Die Off-Aktion
                 }
                 else
                 {
                   LedsOn = 1;
                   PORTC = 0xFF;  // Die On-Aktion
                 }
            }
        }
    }   
}


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jens

Ich denke, über eines sind wir uns einig.
Tasten entprellen ist eine wichtige und oft benötigte Funktionalität. 
Von daher ist es kontraproduktiv, das Einlesen und Entprellen von 
Tastern in die Aufgabenstellung so dermassen einzuweben, wie du das 
machst.

Legen wir die PeDa-Entprellung zu Grunde, so lautet die Hauptschleife
int main()
{
 ....

  while( 1 ) {
    if( get_keypress( 1<<KEY0 ) )
      PORTC = 0xFF;
  }
}

und jetzt vergleich das mit deiner Lösung.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja natürlich,

ich wollte es doch nur ganz verständlich machen.

Wenn ich mehrere Taster auslese, dann auch mit XOR und alten Pinzustand 
mit neuem vergleichen, wo Änderung und ob Taste gedrückt oder 
losgelassen wurde usw. und als extra Routine oder auch Datei 
(Tasten.c)usw..
Auch die Aktionen, die dann ausgeführt werden sollen, werden in 
Extradateien bzw. Routinen ausgeführt ---- z.B. TaAktionOn(i), 
TaAktionOff(i)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.