Exakt tidtagning, Atmega16, 32,768-kristall

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7471
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg av Marta »

Skall det vara för tidtagning så är nog det enklaste att multiplicera med en kalibreringskonstant i samband med visningen. En vanlig skräpkristall försedd med värmare som håller den på konstant temperatur borde klara 10ppm stabilitet utan större svårighet. I varje fall sedan den blivit "inkörd".
silop
Inlägg: 2
Blev medlem: 26 mars 2006, 22:44:43
Ort: Hökerum

Inlägg av silop »

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
}
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Programmet må använda rätt interruptinställningar, men du kommer inte ifrån att din kristall som ska vara på 14,74560 MHz inte går exakt i den frekvensen. Frekvensen varierar +-50 Hz / MHz enligt tidigare inlägg.
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

Nu har jag gjort så här:

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

}
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.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Varför inte använda en kristall med ett trevligare frekvensvärde, t ex en på 14,74560 MHz, som silop tipsade om? Då går divisionerna jämnt ut när du ska räkna ut vilka värden du ska ladda.
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

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:

Kod: Markera allt

if (!(timer%2))	TCNT1++;
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.
Skriv svar