Atmega 8 Sekundentimer in C

Gast #1367661
Lesenswert?

Abend zusammen,
ich habe mal wieder mein Experimentierboard rausgekrammt und wollte 
einen kleinen Timer entwickeln. Zuerst aber nur einen Sekundentimer, der 
eine LED blinken lassen soll. Blinken tut die LED auch, leider geht sie 
schon nach einer Minute um knapp 3 Sekunden falsch. Das ganze ist auf 
einen Steckbrett aufgebaut. Als Taktgeber dient ein 8MHZ-Quarz, der mit 
2 22pf Kondensatoren gegen GND geschaltet ist. Als Stromquelle dient ein 
USBasp-Nachbau. Ich hoffe ihr könnt mit ein weniger weiterhelfen, mit 
der Suche und über Google habe ich leider nichts gefunden :(

MFG Bambie
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/sleep.h>
4
#include <inttypes.h>
5
#include <util/delay.h>
6
#include <stdlib.h>
7

8
//volatile unsigned int  sekunden = 0;
9
//volatile unsigned int  minuten = 0;
10
//volatile unsigned long  stunden = 0;
11
static unsigned int sekunden = 0;
12

13
// Starten des Timers, nachdem er in der Hauptschleife konfiguriert wurde
14
uint8_t timer_start(void)
15
  {
16
    TIMSK = (1<<OCIE1A);   //Interrupt bei Compare Match
17
    sei();            //Interrputs aktivieren
18
    return 0;
19
  }
20
  
21
uint8_t timer_stop(void)
22
{
23
    TIMSK = (0<<OCIE1A);   //Interrupt bei Compare Match ausschalten
24
    return 0;
25
  }
26
  
27
ISR(TIMER1_COMPA_vect){
28
  sekunden++;
29
  PORTB ^= ( 1 << PB0 );
30
  }
31
  
32
int timer (void)
33
  {
34
  if(sekunden == 60)
35
    {
36
    minuten++;
37
    sekunden = 0;
38
    }
39
  if(minuten == 60)
40
    {
41
    stunden++;
42
    minuten = 0;
43
    }
44
  return 0;
45
  }
46

47
int main (void)
48
  {
49
  // Power-LED Einschalten
50
  DDRB = 0x01;
51
  PORTB = 1;
52

53
  //LED Einstellungen
54
  DDRC = 0xFF;
55
  PORTC = 0xFF;
56
  _delay_ms(1000);
57
  PORTC = 0x00;
58
  
59
  //16Bit-Timer für Zeitzählung
60
  TCCR1B |= (1 << WGM12);                //CTC Modus
61
  TCCR1B |= (1 << CS12) | (0 << CS11) | (0 << CS10);   //Prescaler 256
62
  OCR1A = 34286;                      //Compare Wert setzen
63
  timer_start();
64
  
65
  while(1) {
66
  }
67
  return 0;
68
}
Gast #1367677
Lesenswert?

Hallo Bambi,

das past schon.

Du zählst bis 34287 (0-34286) der Timer läuft mit 8000000/256.

Deine Zeit = 34287 * 256/8000000 = 1.0971 Sekunden.

Lass ihn mal bis 31250 zählen, also

OCR1A = 31249;

Dann ist nur noch die Quarzgenauigkeit zu messen.

Gruß avr

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren