Forum: Compiler & IDEs Wäre hier ein break in der If-Anweisung angebracht?


von Uwe S. (2bigus)


Lesenswert?

Guten Morgen

sitze schon seit gestern über einem Problem und finde irgendwie keine 
vernüftige Lösung.
1
/*
2
 * Binaerzaehler_tagzwo.cpp
3
 *
4
 * Created: 27.10.2013 07:34:23
5
 *  Author: Uwe
6
 */ 
7
#define F_CPU 921600UL
8
#include <avr/io.h>
9
#include <util/delay.h>
10
11
12
int main(void)
13
{
14
  unsigned char Zaehler=0;
15
  unsigned char ein = 0;
16
17
  DDRD=0xFF;      // PortD als Ausgang festlegen
18
  DDRA=0x00;      // PortA als Eingang festlegen
19
  PORTD=0x0F;      // PortD durch interne Pullup´s auf 1 legen damit alle 8 LED´s aus sind
20
  
21
  while(1)
22
  {
23
24
    unsigned char SW0 = (!(PINA & (1<<PA0))), SW2 = (!(PINA & (1<<PA2)));  // Switch 0 und 2 sind HIGH bei Tastendruck werden beide auf LOW geschaltet
25
    
26
    if(SW0 != ein)      // Binärzähler startet bei Tastendruck von SW0, XOR verknüpfen um die Selbsthaltung zu realisieren
27
    {
28
      ein |= SW0;      // Selbsthaltung aktivieren
29
      PORTD=~Zaehler++;  // negativ Logik damit die LED´s erst alle aus sind 
30
      _delay_ms(150);    // Zeitverzögerung um das hochzählen des Binärzählers verfolgen zu können
31
      
32
    }
33
    else if(SW2)      // Rücksetzen auf 0 um wieder von vorne zu starten
34
    {
35
      Zaehler=0;
36
      PORTD=0xFF;
37
    }
38
  }
39
}        // WIE KANN MAN DIE EIN ANWEISUNG mit einem zweiten Taster stoppen??????????

: Verschoben durch User
von g457 (Gast)


Lesenswert?

> sitze schon seit gestern über einem Problem und finde irgendwie keine
> vernüftige Lösung.

Das da wäre?

von Uwe S. (2bigus)


Lesenswert?

g457 schrieb:
> Das da wäre?

Ich möchte mit einem zweiten Taster den Zähler stoppen.

: Bearbeitet durch User
von Unbekannter (Gast)


Lesenswert?

Hmm, muesste das nicht if (SW2 != ein) heissen oder ähnlich?

von Karl H. (kbuchegg)


Lesenswert?

wie wärs mit folgendem Schema
1
 ...
2
  running = FALSE;
3
4
  while( 1 )
5
  {
6
7
    if( Taster 1 gedrückt )
8
      running = TRUE;
9
10
    if( Taster 2 gedrückt )
11
      running = FALSE;
12
13
    if( running )
14
    {
15
      Zähler erhöhen
16
      Zähler ausgeben
17
    }
18
19
    _delay_ms( 100 );
20
  }


Das ist:
eine Hilfsvariable, die mit ihrem Wert (0 oder 1, FALSE oder TRUE) eine 
Aussage darüber macht, ob der Zähler laufen soll oder nicht. Ist die 
Aussage der Variable dergestalt, dass der Zähler laufen soll, dann macht 
das der Zähler dann auch: er wird hochgezählt und ausgegeben.
Davon losgelöst ist die Steuerung dieser Variable. In deinem Fall können 
zb die beiden Schalter/Taster auf diese Variable einwirken. Das muss 
nicht so sein, ist bei dir aber so. Es wäre auch denkbar, dass diese 
Variable von anderen Dingen beeinflusst wird. Vieles ist möglich, aber 
wichtig ist, dass du das Vorhandensein der Schalter/Taster vom Zähler 
entkoppelt hast. Der Zähler 'hängt' nur an seiner Variablen - wie auch 
immer die dann beeinflusst wird.

: Bearbeitet durch User
von termite (Gast)


Lesenswert?

ist der konstrukt mit

SW0 != ein mit ein |= SW0 gewollt?

damit dürfte der Zahler erst mit dem losslaseen loslaufen.

der zahler geht alle 150 ms um eins nach oben.

der else zweig wird nur aktiev wenn du beide tasten drückst!

damit ist SW0 == dem überschriebenen Ein. und dann und nur dann kann 
auch der else zweig aktiv werden.

wobei beim losslassen das ganze wieder los düst, da die selbsthaltung 
nicht gelöscht wurde.

von F. F. (foldi)


Lesenswert?

Karl Heinz schrieb:
> wie wärs mit folgendem Schema
1
>     _delay_ms( 100 );
2
>   }
3
>

Wofür an dieser Stelle ein Delay?

von Karl H. (kbuchegg)


Lesenswert?

F. Fo schrieb:
> Karl Heinz schrieb:
>> wie wärs mit folgendem Schema
>
1
>>     _delay_ms( 100 );
2
>>   }
3
>>
>
> Wofür an dieser Stelle ein Delay?

Damit er seinen Binärzähler auch hochlaufen sieht. Ob er denn delay in 
den Zählteil mit reinnimmt oder so wie hier in die Hauptschleife gibt, 
bleibt ihm überlassen.

: Bearbeitet durch User
von termite (Gast)


Lesenswert?

noch ein problem.

selbst wenn du im else zweig die selbshaltung löscht, ist SW0 ja 
immernoch gedrückt, was dann wieder der startbedingung entspricht.

Der vorschlag von Karl Heinz sieht da besser aus. Da muss man sich nicht 
das hirn so verrenken um zu kapieren was da einer machen will.

von Uwe S. (2bigus)


Lesenswert?

Unbekannter schrieb:
> Hmm, muesste das nicht if (SW2 != ein) heissen oder ähnlich?

Das Programm funktioniert soweit ganz gut die Abruch bzw. Stopbedingung 
ist mein Problem. Sobald ich SW0 drücke startet das Programm. Wenn ich 
SW0 gedrückt halte stoppt das Programm und ich kann mit SW2 den Zähler 
auf null setzen. Dann startet das Programm von selbst wieder. Ich würde 
aber gerne das Programm stoppen und dann zurücksetzen und dann erneut 
mit SW0 starten.

von Karl H. (kbuchegg)


Lesenswert?

D.h. du hast 3 notwendige Funktionen

* Zähler starten
* Zähler stoppen
* Zähler auf 0 setzen

aber nur 2 Taster. Das geht dann so nicht, solange du dich nur auf einen 
gedrückten Taster konzentrierst.

Du läufst gerade in das Problem hinein, dass du einen Tastendruck von 
einer gedrückten Taste unterscheiden lernen musst.

Das wäre noch nicht so schlimm, wenn dir da nicht die notwendige 
Tastenentprellung einen Strich durch die Rechnung machen würde.

Entprellung

: Bearbeitet durch User
von nur mal so (Gast)


Lesenswert?

1. Wird der Schalter nicht aktualisiert. Es gibt nur eine 
Initialisierung der Variablen.
2. Lässt sich das delay nicht unterbrechen.

von termite (Gast)


Lesenswert?

Das ist das problem das ich erkannt habe.

Beim Stoppen wird die selbshaltung nicht gelöscht. "ein" wird nicht 
wieder genullt. Selbst wenn du das machen würdest, hättest du das 
problem, das SW0 noch gedrúckt ist, ein != SW0 und somit im nächsten 
durchlauf die startbedingung wieder erfüllt ist.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> D.h. du hast 3 notwendige Funktionen
>
> * Zähler starten
> * Zähler stoppen
> * Zähler auf 0 setzen
>
> aber nur 2 Taster. Das geht dann so nicht, solange du dich nur auf einen
> gedrückten Taster konzentrierst.

Alternativ würde ich vorschlagen, die Funktionen "Zähler auf 0 setzen" 
und "Zähler starten" zusammenzulegen.

von Uwe S. (2bigus)


Lesenswert?

Karl Heinz schrieb:
> wie wärs mit folgendem Schema

Danke die Lösung scheint perfekt zu sein ich hab mir die ganze Zeit das 
Hirn verrenkt und bin eben nicht auf deinen Vorschlag gekommen.
DANKE

von Uwe S. (2bigus)


Lesenswert?

Karl Heinz schrieb:
>> D.h. du hast 3 notwendige Funktionen
>>
>> * Zähler starten
>> * Zähler stoppen
>> * Zähler auf 0 setzen
>>
>> aber nur 2 Taster. Das geht dann so nicht, solange du dich nur auf einen
>> gedrückten Taster konzentrierst.

Ich will ja auch mit SW1 den Zähler stoppen

von F. F. (foldi)


Lesenswert?

@Karl Heinz

Eigentlich würden deine gesammelten Vorschläge ja schon ein gutes 
Anfängerbuch abgeben, aber du solltest wirklich mal eins schreiben und 
dann besser für Anfänger mit leichten Vorkenntnissen (also für mich 
;-)).

von Karl H. (kbuchegg)


Lesenswert?

Uwe Seelmann schrieb:
> Karl Heinz schrieb:
>>> D.h. du hast 3 notwendige Funktionen
>>>
>>> * Zähler starten
>>> * Zähler stoppen
>>> * Zähler auf 0 setzen
>>>
>>> aber nur 2 Taster. Das geht dann so nicht, solange du dich nur auf einen
>>> gedrückten Taster konzentrierst.
>
> Ich will ja auch mit SW1 den Zähler stoppen

Und mit SW0 startest du ihn.

Und wie setzt du ihn auf 0 zurück? (Also jetzt: aus Benutzersicht 
gesehen?)

von termite (Gast)


Lesenswert?

Er hat doch 2 taster, damit lassen sich doch 4 zustände abbilden.

SW0 gedrückt Zähler starten
SW1 gedrückt Zähler stoppen

SW0 und SW1 gedrückt Zähler zurücksetzen (ggf nur dann wenn zähler nicht 
läuft) wobei hier dann noch ein paar gemeinheiten mit reinspielen, da 
man 2 taster nie gleichzeitig drücken kann. Das heist man müsste erst 
sw1 drücken und gedrückt halten, dann kurz sw0 drücken um den Zähler zu 
löschen.

beide nicht gedrückt entweder zählen oder nichts tun.

von Uwe S. (2bigus)


Lesenswert?

Karl Heinz schrieb:
> Und wie setzt du ihn auf 0 zurück? (Also jetzt: aus Benutzersicht
> gesehen?)

Ich habe ein STK500 da sind Taster verbaut, also dachte ich mir einen 
zum Starten einen zum Stoppen und einen zum Rücksetzen. Am Anfang wollte 
ich das mit nur zwei Tastern machen da hab ich aber eben keine richtige 
Lösung gefunden.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Uwe Seelmann schrieb:
> Karl Heinz schrieb:
>> Und wie setzt du ihn auf 0 zurück? (Also jetzt: aus Benutzersicht
>> gesehen?)
>
> Ich habe ein STK500 da sind Taster verbaut, also dachte ich mir einen
> zum Starten einen zum Stoppen und einen zum Rücksetzen.


Also hast du 3 Taster. Ist ok.


Passt soweit. Du bist der Programmierer, du definierst wie das 
funktionieren soll und wieviele Taster du einsetzt. Soweit hast du 
absolut freie Hand.

Schweiriger wird es erst, wenn du eine Doppelfunktion auf einem einzige 
Taster liegen hast. Wie zb. der erste Tastendruck startet den Zähler. 
Der zweite Tastendruck auf demselben Taster stoppt ihn wieder. Und mit 
dem anderen Taster setzt du ihn auf 0 zurück. Denn da läufst du in das 
schon angesprochene Problem des sauberen erkennen eines Tstendrucks (im 
Gegensatz zu 'ist ein Taster gedrückt') rein. Und da wirds dann 
unangenehm.

von F. F. (foldi)


Lesenswert?

Wieso soll das nicht mit zwei Tastern gehen.

Wenn Taster1
  starte



Wenn Taster2
  stoppe


Wenn alles gestoppt
  Zähler zurücksetzen auf Null


Sehe ich das verkehrt?

: Bearbeitet durch User
von Uwe S. (2bigus)


Lesenswert?

F. Fo schrieb:
> Wieso soll das nicht mit zwei Tastern gehen.

> Wenn Taster1
>   starte

> Wenn Taster2
>   stoppe

> Wenn alles gestoppt
>   Zähler zurücksetzen auf Null

> Sehe ich das verkehrt?

korrekt genau so war Plan eins

von Uwe S. (2bigus)


Lesenswert?

@Karl Heinz

Da Du recht kompetent bist hab ich da nochmal eine Frage wenn ich einen 
Taster mit z.b kurzer Tastendruck = ein belegen will und langer 
Tastendruck = aus belegen will wie realisiert man das?

von F. F. (foldi)


Lesenswert?

Dafür hat man doch einen µC und in jedem noch so doofen Anfängerbuch 
steht es doch drin, wie man Tastendrücke "festhält".

Ich hatte das jetzt sehr knapp beschrieben. Aber man kann es ja auch mit 
einem Taster machen.
Jede Lampe mit Touch Steuerung funktioniert mit nur einem Taster und da 
sogar mit mehreren Funktionen.

von Uwe S. (2bigus)


Lesenswert?

F. Fo schrieb:
> Dafür hat man doch einen µC und in jedem noch so doofen Anfängerbuch
> steht es doch drin, wie man Tastendrücke "festhält".

Kannst Du mir ein solches empfehlen.

von F. F. (foldi)


Lesenswert?

Karl Heinz schrieb:

> Schweiriger wird es erst, wenn du eine Doppelfunktion auf einem einzige
> Taster liegen hast. Wie zb. der erste Tastendruck startet den Zähler.
> Der zweite Tastendruck auf demselben Taster stoppt ihn wieder. Und mit
> dem anderen Taster setzt du ihn auf 0 zurück. Denn da läufst du in das
> schon angesprochene Problem des sauberen erkennen eines Tstendrucks (im
> Gegensatz zu 'ist ein Taster gedrückt') rein. Und da wirds dann
> unangenehm.

Ich kenne natürlich die "Entprellung" nach Peter Danegger, aber als ich 
mit Arduino begonnen hatte, da machte man das im Buch mit einem ganz 
kurzem Delay. Bei mir funktionierte das gut.

von Karl H. (kbuchegg)


Lesenswert?

F. Fo schrieb:
> Wieso soll das nicht mit zwei Tastern gehen.
>
> Wenn Taster1
>   starte
>
>
>
> Wenn Taster2
>   stoppe
>
>
> Wenn alles gestoppt
>   Zähler zurücksetzen auf Null


Sobald du Taster 2 drückst IST alles gestoppt. Der Zähler geht auf 0.
Wie liest du das Zählergebnis ab?

von Uwe S. (2bigus)


Lesenswert?

Karl Heinz schrieb:
> Wie liest du das Zählergebnis ab?

Anhand der LED´s in Binärcode sprich am PortD

von Karl H. (kbuchegg)


Lesenswert?

Uwe Seelmann schrieb:
> @Karl Heinz
>
> Da Du recht kompetent bist hab ich da nochmal eine Frage wenn ich einen
> Taster mit z.b kurzer Tastendruck = ein belegen will und langer
> Tastendruck = aus belegen will wie realisiert man das?

Ganz ehrlich.
Da dein Programm mit "zweiter Tag" überschrieben ist, geh ich davon aus, 
dass du erst vor ein paar Tagen angefangen hast.
Und dafür ist diese Aufgabenstellung VIEL ZU SCHWER!

Das ist nichts gegen dich. Tasten sauber in allen möglichen Varianten 
abzufragen IST SCHWER! (Erstaunlicher weise)

Daher: vertag das noch. Zumindest solange, bis du keine 2 Tage mehr 
brauchst um rauszukriegen, dass du dir mit einer Hilfsvariablen (so wie 
hier vorgeschlagen) das Leben enorm erleichtern kannst. Es hat wenig 
Sinn, wenn ich dir jetzt fachgerecht auseinander setze, wie man das nach 
den Regeln der Kunst macht. Du würdest 9/10 davon nicht verstehen, weil 
dir im Vorfeld noch viel zu viel fehlt.

: Bearbeitet durch User
von Uwe S. (2bigus)


Lesenswert?

@Karl Heinz

Danke schön für die Hilfe ich werde mich da noch etwas einarbeiten und 
wenn ich dann wieder auf das Problem stoße darf ich dann bei dir wieder 
anfragen?

Gruß Uwe

von F. F. (foldi)


Lesenswert?

Karl Heinz schrieb:
> F. Fo schrieb:
>> Wieso soll das nicht mit zwei Tastern gehen.
>>
>> Wenn Taster1
>>   starte
>>
>>
>>
>> Wenn Taster2
>>   stoppe
>>
>>
>> Wenn alles gestoppt
>>   Zähler zurücksetzen auf Null
>
>
> Sobald du Taster 2 drückst IST alles gestoppt. Der Zähler geht auf 0.
> Wie liest du das Zählergebnis ab?

Wieso ist alles gestoppt?

Natürlich muss ich den "Taster1 gedrückt" in einer Variablen festhalten.
Das ist das Kapitel gleich nach dem "Blink".

von Uwe S. (2bigus)


Lesenswert?

An Alle die es Interessiert das Programm sieht jetzt so aus:
Es läuft tadellos auf dem STK500
1
int main(void)
2
{
3
  unsigned char Zaehler=0;
4
  unsigned char run = 0;
5
6
  DDRD=0xFF;      // PortD als Ausgang festlegen
7
  DDRA=0x00;      // PortA als Eingang festlegen
8
  PORTD=0x0F;      // PortD durch interne Pullup´s auf 1 legen damit alle 8 LED´s aus sind
9
  
10
  while(1)
11
  {
12
13
    unsigned char SW0 = (!(PINA & (1<<PA0))),SW1 = (!(PINA & (1<<PA1))), SW2 = (!(PINA & (1<<PA2)));  
14
// Switch 0,1 und 2 sind HIGH bei Tastendruck wird jeder nach LOW geschaltet
15
    
16
    if(SW0 == 1)      // Binärzähler startet bei Tastendruck von SW0
17
    {
18
      run = 1;
19
    }
20
    if(SW1 == 1)
21
    {
22
      run = 0;
23
    }
24
    if(run)    
25
    {
26
      PORTD=~Zaehler++;  // negativ Logik damit die LED´s erst alle aus sind 
27
      _delay_ms(150);    // Zeitverzögerung um das hochzählen des Binärzählers verfolgen zu können
28
      
29
    }
30
    else if(SW2)      // Rücksetzen auf 0 um wieder von vorne zu starten
31
    {
32
      Zaehler=0;
33
      PORTD=0xFF;
34
    }
35
  }
36
}

von nur mal so (Gast)


Lesenswert?

Kann mir jemand erklären, wie sich die Tasten aktualisieren?

SWx sind Variablen und keine define#. Nach der Initialisierung werden 
sie nicht mehr beschrieben. Was übersehe ich?

von Karl H. (kbuchegg)


Lesenswert?

nur mal so schrieb:
> Kann mir jemand erklären, wie sich die Tasten aktualisieren?
>
> SWx sind Variablen und keine define#. Nach der Initialisierung werden
> sie nicht mehr beschrieben. Was übersehe ich?

Dass die Variablen innerhalb der Hauptschleife definiert sind.
D.h. jedesmal beim Ende der Schleife werden sie zerstört und mit dem 
nächsten Durchgang durch die Schleife neu erzeugt. Und als solches 
natürluch auch jedesmal wieder neu initialisiert. Mit den dann gültigen 
Werten der Portpins

von nur mal so (Gast)


Lesenswert?

Karl Heinz schrieb:
> D.h. jedesmal beim Ende der Schleife werden sie zerstört und mit dem
> nächsten Durchgang durch die Schleife neu erzeugt.

Na klar! Ist ja nicht static deklariert. Danke!

War spät und lustig gestern. :-D

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.