Genau Jede Sekunde Hochzählen..

Gast #1491334
Lesenswert?

dieses Thema gab es bestimtm schon 1million mal, aber ich finde einfach 
kein lösung.

Ich will eine einfache Uhr mit ein Atmega8 Bauen, mein Programm sieht so 
aus:

$regfile "m8def.dat"
$crystal = 1000000
$baud = 1200
Dim Stunde As Word
Dim Minute As Word
Dim Sekunde As Word
Sekunde = 0
Minute = 0
Stunde = 0
Schleife:
Print Stunde ; ":" ; Minute ; ":" ; Sekunde
Sekunde = Sekunde + 1
Waitms 1000
If Sekunde = 60 Then
Minute = Minute + 1
Sekunde = 0
End If
If Minute = 60 Then
Stunde = Stunde + 1
Minute = 0
End If
If Stunde = 24 Then
Stunde = 0
End If
Goto Schleife

da ich den Internen Quarz benutze geht due Uhr sehr schnell sehr 
falsch^^ ( nach 5 Minuten echtzeit sagt der Chip es sind ca. 4 minuten 
40sekunden vergangen )


wie bekomme ich das ganz genau hin? ich habe hier viele beispiele 
gefunden aber keins in basic und wenn ich das richtig gelesen habe 
benötige ich ein externen quarz, habe hier 4 und 16mhz quarz liegen 
welscher eignet sich besse rund wie schließe ich den an?
Gast #1491341
Lesenswert?

>dieses Thema gab es bestimtm schon 1million mal, aber ich finde einfach
>kein lösung.

Dann suche bitte nochmal und diesmal gründlich.
Und das nächste Mal tue uns bitte den Gefallen und achte auf 
Rechtschreibung.
Moderator (Firma: Titel) Persönliche Seite #1491368
Lesenswert?

> da ich den Internen Quarz benutze
Lies das noch mal nach...
Es gibt keinen internen "Quarz"   :-/
Der interne "Taktgenerator" ist ein ziemlich ungenauer RC-Oszillator. 
Den nimmt man, wenn man irgendeinen Takt braucht. Für alle genaueren 
Anforderungen (RS232 oder Zeiten) bruchst du wirklich einen Quarz oder 
aufwendige Kalibrrermöglichkeiten.
#1491372
Lesenswert?

Stefan schrieb:
> da ich den Internen Quarz benutze

Gibbet nich, is nur ein RC-Generator.

> wenn ich das richtig gelesen habe
> benötige ich ein externen quarz,

Jau, dat stimmt.

> habe hier 4 und 16mhz quarz liegen
> welscher eignet sich besse r

Is wurscht, kannst beide nehmen. Am stabilsten im Full-Swing-Modus.

> und wie schließe ich den an?

Wie im Datenblatt beschrieben.


Peter
Gast #1491627
Lesenswert?

1
volatile int sek=0;
2
volatile int min=0;
3
volatile int hou=0;
4
volatile int out[16];
5

6

7
main()
8
  {
9
  lcd_portinit();
10
  lcd_pwrup();
11
  
12
  
13
  TCCR1A  = 0x00;
14
  TCCR1B   = 0x03;    //prescaler 64 
15
  TIMSK   = 1<<OCIE1A;    //output compare match interrupt enable
16
  OCR1A  = 62497;    //zaehlgrenze bei 4mhz 1sec
17
  
18
  sei();
19
  for(;;)
20
    {
21
    sprintf(out,"%02d:%02d:%02d           ",hou,min,sek);
22
      lcd_sendstring(out);
23
      lcd_choporder(0x02);
24
    }
25

26
  }
27

28
ISR(TIMER1_COMPA_vect)
29
{
30
TCNT1=0;
31
sek++;
32

33
if(sek==60)   {sek=0;min++;}
34
if(min==60)   {min=0;hou++;}
35
if(hou==24)    {hou=0;}
36
}

bitte sehr...funktioniert bei mir einwandfrei
statt einem overflow interrupt habe ich mich für einen compare interrupt 
entschieden. das hat den vorteil das man den beliebig verändern kann und 
somit etwaige ungenauigkeiten im quarz ausgleichen kann...
das programm hier muss mit ~4mhz glaube ich betrieben werden. dann 
bekommst du sekündlich einen interrupt

die lcd_**** musst du löschen hab sie nur der vollständigkeitshalber 
drin gelassen
Gast #1491691
Lesenswert?

Hi,

es geht auch mit dem internen Takt.

Wenn dieser "1MHz! beträgt und die Uhr 5 min nach 4:40 anzeigt werden 
300 Sekunden in 280Sekunden durchlaufen. also ist der Interne Takt 
300/280 = 1,0714 also 7,14% zu schnell.

Gib statt $crystal = 1000000 dann $crystal = 1000000/1,0714 bzw. 
$crystal = 933358 an

Ggf. weiter korrigieren.

B.
Gast #1491695
Lesenswert?

>es geht auch mit dem internen Takt.

>Wenn dieser "1MHz! beträgt und die Uhr 5 min nach 4:40 anzeigt werden
>300 Sekunden in 280Sekunden durchlaufen. also ist der Interne Takt
>300/280 = 1,0714 also 7,14% zu schnell.

Und dann wundert man sich, dass die Uhr im Winter anders läuft als im 
Sommer.
Wenn man in Toleranzgrenzen etwas genaues als Endprodukt haben will, 
dann müssen die darunter liegenden Toleranzen kleiner sein, da sie sich 
aufsummieren.
Einen RC-Oszillator für den Betrieb einer Uhr zu benutzen ist die 
schlechteste Wahl und ein Quarz kostet auch keine Millionen.
#1492654
Lesenswert?

overseer schrieb:
>
1
> ISR(TIMER1_COMPA_vect)
2
> {
3
> TCNT1=0;
4
> 
5
>
>
> bitte sehr...funktioniert bei mir einwandfrei

Fragt sich nur wie lange :-)
Lass den Timer in Ruhe zählen und fummle nicht am Counter Register rum!

> statt einem overflow interrupt habe ich mich für einen compare interrupt
> entschieden.

Der CTC ist besser geeignet.
Zur Erinnerung: Man will haben, dass der Timer in Ruhe und vor allen 
Dingen gleichmässig ticken kann. Jede Störung, die du am TCNTx Register 
durch dein Programm einbringst führt letztendlich nur dazu, dass er das 
nicht kann und deine Uhr auf lange Sicht gesehen falsch geht.

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