Forum: Mikrocontroller und Digitale Elektronik Rat für Zeitausgabe / Zeitberechnung


von µC-noob (Gast)


Lesenswert?

Hallo,
was sagt ihr dazu:

Ich hab bei meinem Programm im hintergrund einen Secundentimer Laufen:
Dieser wird über Timer2 gesteuert und geht erst wieder auf null, wenn 
ein Jahr erreicht ist (oder VCC aus/ ControllerReset).
Code:
1
ISR(TIMER2_COMP_vect)
2
{
3
    static unsigned int iCount = 0;
4
5
    TCNT2 = (TCNT2 - COUNT_VAL); // set timer2 count register value
6
    
7
    iCount++;
8
    
9
    if (iCount == COUNT_STEPS)
10
    {
11
       centralTimeSec++;
12
    }
13
}

Nun ist das als ausgabe für ein LCD natürlich ungünstig:

Deshalb hab ich folgende routine geschrieben:
Diese soll aus der dauerhaft hochlaufenden Secundenzahl
eine Zeitausgabe hh:mm:ss machen.
1
  if( (centralTimeSec) % 60) == 0 )
2
  {
3
    secCounter++;
4
  }
5
6
  if ( centralTimeSec < 59)
7
    secCounter = 0;
8
9
  testSec = (centralTimeSec) - (secCounter * 60);
10
11
  if( ( testSec == 0 ) && (centralTimeSec) != 0) )
12
    testMin = testMin++;
13
14
  if( testMin > 59)
15
  {
16
    testMin = 0;
17
    testHour = testHour++;
18
  }


Was sagt ihr dazu, is das gut oder geht das besser????
Wie ist das mit der Multiplikation, die braucht nicht so viel rechenzeit 
wie beispielsweise eine Division??

Gruß

von Karl H. (kbuchegg)


Lesenswert?

µC-noob wrote:

> Was sagt ihr dazu, is das gut oder geht das besser????

Definiere 'besser'.

Ich würde es aber anders machen.
Benötigst du diese hochlaufenden Sekundencounter unbedingt
an anderer Stelle im Programm?
Wenn nicht, dann würde ich diesen Counter durch 3 Variablen
für Sekunden, Minuten, Stunden ersetzen. Der Update ist
dann ziemlich trivial.
1
uint8_t Sekunden;
2
uint8_t Minuten;
3
uint8_t Stunden;
4
5
ISR(TIMER2_COMP_vect)
6
{
7
    static unsigned int iCount = 0;
8
9
    TCNT2 = (TCNT2 - COUNT_VAL); // set timer2 count register value
10
11
    Sekunden++;
12
    if( Sekunden == 60 ) {
13
      Sekunden = 0;
14
      Minuten++;
15
      if( Minuten == 60 ) {
16
        Minuten = 0;
17
        Stunden++;
18
        if( Stunden == 24 ) {
19
          Stunden = 0;
20
        }
21
      }
22
    }
23
}

von µC-noob (Gast)


Lesenswert?

So hatt ichs auch geplant, aber der Counter wird noch an vielen anderen 
Stellen benötigt,...

Außerdem soll der Code für andere Nutzer erweiterbar sein, die schon den 
Wunsch geäußert haben, dass sie gerne einene Zentralzeit in Sekunden 
haben.

Gruß

von Karl H. (kbuchegg)


Lesenswert?

PS: Deine Umrechnung sieht mir nicht ganz koscher aus.
Hast du die mal über ein paar Stunden getestet?

Die kanonische Lösung wäre
1
  Counter = centralTimeSec;
2
3
  Stunden = Counter % 3600;
4
  Counter = Counter / 3600;
5
6
  Minuten = Counter % 60;
7
  Sekunden = Counter / 60;

Wenn dir die Divisionen zuviel Zeit verbrauchen, könnte
man auch auf eine Subtraktionslösung gehen
1
  Counter = centralTimeSec;
2
3
  Stunden = 0;
4
  while( Counter > 3600 ) {
5
    Stunden++;
6
    Counter -= 3600;
7
  }
8
9
  Minuten = 0;
10
  while( Counter > 60 ) {
11
    Minuten++;
12
    Counter -= 60;
13
  }
14
15
  Sekunden = Counter;

Zu Division: Irgendwo in der avr-lib gibt es auch eine
Funktion die gleichzeitig Division und Modulo-Division
macht. Damit könnte man ebenfalls den Zeitbedarf in
der kanonischen Lösung drücken.

Ich finde allerdings die Methode: Mitzählen beim
Inkrementieren immer noch die einfachste Variante.
Alles schön in 8-Bit Arithmetik. Nichts aufwändiges,
lediglich ein paar increments und Vergleiche.

von µC-noob (Gast)


Lesenswert?

Klasse danke,

dein Code gefällt mir weitaus besser als meiner....

THX

Gruß
Jo

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.