...
AVR Anwendung ... Systemzeit setzen und ... abfragen ... ohne einen extra RTC ...
Wenns sonst nix ist! DAS ist easy.
Ich habe eine 50µs-ISR, das ist bei mir ein Mehrfach-Timer, der mir die Boardzeit macht und einen heartbeat (LED-1sec-toggel) und so, dazu einen Sekundenzähler, der erst nach rund neun Stunden überläuft. Wer längere Laufzeiten hat, müsste halt nen Stundenzähler dazu definieren, dann ginge das über Jahre . . . . Abweichung je nach Quarzkonstanz ein paar Sekunden im Monat.
Als Skizze für eine headerdatei:
Code:
// ============================================================================== =
// Zeiten, insbes. Zeitmessung
// ============================================================================== =
volatile s16 Izeit_1; // Wertbereich int16: 32.767. uint16: 65.535
// Timer läuft hoch. Die Interruptroutine läuft mit 20 kHz
volatile s16 Izthrznt; // Der zeitliche Horizont, z.B. 20000 für 2 sec
volatile s16 Isecundn; // Sekunden Programmlaufzeit, 32.767 sec sind
// 546,117 Minuten bzw. 9 Std
// ============================================================================== =
//=============================================================================== =
// Modul R5M_tmrij.c Routinen: Timerroutinen
// ============================================================================== =
void TC2TMR_init(void); // Init Tmr/Cntr 2, 8-Bit auf 20 kHz = 50 µs
void TC2_stop(void); // Stoppe Tmr/Cntr 2
ISR(TIMER2_COMPA_vect); // Routine zählt hoch im Takt 20 kHz = 50 µs
// ============================================================================== =
// ...
#define ToggleBit(ADDR,BIT) ((ADDR) ^= (1<<(BIT))) // Toogelt Bit
Und dazu der eigentliche Timer:
Code:
// ============================================================================== =
// === Initialisierung fuer Timer2 mega168/328
void TC2TMR_init(void) // Init Tmr/Cntr 2, 8-Bit auf 20 kHz = 50 µs
{ //
TCCR2A |= (1<<WGM21); // Timer im CTC-Mode, Top=OCR2A doc S 157
TCCR2B |= (1<<CS21); // Prescaler 1/8 / Clock <- CPU doc S 158
OCR2A = 124; // Preset 124 für 50µs bei 20Mhz
TIMSK2 |= (1<<OCIE2A); // Tmr/Cntr2 CompareA interrupt enabled
// ##>>> Izeit_1 wird im main initialisiert
} //
// ============================================================================== =
// ============================================================================== =
// === Stoppen Timer2 mega168
void TC2_stop(void) // Stoppe Tmr/Cntr 2
{ //
TCCR2A &= ~(1<<WGM21); // Timer WGM21 resetten
TIMSK2 &= ~(1<<OCIE2A); // Tmr/Cntr2 CompA interrupt DIS abled
} //
// ============================================================================== =
// ============================================================================== =
// === Nicht unterbrechbare ISR für timer2 ==================================== */
// Routine zählt hoch im Takt 20 kHz = 50 µs.
ISR(TIMER2_COMPA_vect) // Vektor 7
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{ //
Izeit_1 --; // ###>>> Izeit_1 ist aktuell int16_t ==>>
// Izeit_1 bleibt bis 32000 in der int16-Grenze
if ( Izeit_1 ) // Interrupt-Timer = 1 ... 20 000 ... (1 sec blink)
{ } // WENN Izeit_1 =|= Null => Ausdruck ist wahr => Anweisung ausgeführen
else // Eine Sekunde ist voll =>
{ //
Izeit_1 = Izthrznt; // ansonsten: Rückstellen auf Zeithorizont
ToggleBit (PORTB, L1g); // gnLED auf Pin PB3 toggeln
Isecundn ++; // Sekundenzähler hochtackern, max 9 Std
} // Ende if (Izeit_1 )
// - - - - - - - - - - - - - - - -
return;
} // Ende ISR(TIMER2_COMPA_vect)
// ============================================================================== =
Der "TC2_stop" ist ja im Prinzip für eine Boardzeit nicht sinnvoll, den habe ich für sonstige Anwendungen, die hier nicht interessieren.
Ist es das, was Du suchst ?
Lesezeichen