Forum: Mikrocontroller und Digitale Elektronik Genau Jede Sekunde Hochzählen..


von Stefan (Gast)


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?

von Naja (Gast)


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.

von spess53 (Gast)


Lesenswert?

Hi

Uhrenquarz an TOSC1/2. Timer2 erzeugt dann mit Vorteiler 128 genau jede 
Sekunde eine Overflowinterrupt. Fertig.

MfG Spess

von Denny S. (nightstorm99)


Lesenswert?

spess53 schrieb:
> Hi
>
> Uhrenquarz an TOSC1/2. Timer2 erzeugt dann mit Vorteiler 128 genau jede
> Sekunde eine Overflowinterrupt. Fertig.
>
> MfG Spess

Genau, das steht in der Hilfe von Bascom unter Timer2 genau drin.


Gruß

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.

von Peter D. (peda)


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

von overseer (Gast)


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

von Jürgen C (Gast)


Lesenswert?

Hallo,
schau mal in der Bascom-Hilfe unter "CONFIG CLOCK"

von Brigitte (Gast)


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.

von Brigitte (Gast)


Lesenswert?

Hi,

du kannst auch dein waitms=1000 um ~7% vermindern und anpassen.

Waitus = .... wäre auch möglich.

B.

von STK500-Besitzer (Gast)


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.

von Karl H. (kbuchegg)


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.

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.