Forum: Mikrocontroller und Digitale Elektronik Vorwärts/Rückwärtszähler


von Dennis S. (schwarde)


Lesenswert?

Hallo,

ich brauche dringend Hilfe. Ich habe ein Programm bekommen das in C 
geschrieben ist für den Mikroprzessor Atmega32. Da ich totaler Anfänger 
bin habe ich nicht wirklich viel Ahnung was an welcher Stelle des 
Programms statt findet. Ich möchte gerne Kommentarmarken zu Verständinis 
schreiben. Ich habe schonmal angefangen.... es wäre nicht schlecht wenn 
mir einer weiterhelfen könnte mit Kommentaren oder es verständlich 
erklärt.
Das Programm sieht wie folgt aus:
1
 // 8-Bit-Variable für den Zähler
2
  uint8_t Cnt = 0;
3
  // Zustandsvariable: 1=Taste gedrückt 0=Taste nicht gedrückt
4
  uint8_t State = 0;
5
  
6
  // Richtungsbits für LEDs auf Ausgang
7
  DDRC = 0b11111111;
8
  // Richtungsbits für Taster auf Eingang
9
  DDRB = 0b00000000;
10
11
  // Initialen Zählerstand = 0 ausgeben.
12
  // Invertierung des Zählerstands für die Ausgabe auf den LEDs
13
  // nicht vergessen.
14
  PORTC = ~Cnt;
15
  
16
  while (1)
17
  {
18
    switch (State)
19
    {
20
    case 0:
21
      if((PINB & (1 << 7)) && Cnt < 254)
22
      {
23
        Cnt++;
24
        PORTC = ~Cnt;
25
        State = 1;
26
      }
27
      else if((PINB & (1 << 6)) && Cnt > 0)
28
      {
29
        Cnt--;
30
        PORTC = ~Cnt;
31
        State = 2;
32
      }
33
      else if((PINB & (1 << 6)) && (PINB & (1 << 7)))
34
      {
35
        State = 3; 
36
      }
37
      break;
38
    case 1:
39
      if(PINB == 0x00)
40
      {
41
        State = 0;
42
      }
43
      else if((PINB & (1 << 6)))
44
      {
45
        State = 2;
46
      }
47
      else if((PINB & (1 << 6)) && (PINB & (1 << 7)))
48
      {
49
        State = 3;
50
      }
51
      break;
52
    case 2:
53
      if(PINB == 0x00)
54
      {
55
        State = 0;
56
      }
57
      if((PINB & (1 << 7)))
58
      {
59
        State = 1;
60
      }
61
      else if((PINB & (1 << 6)) && (PINB & (1 << 7)))
62
      {
63
        State = 3;
64
      }
65
      break;
66
    case 3:
67
      if(PINB == 0x00)
68
      {
69
        State = 0;
70
      }    
71
      else if((PINB & (1 << 7)))
72
      {
73
        State = 1;
74
      }
75
      else if((PINB & (1 << 6)))
76
      {
77
        State = 2;
78
      }
79
      break;
80
    }
81
  }
82
}

Danke schonmal!!!

: Verschoben durch User
von Karl H. (kbuchegg)


Lesenswert?

Thread verschoben

von Michael (Gast)


Lesenswert?

Dennis Schwarz schrieb:
> Ich habe schonmal angefangen.... es wäre nicht schlecht wenn
> mir einer weiterhelfen könnte mit Kommentaren oder es verständlich
> erklärt.

Das Program initialisiert die Ports und läßt in der While-Schleife einen 
Zustandsautomaten laufen. Über die Case-Anweisung wird das Verhalten in 
den Zuständen getrennt behandelt. Die if - else if Konstruktionen 
steuern jeweils den Übergang in einen anderen Zustand.

von Karl H. (kbuchegg)


Lesenswert?

> Ich möchte gerne Kommentarmarken zu Verständinis schreiben.

Das ist einen Zustandsmaschine (und eine etwas seltsame möchte ich 
hinzufügen).

Um so etwas zu verstehen, wirst du mit Kommentaren nicht weiter kommen.
So etwas malt man sich auf

* die Maschine hat 4 Zustände

* ein
     if( PINB == 0 )
  liest du als 'Wenn keine Taste gedrückt'

* PINB & ( 1 << x )
  kann gelesen werden als 'Taste x gedrückt'

* jeder case realisiert einen Zustand

* die Maschine ist immer nur in einem Zustand, realisiert durch den
  switch, welcher die Variable 'state' auswertet, welche den momentanen
  Zustand der Maschine darstellt.

* eine Zuweisung an 'state' stellt den Übergang von einem
  Zustand in einen anderen Zustand dar

* PORTC = ~Cnt;
  lässt genau die LED leuchten, die im Bitmuster von Cnt auf 1 sind
  hier wird als nichts anderes getan, als den Zählerwert von Cnt
  sichtbar zu machen


Um so etwas aufzuzeichnen, malt man sich die einzelnen Zustände als 
Kreise auf. Bei dir wind es 4 Kreise. Schreib bei jedem Kreis die Nummer 
dazu.
In jedem Kreis stellt man sich immer wieder derselben Frage. Nämlich: 
Bei welcher Eingangssituation (wie sind die Tasten), passiert welche 
Aktion und in welchen Zustand wird dann gewechselt?

Und das kann man sich mit einer Grafik ganz gut veranschaulichen.
Siehe
Statemachine


Alles in allem ist das eine einfache Statemachine, wenn auch eine 
seltsame. Denn echte 'Arbeit' verrichtet sie nur im Zustand 0 bei 
Tastendruck und wechselt dann gleich in einen der anderen Zustände über. 
Die anderen Zustände spielen sich aber nur die Bälle zu und tun im 
Grunde nichts. Erst wenn keine Taste mehr gedrückt ist, geht es wieder 
zurück in den Zustand 0.

von Dennis S. (schwarde)


Angehängte Dateien:

Lesenswert?

So habe ich das Programm verstanden. Wie gesagt es wird nur hin und her 
geschoben. Es hat geholfen sich Kreise auf zu zeichnen.
Die Textdatei befindet sich im Anhang

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

1.

C-Programme werden typischerweise in Textdateien mit einer Namensendung 
".c" gespeichert, und nicht mit ".txt"

2.

Ein jeder dieser Kommentare ist vollkomen sinnfrei (und sogar 
fehlerhaft). Da steht ja links schon was es tut, und als Kommentar nur 
nochmal das selbe in einer andren Sprache. >Es steht nicht da WARUM da 
irgendwas passiert


else if((PINB & (1 << 6)) && (PINB & (1 << 7)))   // PB6 und PB7 
bet�tigt
  {
    State = 3;                                      // Zustand 3
  }
  break;


case 1:                                             // Fall 1
if(PINB == 0x00)                                   // PB6==OFF,PB7==OFF
   {
     State = 0;                                      // Zustand 1




3.

Was genau ist denn ""Zustand 3" nun eigentlich in deiner Schaltung? Das 
wäre kommentierungswert. Die reine Zahl 3 sagt nicht viel aus ....

bei mir persönlich ist "Zustand 3" derjenige, den ich habe, wenn ich 
einen fettigen Reibekuchen und ein Glas Milch zu mir genommen habe, nach 
Beendigung der Achterbahnfahrt mit zusammen gekniffenem Mund aus der 
Gondel steige. Den Statusübergang zum "Zustand 4" beschreibe ich jetzt 
mal nicht ;-)

von Karl H. (kbuchegg)


Lesenswert?

Wegstaben Verbuchsler schrieb:

> Ein jeder dieser Kommentare ist vollkomen sinnfrei (und sogar
> fehlerhaft). Da steht ja links schon was es tut, und als Kommentar nur
> nochmal das selbe in einer andren Sprache. >Es steht nicht da WARUM da
> irgendwas passiert

Wegstaben Verbuchsler hat recht.

Fang erst mal damit an, den Dingen Namen zu geben.
Was ist denn der Taster an PB6? Hat der einen Namen? Hat der eine 
spezielle Funktion? Wenn ja welche?
Kann man den Zuständen Namen geben? Was ist das Charakteristikum eines 
jeden Zustands?

Das sind die Dinge, die interessieren!
Neben ein
      i++;

als Kommentar

      i++;       // i um 1 erhöhen

kannst du dir sparen. Der Kommentar erzählt mir nichts, was ich nicht 
auch im Code sehen würde!

von Karl H. (kbuchegg)


Lesenswert?

Und wenn du den Dingen Namen gibst und die dann auch gleich im Code 
entsprechend einbaust, dann wirst du feststellen, dass der Code immer 
mehr selbsterklärend wird, du also zum großen Teil auf Kommentare sogar 
verzichten kannst, weil alles wissenswerte im Code selber steht. Was 
dann noch bleibt und was so nicht direkt im Code ablesbar ist, das 
schreibt man als Blockkommentar vor den nächsten Codeabschnitt.
C-Programme bei denen jede Zeile einen Kommentar trägt, bei denen sind 
meistens 90% alles Kommentare sinnlose Kommentare. Schreibarbeit für 
nichts und wieder nichts, weil das was im Kommentar steht sowieso schon 
im Code steht.  ... Sofern der Kommentar bei Codeänderungen immer brav 
nachgezogen wurde und nicht sowieso einfach nur falsch ist.

Anstelle von
1
   if( PINB & ( 1 << 6 ) )       // ist die Taste '+' gedrückt

kann man auch schreiben
1
#define KEY_PIN    PINB
2
#define KEY_PLUS   PB6
3
4
.....
5
6
7
8
    if( KEY_PIN & ( 1 << KEY_PLUS ) )

und dann steht plötzlich das, was vorher im Kommentar stand mitten im 
Code, für alle lesbar und ohne das man sich merken muss (oder davon 
abhängig ist, dass der Kommentar stimmt), dass die '+' Taste am Pin 6 
vom Port B hängt.

Und wenn man dann auch noch macht
1
#define KEY_PIN    PINB
2
#define KEY_PLUS   PB6
3
4
#define KEY_PRESSED(x)   (KEY_PIN & ( 1 << (x) ))
5
6
.....
7
8
9
10
    if( KEY_PRESSED( KEY_PLUS ) )

was jetzt den Code gleich in eine ganz andere Liege der 
Selbstkommentierung hievt. Denkt man sich an dieser Stelle beim if noch 
ein paar Füllwörter dazu, dann steht da mehr oder weniger im Klartext 
... "Wenn die Taste '+' gedrückt ist". Und weil es da mehr oder weniger 
genau so im Klartext steht, liest der geneigte Leser auch tatsächlich 
das, was auch wirklich im Code passiert und versteht auch leicht, was da 
im Code passiert. Das erklärt ihm zwar noch nicht in allen Einzelheiten 
das WARUM (warum ausgerechnet hier die '+' Taste interessant ist), aber 
bei einfachen Programmen ist das dann aus dem Zusammenhang heraus nicht 
mehr so schwer zu verstehen.

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.