Forum: Mikrocontroller und Digitale Elektronik Einstellung von Timer1 von ATMEGA32


von Jorge (Gast)


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

von holger (Gast)


Lesenswert?

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

Der interne Oscillator ist für eine Uhr nicht geeignet.

>  OCR1A = 3906,25-1;

Spätestens bei dem Komma pisst dich der Compiler an.

von Karl H. (kbuchegg)


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?

von Jorge (Gast)


Lesenswert?

Wie ist denn die richtige Methode ?

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von Karl H. (kbuchegg)


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)

von spess53 (Gast)


Lesenswert?

Hi

> Wie ist denn die richtige Methode ?

Nimm den Prescaler 64.

MfG Spess

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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

 Hmmm.
 Vielleicht bei C++.
 Das hier ist plain C, die Compiler sind da nicht so Hi-Tech.

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

von Karl H. (kbuchegg)


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.

von H.Joachim S. (crazyhorse)


Lesenswert?

Unabhängig von allen guten und richtigen Ratschlägen - es ist völlig 
sinnfrei, mit dem internen Oszillator eine Uhr bauen zu wollen. Selbst 
wenn es programmtechnisch richtig wäre - mir der ereichbaren Genauigkeit 
kommt man ein paar Jahrhunderte zu spät.

von OldMan (Gast)


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
}

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Karl Heinz schrieb:
>>  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.

 LOL.
 Ich sprach von anpissen, nicht von Timer.

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.