Hallo Nightstorm99,
Natürlich hab ich dazu ein Programmbeispiel, nur leider passt das nicht ganz in die Rubrik, weil es in C geschrieben ist...
Ich poste trotzdem ein paar Ausschnitte, ich hoffe, daß ein Bascomer C lesen kann
Da ich im Moment mit dem Mega169 Arbeite bezieht sich das Beispiel auf diesen µC.
Bei M169 ist der Timer2 der jenige, der sich asynchron betreiben läßt.
Im Zweifel hilft ein Blick in das Dattenblatt ob der Timer 2 oder 0 werwendet werden kann.
Initialisiert wird er so:
Code:
void RTC_Init(void) {
wait(1000);//1 Sekunde warten, damit der Quarz sicher schwingt
cli();
TIMSK2 &=~(1<<TOIE2);
ASSR = (1<<AS2);
TCNT2 = 0;
TCCR2A |= (1<<CS22) | (1<<CS20);// select precaler: 32.768 kHz / 128 = 1 sec between each overflow
while((ASSR & 0x01) | (ASSR & 0x04));// wait for TCN2UB and TCR2UB to be cleared
TIFR2 = 0xFF; // clear interrupt-flags
TIMSK2 |=(1<<TOIE2); // enable Timer2 overflow interrupt
sei();
uhr.sek = 0;
uhr.min = 20;
uhr.std = 19;
uhr.tag = 1;
uhr.monat = 12;
uhr.jahr = 7;
}
Ich denke Bascom liefert einen Einzeiler, der das ganze übernimmt, sonst kann man die Register auch in Basic per Hand setzen.
uhr.* ist eine einfache struct, wo halt die Zeit und Datum gespeichert wird.
Dazu braucht man noch den Timer2 Überlauf Interrupt, der z.B. so Aussieht
Code:
ISR(TIMER2_OVF_vect) {
if (++uhr.sek >= 60) {
PowerSaveTimer++;
uhr.sek = 0;
if (++uhr.min >= 60) {
uhr.min = 0;
if (++uhr.std >=24){
uhr.std = 0;
uhr.tag++;
if (uhr.tag > pgm_read_byte(&MonatsLaenge[uhr.monat])) {
uhr.tag = 1;
if (++uhr.monat >=12){
uhr.monat = 1;
uhr.jahr++;
}
}
}
}
}
}
Hier werden halt Sekunden hochgezählt, dann entsprechend Minuten,Stunden, Tage usw.
Ich habe darauf verzichtet, die Schaltjahre zu testen, um festzustellen, wieviele Tage wohl der Februar hat, das kann aber gut mit Modulo 4 getestet werden
Jede Minute wird die Variable PowerSaveTimer inkrementiert und in der Hauptschleife mit einem Wert verglichen, wo man den Timeout festlegt, also ab wann der µC anfangen soll Strom zu sparen.
Das sieht dann so aus:
Code:
if (PowerSave == FALSE) {
/*Tue was*/
if (PowerSaveTimer >= POWERSAVETIMEOUT) {
PowerSaveTimer = 0;
PowerSave = TRUE;
}
}
else {
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_mode();
if (!(PINB&(0x40))) {
PowerSave = FALSE;
}
}
Wenn PowerSaveTimer den Wert von POWERSAVETIMEOUT erreicht hat, wird Strom gespart, ab hier wird nur der Interrupt ausgeführt, geschaut, ob eine Taste betätigt wurde, wenn nicht, wird weiter geschlafen.
Das wäre dann das wichtigste
Gruß Sebastian
P.S. Ich will hier keinen auf Jehova machen nur ein Beispiel zeigen...
Wenn jemand meint, ich soll mein 'Programm' entfernen dann mag er mir das sagen.
Lesezeichen