Exakt tidtagning, Atmega16, 32,768-kristall
Jag får följande timerinitiering och när jag använder programmet stämmer tiden:
//TIMER1 initialize - prescale:256
// desired value: 10mSec
// actual value: 10,000mSec (0,0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x6A; //setup
TCNT1L = 0xE2;
OCR1AH = 0x95;
OCR1AL = 0x1E;
OCR1BH = 0x95;
OCR1BL = 0x1E;
ICR1H = 0x95;
ICR1L = 0x1E;
TCCR1A = 0x00;
TCCR1B = 0x04; //start Timer
}
//TIMER1 initialize - prescale:256
// desired value: 10mSec
// actual value: 10,000mSec (0,0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x6A; //setup
TCNT1L = 0xE2;
OCR1AH = 0x95;
OCR1AL = 0x1E;
OCR1BH = 0x95;
OCR1BL = 0x1E;
ICR1H = 0x95;
ICR1L = 0x1E;
TCCR1A = 0x00;
TCCR1B = 0x04; //start Timer
}
Nu har jag gjort så här:
D.v.s. jag kör ett tick mer varannan tusendel. Det blir exakt på typ en timme men sen vet jag inte. Nästa steg är att ta tid en längre stund, kanske 5 timmar, och sen justera så att man ökar/minskar ett tick i en lagom frekvens för att det ska bli bra.
Jag vet att det ändå inte blit helt exakt eftersom kristallen inte är helt exakt men för min tillämpning (se tidigare inlägg) duger det.
Eller finns det nåt smartare sätt? Hur mkt varierar kristallen map temperatur osv? Utrustningen skall främs användas i rumstemperatur så den faktorn är ganska konstant.
Kod: Markera allt
INTERRUPT(SIG_OUTPUT_COMPARE1B) {
// interrupt handler for timer compare match
timer++;
CLEAR_TIMER;
if (!(timer%3)) {
OCR1BH=62;
OCR1BL=91; // increase compare every other 1/1000 of a second
}
else {
OCR1BH=62;
OCR1BL=90;
}
}
void init_clock(void) {
// Starts 16bit timer using 16MHz crystal
TCCR1B|=0x01; // clear timer, no rescaler
TIMSK|=0x08; // interrupt on compare match B
OCR1BH=62; // output compare registers.
OCR1BL=91; // 90 too fast, 91 too slow
TIFR|=0x04; // start timer, compare
sei(); // enable interrupts
}
Jag vet att det ändå inte blit helt exakt eftersom kristallen inte är helt exakt men för min tillämpning (se tidigare inlägg) duger det.
Eller finns det nåt smartare sätt? Hur mkt varierar kristallen map temperatur osv? Utrustningen skall främs användas i rumstemperatur så den faktorn är ganska konstant.
Ah, det e sant. Men jag hade bara en 16 liggandes... Och eftersom det ändå inte blir exakt så att jag ändå måste finjustera kan jag lika gärna köra på 16.
Nu har jag bytt ut koden i interruptet till en lite trevligare:
Onödigt att hålla på å mekka i OCR1-registret när man kan lösa det enklare. Nu ska jag lämna klockan på över natten för att se hur mycket den drar sig på 8-10 timmar.
Nu har jag bytt ut koden i interruptet till en lite trevligare:
Kod: Markera allt
if (!(timer%2)) TCNT1++;