PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Einfache Uhr



Tux12Fun
03.04.2011, 17:50
Hallo,

ich bin gerade dabei mich etwas mit den Timern im ATMEGA32 zu befassen.
Leider komme ich da nicht so recht auf den grünen Zweig.

Das Projekt soll eine mini Uhr werden. Die Uhrzeit soll auf einem LCD Display
angezeigt werden.

Nun das Problem mit dem Timer:

Freq. ATMEGA32 = 16 Mhz
Zeitfreq = 1s (gesucht)

Soweit ich aus der RN Hilfe verstanden habe, muss ich jetzt zuerst die 16 Mhz in Herz umwandeln

16Mhz = 16.000.000Hz

Dann die

16.000.000 / 1024(PS) = 15625 / 1 Hz(gesuchte Freq) = 15625 = geht nicht, da 8 Bit Timer max. 256

Daraus habe ich dann gefolgert, dass ich das über eine eigene Zählervariable lösen muss

Also das Spiel für 1000 Hz und dann zähle ich in einer Variable nochmal mit bis ich bei 1000 bin = 1 Sek.
16.000.000 / 1024 = 15625 / 1000 Hz(gesuchte Freq) = 15.625 = geht nicht, da ungerade ?
16.000.000 / 256 = 62500 / 1000 Hz(gesuchte Freq) = 62.500 = geht nicht, da ungerade ?
16.000.000 / 64 = 250000 / 1000 Hz(gesuchte Freq) = 250.000 = geht
256(8Bit) - 250 = 6 = Vorladen mit der Zahl 6 oder ?

Also müsste ich als Prescale 64 nehmen und mit 1000 Hz also 1 ms Takt leben

Damit zum Code aus dem RN Beispiel:
- Wie finde ich die Prescaler ? CS20 ist wenn ich das richtig verstehe 1 aber was ist 64 ?
- OCR2 müsste dann nicht 73 sondern 6 sein oder ?
- wie wird sleep_millisec aufgerufen bzw. wer tut das ?
- Die Initialisierung würde dann in die main Funktion gehören oder ?



volatile uint8_t countTimer2; /* Speichert den aktuellen Zählerwert */

/* ISR zum auffangen der Interrupts: */
SIGNAL(SIG_OUTPUT_COMPARE2){
countTimer2++;
}

/* Initialisierung: */
TCCR2 = (1<<CS20) | (1<<WGM21); /* Prescaler von 1 | CTC-Modus (siehe unten für Beschreibung) */
OCR2 = 73; /* Vergleichswert */
TIMSK |= (1<<OCIE2); /* Interrupts aktivieren und damit Timer starten */
sei();

/* Funktionen zum benutzen der Timer:
Diese Funktion nicht aufrufen. Wird von sleep_millisec aufgerufen.
Bei t=100 schläft die Funktion 1 ms. */
inline void sleep(uint8_t t){
/* countTimer2 wird in der ISR oben inkrementiert */
countTimer2 = 0;
while (countTimer2 < t);
}

/** Schläft x-Millisekunden. */
inline void sleep_millisec(uint16_t msec){
uint16_t i;
for(i=0; i<msec; i++) {
sleep(100);
}
}



Danke schon im Voraus für eure Hilfe

Hubert.G
03.04.2011, 18:55
Den Prescaler findest du im Datenblatt, bei mir Seite 124. 64 ist CS22
Wenn du 250000 hast und machst nach 250 Takte einen Interrupt, dann bekommst du 1000, also 1mSec. OCR2 ist daher 250.
Wo sleep aufgerufen wird weiss ich nicht, kenne das Programm nicht.
Wenn du in deiner Endlosschleife wartest bis countTimer2 1000 ist (muss dann allerdings uint16_t sein), dann hast du 1Sekunde.

sternst
03.04.2011, 23:21
Wenn du 250000 hast und machst nach 250 Takte einen Interrupt, dann bekommst du 1000, also 1mSec. OCR2 ist daher 250.
Fast. Für einen Interrupt alle 250 Timer-Takte muss OCR2 249 sein.