Einstellung von Timer1 von ATMEGA32

Gast #3897738
Lesenswert?

hey,


Habe ein ATMEGA32 mit einer internen Frequenz von 1MHz für eine Uhr


Wollte mal fragen op den Timer1 so richtig eingestellt ist für genau 
1Sekunde ?

1
#define F_CPU 1000000UL    
2
#include <util/delay.h>    
3
#include <avr/interrupt.h>
4
#include <avr/io.h>
5

6

7

8
unsigned char Stunden = 0;
9
unsigned char Minuten = 0;
10
unsigned char Sekunden = 0;
11

12

13
int main() {
14
  
15
    
16
  TCCR1B = (1<<CS12|1<<WGM12);
17
  OCR1A = 3906,25-1;
18
  TIMSK1 = 1<<OCIE1A;
19
  sei();
20
  
21

22
  while(1)
23
  {
24

25
  }
26
  
27
  return 0;
28
  
29
}
30

31

32
ISR(TIMER1_COMPA_vect)
33
{
34
  Sekunden++;
35
  
36
  if(Sekunden == 60)
37
  {
38
    Sekunden = 0;
39
    Minuten++;
40
  }
41
  if(Minuten == 60)
42
  {
43
    Minuten = 0;
44
    Stunden++;
45
  }
46
  if(Stunden > 23)
47
  Stunden = 0;
48
  
49
}



Danke für Ihre Hilfe
#3897746
Lesenswert?

Was immer du hier auch machen wolltest
1
  OCR1A = 3906,25-1;
hier passiert ganz sicher nicht das, was du vor hattest.

Interpretiere ich das , mal als fehlgeleitetes Dezimalkomma (in 
Programmierpsrachen verwendet man einen Dezimalpunkt und kein Komma), 
dann bleibt immer noch, dass OCR1A nur ganze Zahlen aufnehmen kann.
Der Timer zählt in ganzen Schritten. Wie soll der auf komma 25 
vergleichen?
#3897759
Lesenswert?

Jorge schrieb:

> unsigned char Stunden = 0;
> unsigned char Minuten = 0;
> unsigned char Sekunden = 0;

Die Variablen hier werden volatile werden müssen, wenn du in der 
Hauptschleife dann mit der Uhrzeit auch was anfangen willst.

> Wollte mal fragen op den Timer1 so richtig eingestellt ist für genau
> 1Sekunde ?


Die Frage kannst du dir im übrigen auch realtiv leicht fürs erste selbst 
beantworten. Häng an einen Pin eine LED an und lass dir die Sekunden auf 
diese LED ausgeben (das unterste Bit). Wenn alles stimmt, dann musst du 
dort deine Sekunden wiederfinden. Blinkt es nach Augenmass zu schnell 
oder zu langsam, dann ist was gröber faul. Wenn es gefühlsmässig 
hinkommt, kannst du ja mal 60 oder mehr LED Blinker abzählen und 
gleichzeitig eine andere Uhr nebenher laufen lassen. Dauern 60 derartige 
BLinker dann tatsächliche 120 Sekunden (plus minus), dann bist du gut 
dabei.

So richtig genau wird das sowieso nicht, denn der interne Takt ist nicht 
genau 1000000.0000000 Hz sondern weicht davon oft nicht unerheblich ab.
Das soll dich aber erst mal nicht verdriessen.
Das Motto lautet: Hilf dir selbst, dann hilft dir Gott. Nur, wie helfe 
ich mir selbst?
Und genau da kommt das allereinfachste Hilfsmittel ins Spiel: eine LED 
an einem Portpin. Man soll es gar nicht für möglich halten, welche 
INformation man aus dem Programm mit einere simplen LED nach aussen 
tgransportieren kann.
#3897761
Lesenswert?

Jorge schrieb:
> Wie ist denn die richtige Methode ?

Welchen Teil von 'nur ganze Zahlen' hast du nicht verstanden?

Es gibt nun mal nur ganze Postkästen an der Wand. Wie willst du 268.25 
Postkästen an der Wand abzählen? Entweder 268 oder 269. Aber 268.25 
Postkästen existieren nicht.

(Genausowenig wie es 365.25 Tage im Jahr gibt. Ein Jahr hat entweder 365 
oder 366 Tage. Aber keine 365.25)
#3897785
Lesenswert?

Marc Vesely schrieb:
> holger schrieb:
>>>  OCR1A = 3906,25-1;
>>
>> Spätestens bei dem Komma pisst dich der Compiler an.
>
>  Hmmm.
>  Vielleicht bei C++.

Auch nicht.

>  Aber die Idee an und für sich ist gar nicht so schlecht.

Zugegeben: auf den ersten Blick naheliegend. Auf den zweiten Blick 
allerdings zeigt sich, dass der Fragesteller nicht verstanden hat, wie 
ein Timer arbeitet.
Gast #3897800
Lesenswert?

So mache ich das:
1
// INFO: F_CPU  3686411UL -> Compiler Option!!!!
2

3
// Sekundentakt
4
ISR(TIMER1_COMPA_vect)
5
{
6
    if ( systick )
7
        systick++;
8

9
    if ( TimeOut )
10
        TimeOut--;  
11
}
12

13
void Init_Timer(void)
14
{
15
  
16

17
// This is the central clock with 1 Hz 
18
  TCCR1B = PRESCALER1 | (1 << WGM12);// Prescaler 1024 and CTC Mode
19
  TCNT1 = 0;        // Set to zero
20
  OCR1A = (F_CPU/1024);   // calculate the 1 second value = 3600
21

22
    sei();
23
}

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