Ska du ha en riktig exakt klocka ska du montera en DS32KHZ! Det är en 32768Hz oscillator som är temperaturkompenserat, om du kör "rumstemperatur" har du en avvikelse på max ±1 min/år och det är väl skapligt.
Vill du vara ännu häftigare monterar du också en DCF77-mottagare men det är en del mer pyssel med den biten.
Det lösa klockkristaller på 32768Hz är inte speciellt noga, ska de bli bra måste du trimma deras belastningskondingar och till detta ha en bra (exakt!) frekvensmätare... Ska man undvika DS32KHZ är det faktisk mer noga med det vanliga klockkristall (4MHz ELFA 74-515-29 ±50ppm) än ett 32KHz klockkristall (ELFA 74-530-04 ±50ppm @ 12,5pF) då deras lastkapicitans kan vara svår att få rätt.
Att ett avbrott maskas ut under ISR-tide betyder INTE att timern sluter köra eller hur? Näpp, det betyder bara att timern inte ger interrupt under den tid och då en ISR (Interrupt Service Routine) ska vara snabb (inden "delay"/"wait" eller skit) lär den rikligt hinna genom.
Ett sätt är att ställa timern till att ge interrupt varje sekund och då öka en flagga som anger att sekunderna ska ökas på. Efter det avsluter man ISR'n.
I "huvudrutinen" kollar man sedan om denna flagga är mer än noll. Är den mer än noll räknar man 1 ner och öker på sekunderna/minuterna/timmerna.
Om det nu tar så helvetes lång tid att det tar mer än 1 sekund kommer flaggan ju att visa att det åter ska läggas till osv. Om din uppdateringstid likaväl tar mer än 1 sek har du ett programmeringsproblem hur som helst eller en ovanligt seg µC.
Man räknar ju:
Kod: Markera allt
if(Flaggan) // Allt annat än noll är sant
{
Flaggan--; // Räkna bort 1 uppdatering
if(++Seconds >= 60) // Räkna upp sekunder OCH kolla om den är 60 eller mer
{
Seconds = 0;
if(++Minutes >= 60) // Samma grej med minuterna
{
Minutes = 0;
if(++Hours >= 24) Hours = 0; // Nolla om den blir 24 eller mer
}
}
}