Forum: Mikrocontroller und Digitale Elektronik Timer1 ( Bascom Uhr mit Alarm ) zu schnell


von Thomas Kiss (Gast)


Angehängte Dateien:

Lesenswert?

Mein Timer (Uhr ) läuft zu schnell....warum ?

Die Berechnung vom Timer1 sollte korrekt sein ( 1 Hz ) die Uhr macht 
aber in ca 6 Stunden 5 Min differenz..läuft also zu schnell ..Warum ?

( Bascom Anfänger ) Die Uhr mit Alarm, erfüllt aber alle gewünschte 
Funktionen....Habt ihr eine Idee ? Kann es sein daß die 16Mhz Quarz ein 
Montagsprodukt ist ?

Danke !!

: Verschoben durch User
von Anselm 6. (anselm68)


Lesenswert?

wenn ich mich nicht vertan habe, sind es 1,3% Abweichung.
Würde ich als "normal" ansehen.
Es gibt RTC-Bausteine die genau dies Problem nicht haben.

Gruß Anselm

von Horst H. (horha)


Lesenswert?

Hallo,


Anselm 68 schrieb:
> sind es 1,3% Abweichung.
> Würde ich als "normal" ansehen.

Das sind 1,3% sind 13000 ppm das ist doch recht übertrieben viel.

Reichelt Billigquarz 0,18 Euro:
1
Standardquarz im Gehäuse HC18/U.
2
3
• Frequenz: 16,0000 MHz
4
• Modus: Grundton
5
• Cl: 32 pF
6
• Rsmax: 20 Ohm
7
• Temperaturkoeffizient: ± 30 ppm
8
• Frequenztoleranz: ± 30 ppm
9
• Gehäuse: HC18/U

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr#Ganggenauigkeit 
sollte wohl das passende parat haben, um die Genauigkeit zu erhöhen.
CTC- Modus zum Beispiel.
Im Programm wird ja selbst der Timer1 gesetzt, theoretisch 16 ppm genau
16e6 /256/(65535-3036) = 1,000016 Hz.
Aber ein Interrupt in BASCOM dauert zum aufrufen und verlassen etwa 100 
Takte, da alle möglichen Register gerettet werden.
Also ehe der Timer1 Wert gesetzt wird sind schon mehr als 50 Takte 
vergangen.
Dann müsste aber die Uhr zu langsam gehen. Blödsinn: das sind 50/16e6 
etwa 3ppm, da kräht kein Hahn nach...

http://www.rn-wissen.de/index.php/Bascom_Debounce_ISR_in_Assembler
Hat auch eine Uhrenfunktionen 1/128 Sekunden Takt.

von Karl H. (kbuchegg)


Lesenswert?

Thomas Kiss schrieb:
> Mein Timer (Uhr ) läuft zu schnell....warum ?

Weil Timer vorladen nicht wirklich eine vernünftige Methode ist um Takte 
abzuzählen.
Schau in deiner BASCOM Doku nach, wie man den Timer im CTC Modus 
benutzt.

von Marcus B. (raketenfred)


Lesenswert?

die einfachste methode wäre, einfah die uhrzeit mit einem wert den du 
ausmisst- zu kalibrieren- z.b. die 59te minute pro stunde entfernen

von Peter D. (peda)


Lesenswert?

1,4% kann kein Quarzfehler sein.
Hast Du die Fuse CKOPT = 0 gesetzt?


Peter

von STK500-Besitzer (Gast)


Lesenswert?

>1,4% kann kein Quarzfehler sein.
>Hast Du die Fuse CKOPT = 0 gesetzt?

in einer Hochsprache den Timer nachladen, ohne die genaue Taktanzahl zu 
wissen, hat was mystisches...

von Peter D. (peda)


Lesenswert?

STK500-Besitzer schrieb:
> in einer Hochsprache den Timer nachladen, ohne die genaue Taktanzahl zu
> wissen, hat was mystisches...

Naja, vielleicht kann man in Bascom nicht so einfach nur die Formel 
hinschreiben und es den Präprozessor ausrechnen lassen, wie man es in C 
gewohnt ist.

Aber es haut schon genau hin:
(65536 - 3036) * 256 = 16e6

Ich hatte jedenfalls mal beim ATTiny26 die CKOPT vergessen und der Quarz 
ging ziemlich nachm Mond.


Peter

von Thomas Kiss (Gast)


Angehängte Dateien:

Lesenswert?

Die Bits sehen im Pony so aus, denke ist richtig....oder ?

von Thomas Kiss (Gast)


Lesenswert?

Nun habe ich meine Schaltung auf einen Steckbrett aufgebaut, mit einem 
anderen Quarz. Ich hatte in 8 Stunden ca 9 Minuten abweichung, zu 
schnell.

Der Atmega mit 16  Mhz, kann mit so einer Anwendung nicht am Limit sein.

Nun wäre meine Frage, wie kann ich einfach berechnen, welchen Vorteiler 
ich nehmen soll ( anstatt 3036 ) bevor ich Tagelang probieren muss...

Wäre zwar eine Bastellösung aber wichtig wäre, daß die Anwendung läuft.

Danke für Euren Tipps !!

von Horst H. (horha)


Lesenswert?

Hallo,

theoretisch müßte Deine Uhr recht genau sein.
Verzählst Du Dich bei den Sekunden?
Nach 59 statt 60 Sekunden um eine Minute zu erhöhen würde 1/60 = 1,66 % 
erklären.

von Thomas Kiss (Gast)


Lesenswert?

@Horst...

acha..spannend..hmm..naja wenn ich aber folgendes machen würde :

anstatt :

If Sekunde = 59 Then Minute = Minute + 1

sowas :

If Sekunde = 60 Then Minute = Minute + 1

dann erscheint im LCD Display bei Sekunden "60" dann springt auf 00 
Richtig wäre, wie jetzt, die Anzeige ist 58,59,00

von Horst H. (horha)


Lesenswert?

Hallo,

Statt
1
'---Berechnung der Uhrzeit
2
3
 If Sekunde = 59 Then Minute = Minute + 1
4
 If Sekunde = 59 Then Sekunde = 0
5
 If Minute > 59 Then Stunde = Stunde + 1
6
 If Minute > 59 Then Minute = 0
7
 If Stunde > 23 Then Stunde = 0
Nun:
1
'---Berechnung der Uhrzeit
2
  
3
 If Sekunde = 60 Then 
4
   Sekunde = 0
5
   Minute = Minute + 1
6
   IF Minute = 60 then
7
     Minute = 0
8
     Stunde = Stunde+1
9
     If Stunde > 23 Then 
10
       Stunde = 0
11
     end if ' Stunde korrigieren
12
   end if ' Minute korrigieren
13
 end if ' Sekunde korrigieren

Erst die Uhrzeit berechnen dann ausgeben, aber vielleicht machst Du das 
schon.

von Thomas Kiss (Gast)


Lesenswert?

Super, vielen Dank, werde probieren und gebe dann kurz Bescheid...

von Paul Baumann (Gast)


Lesenswert?

Die Takterzeugung ist so, wie Du sie hier machst in Ordnung. Ich habe
eine Uhr, die zwar mit 4 MHz-Quarz ausgeruestet ist, aber die 
Takterzeugung
mache ich genau so, wie Du hier. Diese Uhr ist so genau, dass ich nur 
zur Sommer/Winter-Zeitumstellung dran muss.

MfG Paul

von Thomas Kiss (Gast)


Lesenswert?

Noch ne Frage....es spielt schon eine Rolle, in welche Reihenfolge die 
Kommandos in der Do Loop Schleife stehen...

Do
...
...Berechnung
......
...Ausgabe
......
Loop


Oder

Do
.....
Berechnungen....
Berechnungen....
.....
Ausgabe....
Loop

Was meint Ihr ?

von Karl H. (kbuchegg)


Lesenswert?

Deine ganze 'Berechnung' - das Erhöhen der Uhr um 1 Sekunde, gehört in 
die Overflow-Interrupt Routine!
1
Takt:
2
 Timer1 = 3036
3
 Incr Sekunde
4
5
 If Sekunde = 60 Then 
6
   Sekunde = 0
7
   Minute = Minute + 1
8
   IF Minute = 60 then
9
     Minute = 0
10
     Stunde = Stunde+1
11
     If Stunde > 23 Then 
12
       Stunde = 0
13
     end if ' Stunde korrigieren
14
   end if ' Minute korrigieren
15
 end if ' Sekunde korrigieren
16
 
17
Return

Hier, an dieser Stelle "tickt" die Uhr. Dann lass sie hier vollständig 
ticken. Du hast Zeit genug dafür und die Interrupt Routine ist klein 
genug dafür. Lass dich nicht von der scheinbaren Code-Länge in BASCOM 
täuchen. Das alles übersetzt sich zu einer Handvoll Anweisungen, die in 
0 Komma Nichts abgearbeitet werden.

von STK500-Besitzer (Gast)


Lesenswert?

die zweite Variante ist besser.

von Thomas Kiss (Gast)


Lesenswert?

So etwa ?


'Config
Config Timer1 = Timer , Prescale = 256
   Enable Timer1
   On Timer1 Takt
   Enable Interrupts
   Timer1 = 3036

'Main
Do
.....
Loop

'SUB
Takt:
Timer1 = 3036
Incr Sekunde
If Sekunde = 59 Then
   Sekunde = 0
   Minute = Minute + 1
      If Minute = 60 Then
      Minute = 0
      Stunde = Stunde + 1
         If Stunde > 23 Then
         Stunde = 0
         End If
      End If
End If


Return

von Karl H. (kbuchegg)


Lesenswert?

Thomas Kiss schrieb:
> So etwa ?
>
>
> 'Config
> Config Timer1 = Timer , Prescale = 256
>    Enable Timer1
>    On Timer1 Takt
>    Enable Interrupts
>    Timer1 = 3036
>
> 'Main
> Do
> .....
> Loop
>
> 'SUB
> Takt:
> Timer1 = 3036
> Incr Sekunde
> If Sekunde = 59 Then

60

>    Sekunde = 0
>    Minute = Minute + 1
>       If Minute = 60 Then
>       Minute = 0
>       Stunde = Stunde + 1
>          If Stunde > 23 Then
>          Stunde = 0
>          End If
>       End If
> End If
>
>
> Return



Genau.

von Thomas Kiss (Gast)


Lesenswert?

Wenn soweit alles OK ist, soll ich Details von diesem kleinen Projekt 
machen ? Code, Hex, Layout, Platine, Foto vom Fertiggereät..oder 
interessiert niemand sowas "kleines" ?

von Karl H. (kbuchegg)


Lesenswert?

Mach ruhig.
Überleg dir aber vorher, wie du deine LCD-Ausgabe einfacher machen 
kannst. Das erscheint mir sehr, sehr umständlich

Warum funktioniert Code-technisch eigentlich das Einstellen der 
Normalzeit und das Einstellen der Alarmzeit völlig anders?

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:
> Mach ruhig.
> Überleg dir aber vorher, wie du deine LCD-Ausgabe einfacher machen
> kannst. Das erscheint mir sehr, sehr umständlich

Nehm ich zurück.
Das geht in BASCOM anscheinend nicht einfacher.
(wundert mich jetzt etwas)


Kannn man das in BASCOM so schreiben?
1
S1 = Str(sekunde)                                           'Uhr Stunde
2
S2 = Str(minute)                                            'Uhr Minute
3
S3 = Str(stunde)                                            'Uhr Sekunde
4
5
'----------- Anzeige Stunden , Minuten, Sekunden auf Display ------------------
6
7
Locate 1 , 1
8
Lcd "Uhr:    " ; Format(s3 , "00") ; ":" ; Format(s2 , "00") ; ":" ; Format(s1 , "00")                   'Stunde-Minute-Sekunden

von Thomas Kiss (Gast)


Lesenswert?

naja ich habe folgendes gedacht :

Im Display oben ist eine normale uhr..

unten rechts kann ich Stunden und Minuten einstellen ( nach 2 Stunden 30 
Min ) soll Alarm ausgegeben werden. Nun wir diese Zeit zur Uhrzeit 
dazugerechnet und erschein im Display unten Links....so etwa, klaro mann 
kann es optimieren, aber es funzt soweit so gut...

von Thomas Kiss (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Kannn man das in BASCOM so schreiben?
>
> S1 = Str(sekunde)                                           'Uhr Stunde
>
> S2 = Str(minute)                                            'Uhr Minute
>
> S3 = Str(stunde)                                            'Uhr Sekunde
>
>
>
> '----------- Anzeige Stunden , Minuten, Sekunden auf Display ------------------
>
>
>
> Locate 1 , 1
>
> Lcd "Uhr:    " ; Format(s3 , "00") ; ":" ; Format(s2 , "00") ; ":" ; Format(s1 , 
"00")

Vielleicht ich finde persönlich, daß meine Version übersichtlicher ist.

S1 = Str(sekunde)                                           'Uhr Stunde
S1 = Format(s1 , "00"

Lcd "Uhr:    " ; S3 ; ":" ; S2 ; ":" ; S1

von Karl H. (kbuchegg)


Lesenswert?

Thomas Kiss schrieb:
> naja ich habe folgendes gedacht :
>
> Im Display oben ist eine normale uhr..
>
> unten rechts kann ich Stunden und Minuten einstellen ( nach 2 Stunden 30
> Min ) soll Alarm ausgegeben werden. Nun wir diese Zeit zur Uhrzeit

das hab ich schon verstanden.
Aber deine Tastenabfragen für die normale Uhr und die Alarmzeit sind im 
Programm nicht gleich aufgebaut. Das eine geht über debounce, das andere 
geht über einen gedrückten Taster und eine künstliche Wartezeit.

> dazugerechnet und erschein im Display unten Links....so etwa, klaro mann
> kann es optimieren, aber es funzt soweit so gut...

Wenn du veröffentlichen willst, denk daran: Dein Code ist dein 
Aushängeschild. Der sollte schon auch etwas gleich schauen. Wer eine 
Vernisage macht, veröffentlicht auch nicht seinen Skizzenblock, sondern 
die sauber, nach den Regeln der Kunst aufgebauten Ölbilder.

von Thomas Kiss (Gast)


Lesenswert?

@Karl Heinz,

ach..jetzt ich weiss Du meinst..

Da ich noch Anfänger bin, habe erstmal die Einstellungen auf die 
"einfache" Art gemacht...Dann habe ich gesehen, daß man mit Debounce 
auch machen kann, so habe ich es auf eine Stelle eingebaut, nur zum 
testen...

Apropo dazu eine Frage, welche ist im Code eine bessere Lösung, mit 
Debounce zum Sub springen, evtl. mehrmals in der Do Loop Schleife, oder 
erledigen wir die Sachen in der Schleife, also mit Waits usw...?

von Oliver H. (Firma: OliverHeinrichs.de) (dobson)


Lesenswert?

Hat Bascom nicht mittlerweile die Uhr integriert? Die DCF77-Routine 
nutzt doch so was...
Vielleicht hilft dir das weiter:
http://heinrichs-oliver.net/bascom/funkuhr.bas
Wenn ich mich recht entsinne, kann man die Variablen auch manuell 
setzen.
Die sind _sec, _min und _hour
Bitte beachte, das das Programm so ein bis zwei Fehler in den Schleifen 
enthält, und noch einmal korrigiert werden muss.

von Thomas Kiss (Gast)


Lesenswert?

Ja die DCf Routine habe schon gesehen, aber eine "zu Fuss" Uhr Routine 
kenne ich nicht...

von Oliver H. (Firma: OliverHeinrichs.de) (dobson)


Lesenswert?

Die DCF77 Routine updatet dir ja nur deine Zeit (Time$), sobald ein 
gültiges Signal empfangen und decodiert wurde.
Sieh mal in der Hilfe unter Time$. Den kannst du manuell stellen. Dann 
ersparst du dir das ganze if sekunde = 60 then minute = minute + 1

von Thomas Kiss (Gast)


Lesenswert?

Nun habe ich folgendes probiert, leider ohne Erfolg ( Uhr läuft im 
Simulator nicht ) was ist falsch ?

   $sim
   $regfile = "m8def.dat"
   $crystal = 16000000
   $hwstack = 100
   $swstack = 100
   $framesize = 100


   $sim


Dim Sekundenzeiger As Long

Config Clock = User
Config Date = Dmy , Separator = .


   Config Timer1 = Timer , Prescale = 256
   Enable Timer1
   On Timer1 Takt
   Enable Interrupts
   Timer1 = 3035                                  'Timervorgabe für 
Sekunden Takt


Enable Timer1
Enable Interrupts

Time$ = "12:00:00"


'Hauptschleife
Do

Locate 1 , 1
Lcd Time$

Loop

End



Takt:
   Incr Sekundenzeiger
   Time$ = Time(sekundenzeiger)
   Timer1 = 3035

   Print Time$                                              'NUR FÜR 
BASCOM SIMULATOR

Return


Settime:
Return

Getdatetime:
Return

Setdate:
Return

von Horst H. (horha)


Lesenswert?

Hallo,

Eigentlich ist Deine Frage offtopic...
wenn Du time benutzt, betreibt Basccom automatisch die Uhr und belegt 
Timer0 oder 2 oder nicht?
Dein Sekundenzeiger ist das gleiche wie SecOfDay() von Bascom.
Im Simulator musst Du auch die Timer simulieren, also ein Häkchen dran 
machen.
Das dauert aber eine Ewigkeit 16 Mio Takte zu simulieren und dabei 
ständig eine Ausgabe zu machen noch mehr.
Ohne ständige Ausgabe und mit Idle
1
'Hauptschleife
2
Do
3
4
Locate 1 , 1
5
Lcd Time$
6
IDLE' Nicht ständig neu ausgeben , wenn sich nichts ändert
7
Loop
8
9
End
dauert die Simulation einer Sekunde bei mir im Simulator etwa 18 
Sekunden ( 2,9 Ghz )
Du solltest als Timerstartwert (am besten als Konstante Timervorgabe 
deklarieren ) etwas schnelleres wählen wie etwa ( 65535-1000) .
Ausserdem alle Ansichten wie Register/IO oder Memory abschalten.
Aber Time$ = Time(sekundenzeiger) etc brauchen ~3% vom Platz

von Horst H. (horha)


Angehängte Dateien:

Lesenswert?

Hallo,

ein kleines Testprogramm, um mal wie "damals" einen Uhrenstring direkt 
zu verarbeiten. Etwa 10x schneller als eine String 'hh:mm:ss' so zu 
erzeugen.
Zeit = time(SekundeDesTages)

von Thomas Kiss (Gast)


Angehängte Dateien:

Lesenswert?

In dieser Form läuft es perfekt..( bisher )
Klar es gibt immer eine bessere Lösung ( wenn man schon Profi ist !! )
Trotzdem super Danke an Alle

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.