Hallo zusammen,
ich arbeite aktuell an einer Art Uhr, vielmehr möchte ich dazu auch noch nicht verraten. Jedenfalls läuft mein AVR (mega16) mit internem Taktgeber auf 8 MHz und der Timer ist so eingestellt, dass er alle 0,25 Sekunden überlaufen soll. Ich habe aber bereits nach einer Minute eine Abweichung von etwa 2-3 Sekunden. Ist der interne Taktgeber tatsächlich so ungenau, oder habe ich irgendwo einen Denkfehler im Code?
C
#define F_CPU 8000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdbool.h>
#include "light_ws2812.h"
volatile uint8_t quarter_sec=0;
volatile bool refresh=0;
struct CRGB { uint8_t g; uint8_t r; uint8_t b; };
volatile struct CRGB led[60];
// timer1 overflow 0.25 seconds
ISR(TIMER1_OVF_vect) {
TCNT1 = 34286;
quarter_sec++;
refresh=1;
}
int main(void)
{
uint8_t sec=0;
uint8_t min=0;
uint8_t hour=0;
DDRB |= _BV(PB0); // PB0 as output
// timer1 overflow 0.25 seconds
TCCR1B |= (1<<CS11) | (1<<CS10);
TIMSK |= ( 1 << TOIE1);
TCNT1 = 34286;
sei();
while(1)
{
// increase seconds after four timerticks
if(quarter_sec>3) { sec++; quarter_sec=0; }
// we have only 60 seconds per minute (0-59)
if(sec>=60) { sec=0; min++; }
// we have only 60 minutes per hour (0-59)
if(min>=60) { min=0; hour++; }
// we have only 24 hours per day (0-23)
if(hour>=24) { hour=0; }
...
}
}
Alles anzeigen
In der späteren Anwendung soll natürlich nicht der interne Zeitgeber verwendet werden sondern ein Quarz. Außerdem überlege ich noch ob ich ihm eine RTC an die Seite stelle oder gar DCF77 so dass man garnichts mehr von Hand stellen muss.
Gruß und guten Rutsch
Dominique