Forum: Mikrocontroller und Digitale Elektronik [Erklärungsbedarf] countdown-demo.zip


von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Guten Morgen,

ich verwende in meinem Projekt den Code aus:
Beitrag "Warten und Verzögern ohne zu Blockieren (avr/delay.h)"

Allerdings blicke ich trotz wirklich zahlreicher Kommentare noch nicht 
so ganz durch den Code aus countdown.c durch.

Ganz speziell die Bedeutung des Pointers *addr.

Aber fangen wir erst mal damit an, was ich überhaupt bezwecken will:
Ich möchte eine Countdown über mehrer Minuten im Format "mm:ss" auf 
einem Display ausgeben.

Bisher tat ich das mit weniger Erfolg durch die Definition und Das 
Aufziehen ZWEIER Laufvariablen:
count.min.duration = 15;
count.sec.duration = 30;

Dabei liefen diese untereinander bereits asynchron. Soll heißen, die 
beiden haben auf dem Display sichtlich zu unterschiedlichen Zeiten 
genullt.

nun wollte ich zuerst ein neues Struct a la:
1
struct
2
        {
3
      // Ab hier die benötigten 16-Bit Countdown-Zähler eintragen
4
        uint16_t duration;
5
        } sec_16;

anlegen
count.sec_16.duration = minutes*60+seconds;
eintragen und später beim Display wieder
1
void printMmSs(uint16_t seconds)
2
{
3
  int8_t mm = seconds / 60;
4
  int8_t ss = seconds % 60;
5
  lcd_printInt(mm, 2);
6
  lcd_print_P(PSTR(":"));
7
  lcd_printInt(ss, 2);
8
}

Doch wie gesagt scheiterte es bei der Durchsicht von countdown.c und die 
2 Zeilen, die dafür sorgen, dass nun meine neue sec_16 ebenfalls 
runtergezählt wird.

ABER, wenn ich die Kommentare richtig deute, soll mein gewünschtes 
Vorhaben wohl bereits out-of-the-box funktionieren!?
Jedoch frage ich mich wie sich Johann L. #1282652 das ursprünglich 
dachte?
Wie müsste ich den Minutencounter setzen, damit ich welche variable als 
Sekunden für das Display auslesen kann?

count.sec.timer_1m ??

Ganz konkret steht dort in Zeile 125-138 (countdown.c):
1
    ///////////////////////////////////////////////////////////
2
    // Die Sekunden-Werte von 'count' runterzählen 
3
    // (8-Bit Werte, falls vorhanden)
4
    // addr zeigt danach auf das erste Element der Komponente
5
    DOWN (count.sec);
6
    if (!sizeof (count.min) || val > 0)        
7
        return;
8
    // Eine Minute ist vergangen: Sekunden-Zähler zurücksetzen
9
    *addr = 60;
10
    
11
    ///////////////////////////////////////////////////////////
12
    // Die Minuten-Werte von 'count' runterzählen 
13
    // (8-Bit Werte, falls vorhanden)
14
    DOWN (count.min);


Ich würde mich riesig über eine kleine Hilfestellung freuen.

Grüße Oekel

: Verschoben durch Moderator
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

D a v i d K. schrieb:
> Ich möchte eine Countdown über mehrer Minuten im Format "mm:ss" auf
> einem Display ausgeben.
>
> Bisher tat ich das mit weniger Erfolg durch die Definition und Das
> Aufziehen ZWEIER Laufvariablen:
> count.min.duration = 15;
> count.sec.duration = 30;

Du brauchst einen Countdown, und zwar jede Sekunde, denn du brauchst 
jede Sekunde ein "Ereignis": Einen Zähler, der 60*min + sek enthält um 1 
vermindern und das Ergebnis anzeigen.  Alternatriv 2 Zähler, einer für 
die Minuten und einer für der Sekunden.  Diese Zähler würd ich aber 
nicht in der countdown Struktur verwalten, sondern im Modul, das auch 
die Anzeige triggert.

Um die 1 Sekunde zu realisieren nimmst du am besten 100 Millisekunden.

: Bearbeitet durch User
von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Johann L. schrieb:
> D a v i d K. schrieb:
>> Ich möchte eine Countdown über mehrer Minuten im Format "mm:ss" auf
>> einem Display ausgeben.
>>
>> Bisher tat ich das mit weniger Erfolg durch die Definition und Das
>> Aufziehen ZWEIER Laufvariablen:
>> count.min.duration = 15;
>> count.sec.duration = 30;
>
> Du brauchst einen Countdown, und zwar jede Sekunde, denn du brauchst
> jede Sekunde ein "Ereignis": Einen Zähler, der 60*min + sek enthält um 1
> vermindern und das Ergebnis anzeigen.  Alternatriv 2 Zähler, einer für
> die Minuten und einer für der Sekunden.  Diese Zähler würd ich aber
> nicht in der countdown Struktur verwalten, sondern im Modul, das auch
> die Anzeige triggert.
>
> Um die 1 Sekunde zu realisieren nimmst du am besten 100 Millisekunden.

Auf die Art und Weise kann ich es mit jedem beliebigen Couter 
realisieren, der mir 1sec zur Verfügung stellt. Das war mir jedoch 
vorher bereits klar.

Ich möchte aber verstehen, was es mit dem ursprünglichen Code auf sich 
hat und wieso die beiden counter dort ungleich sind. Also der für 1min 
!= 60*1sec.

Grüße Oekel

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

D a v i d K. schrieb:
> Johann L. schrieb:
>> D a v i d K. schrieb:
>>> Ich möchte eine Countdown über mehrer Minuten im Format "mm:ss" auf
>>> einem Display ausgeben.
>>>
>>> Bisher tat ich das mit weniger Erfolg durch die Definition und Das
>>> Aufziehen ZWEIER Laufvariablen:
>>> count.min.duration = 15;
>>> count.sec.duration = 30;
>>
>> Du brauchst einen Countdown, und zwar jede Sekunde, denn du brauchst
>> jede Sekunde ein "Ereignis": Einen Zähler, der 60*min + sek enthält um 1
>> vermindern und das Ergebnis anzeigen.  Alternatriv 2 Zähler, einer für
>> die Minuten und einer für der Sekunden.  Diese Zähler würd ich aber
>> nicht in der countdown Struktur verwalten, sondern im Modul, das auch
>> die Anzeige triggert.
>>
>> Um die 1 Sekunde zu realisieren nimmst du am besten 100 Millisekunden.
>
> Auf die Art und Weise kann ich es mit jedem beliebigen Couter
> realisieren, der mir 1sec zur Verfügung stellt. Das war mir jedoch
> vorher bereits klar.
>
> Ich möchte aber verstehen, was es mit dem ursprünglichen Code auf sich
> hat

Zunächst zum countdown-Modul selbst:  Fokus ist ein kleiner 
Resourcen-Verbrauch, insbesondere was die verbnrauchte Zeit angeht, die 
ja in jeder ISR anfällt, d.h. 100x pro Sekunde wird über alle Counter 
geschleift, falls es ein 100µs-Eintrag gibt sogar 10000x.

> und wieso die beiden counter dort ungleich sind. Also der für 1min
> != 60*1sec.

Die Timer haben eine Granularität. Der Sekunden-Count wird z.B: auf 100 
gesetzt und 100x dekrementiert, bis 1 Sekunde voll ist.  Vorteil ist, 
dass so nur ein 8-Bit Zähler benötigt wird.  Nachteil ist, dass 1 
Sekunde nicht besser als 100 ms aufgelöst werden kann.  Analog wird 1 
Minute nicht besser als 1 Sekunde aufgelöst.

Eine bessere Auflösung würde breitere Zähler erfordern, um den 
Minuten-Zähler besser als 1ms aufzulösen wäre z.B. bereits ein 
32-Bit-Zähler erforderlich (bzw. ein 24-Bit-Zähler mit __uint24).

Bei den meisten Warte-Aufgaben sind aber gar keine so großen Auflösungen 
erforderlich:  Wenn zB eine Taste entprellt wird oder zwischen langem 
und kurzem Tastendruck unterschieden wird, dann braucht das ja nicht bis 
in den µs-Bereich genau zu sein.  Ebenso andere Aufgaben, die ich 
üblicherweise darüber realisiere:  DCF entprellen / timen, Eieruhr o.ä., 
LED blinken lassen, Morse ausgeben, Bildschirmschoner timen, etc.

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.