Forum: Mikrocontroller und Digitale Elektronik Atmega 8 Sekundentimer in C


von Bambie (Gast)


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
}

von avr (Gast)


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

von Bambie (Gast)


Lesenswert?

Ahh, ok, jetzt ist es genau. Man sollte vielleicht selber nachrechnen... 
Hatte das Tool rnAVR benutzt. Dann kann ja ja jetzt weiter basteln :) 
Ich danke dir für deine schnelle Antwort.

MFG Bambie

von Sebastian Neuhuber (Gast)


Lesenswert?

cool kan microcontroller zwar nich in c programieren aber C#
und ich finde es interesant das die sprachen sich so aehneln

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.