Hallo Leute!
Ich versuche eine Zeitschaltuhr zu bauen, dazu sollte unter anderem die
aktuelle Uhrzeit auf einem LC-Display angezeigt werden. Die Uhrzeit muss
nicht exakt sein, sie wird auch von hand eingestellt. Nun habe ich mit
der Formel
T = ((1/Fosc)*4)*PRESCALER*(2^16-x)
1 = ((1/16000000)*4)*64*(2^16-x)
für x=3036 ausgerechnet.
Mit diesem Wert habe ich aber auf 20 Sekunden bereits eine Verzögerung
von ca. einer Sekunde. Mit dieser Formel komme ich also nicht weiter :/
Ich habe auch anderen Prescaler mit dieser Formel versucht, ohne Erfolg.
Testweise habe ich für x = 8000 versucht, hierbei habe ich schon einen
genaueren Takt bekommen. Nach ca 5 Minuten habe ich aber auch schon
einen Unterschied feststellen können. Nach 17 Minuten sind es ca. 2
Sekunden Unterschied.
Messen kann ich den Zeitunterschied nur mit meiner Handy-Stoppuhr nach
Gefühl.
Ich verwende einen PIC18F26k22 und dessen interner 16MHz Oszillator mit
PLL (4x).
Hier ist meine Software, etwas redzuiert
Woran kann es liegen, dass mein Sekundentakt nicht hinhaut?
Ich hoffe ihr könnt mir helfen :)
Weiters wünsche ich noch jedem Leser frohe Ostern!
LG Markus
Markus B. schrieb:> Woran kann es liegen, dass mein Sekundentakt nicht hinhaut?
Davon abgesehen, dass der interne Oszillator sehr ungenau ist,
wäre es viel einfacher und besser einen Timer zu verwenden, der
automatisch so weit zählt wie nötig. Ohne dass man diesen "reloaden"
muss.
Schau mal da:
http://www.hs-ulm.de/users/vschilli/Mikrocontroller/uCQ/_downloads/uCquick-X.pdf
(5.1 und 5.2)
<edit>Die Berechnug des Reload-Wertes wäre in 4.4.2, macht aber keinen
Sinn.
Beitrag "Mit Batterie gepufferte Uhr für Steuerung."
Im ersten Projekt (PIC18...) findest du wie man Zeit Flanken im
Interrupt erzeugt. Im zweitem Projekt arbeitet PIC12... mit dem Quarz
32768 kHz und Interrupt 1 Sek. , sonst mit internem Oszillator. Das
„schlafen gehen“ (sleep) muss nicht sein.
@ Markus B
Ich sehe das so:
Grundsaetzlich soll man fosc nur so hoch wie unbedingt erforderlich
waehlen. Man erspart sich so Klimmzuege.
Mit fosc/4=16MHz kannst Du mit dem TMR0 im 8Bit-Mode und dem Vorteiler
256 ohne zusaetzlichen Aufwand, nicht viel ausrichten.
Mein Vorschlag (wenn es schon fosc/4=16Mhz sein muss):
fosc: 16.000.000Hz
PLL: fosc * 4 =64.000.000 Hz
working Cycles/s = Fosc*PLL/4 =16.000.000
Ein TMR0-Overflow-Interrupt kann nur sinnvoll verwendet werden, wenn der
TMR0 in den 16Bit-Modus versetzt wird (siehe oben).
TMR0 16Bit-Mode: Set T0CON,T08BIT (Bit 6) = 1
counts 0 - 65535 (65536 clocks) (TMR0H:TMR0L)
Sinnvoll waere z.B der Overflow-Interrupt alle 5ms. Bei jedem
TMR0-Overflow wird sodann ein Zaehler incrementiert.
Bei Zaehlerstand = 200 ist 1s verstrichen.
Nebenbei kann der Interrupt auch noch fuer 1/10s oder auch zum
Entprellen von Tasten nuetzlich sein.
Bei der Verwendung des Vorteilers :2 muss der Interrupt bei
Zaehlerueberlauf 80.000 / 2 = 40.000 erfolgen.
Dazu muss der Zaehler nach jedem Ueberlauf auf Preset =
65.536 - 40.000 = 25.536 gesetzt werden (TMR0H:TMR0L).
Lies doch einfach mal das Datenblatt Abschnitt
"11.0 TIMER0 MODULE"
FIGURE 11-2: TIMER0 BLOCK DIAGRAM (16-BIT MODE)
mfG Ottmar
mfG Ottmar
Laut Mplabx Simulator haut dein Programm so hin. Nur 1/100000
Abweichung.
(Das Stopwatch Window des Simulators zeigt die abgelaufene Zeit zwischen
den Breakpoints an).
Breakpoint auf "TMR0IF=0;"
Stopwatch cycle count = 4000048 (1,000012 s)
Breakpoint auf "systemTime.sec = 0;"
Stopwatch cycle count = 240002887 (60,000722 s)
Unmittelbar vorm "WriteTimer0" ist TMR0L immer noch 0 -- haut auch hin.
Würde ich mir erst mal den internen Oszillator genauer anschauen.
Den internen Oszillator kannst du ruhig verwenden.
Bei den PIC18F.. sind die ab Werk her schon auf 1% genau geeicht.
Genaueres steht im Datenblatt !
Das reicht schon für eine sehr genaue Uhr.
Meine Uhren laufen auch mit dem internen Oszillator und haben gerade mal
ein paar Sekunden Abweichung im Monat, wenn nicht sogar weniger.
Die Abweichung kannst du auch über längere Zeit ermitteln und dann per
Software kompensieren !
Ist nicht schwer...
Was auch noch einen Einfluss hat, ist die Temperaturstabilität des
Oszis.
Finger auf das Gehäuse legen sorgt meist schon für einen ziemlich
krassen Drift.
Wenn du aber eh Netzspannung an deiner Schaltung hast
(Zeitschaltuhr...?), könntest du auch die Netzfrequenz mitzählen. Hier
hat mal einer behauptet, die sei langfristig auf 1 ppm genau.
Und sonst Korrekturtaster und basta :)
Norbert S. schrieb:> Bei den PIC18F.. sind die ab Werk her schon auf 1% genau geeicht.> Genaueres steht im Datenblatt !> Das reicht schon für eine sehr genaue Uhr.
Geeicht?
1% ist für eine Uhr lächerlich. In 100s (also 1min40s) bis zu 1 Sekunde
Abweichung. In einer Stunde dann 36 Sekunden. Am Tag 14,4 Minuten...
(Hoffentlich habe ich mich nicht verrechnet ;-)
Norbert S. schrieb:> Meine Uhren laufen auch mit dem internen Oszillator und haben gerade mal> ein paar Sekunden Abweichung im Monat, wenn nicht sogar weniger.
Die Temperatur ist wohl recht stabil?
Norbert S. schrieb:> Die Abweichung kannst du auch über längere Zeit ermitteln und dann per> Software kompensieren !> Ist nicht schwer...
Wenn die Abweichung konstant ist...
Sowie den TIMER0 teil auskommentiert.
Im Anhang die komplette main.c :)
Ich mache dann weiter mit den weiteren Vorschlägen!
Vielen Dank und noch einen schönen Ostermontag :)
LG Markus
Edit: CCP1COUNT habe ich wie folgt berechnet:
0,01 = (1/16000000)*8*x -> x=20000
Markus B. schrieb:> Das habe ich nun so probiert, auf 40sek ist mein Programm eine Sekunde> schneller.
Dann ist wohl der interne Oszillator um 2,5% schneller und du musst
dementsprechend für CC1COUNT 20500 nehmen.
Volker S. schrieb:> Markus B. schrieb:>> Das habe ich nun so probiert, auf 40sek ist mein Programm eine Sekunde>> schneller.>> Dann ist wohl der interne Oszillator um 2,5% schneller und du musst> dementsprechend für CC1COUNT 20500 nehmen.
Also ich plaediere ja immer noch fuer die Loesung mit einem
32.768kHz-Oszillator.Hat halt den Vorteil,dass man beliebige PICs
einsetzen kann ohne gleich wieder kalibieren zu muessen....
Toxic schrieb:> Also ich plaediere ja immer noch fuer die Loesung mit einem> 32.768kHz-Oszillator.Hat halt den Vorteil,dass man beliebige PICs> einsetzen kann ohne gleich wieder kalibieren zu muessen....
Ja, das sollte auch stabiler bei Temperaturänderungen sein.
Hallo,
nachdem ich leider den sekundären Oszillator nicht nutzen kann, da ich
diese Pins (SOSCI, SOSCO) bereits anderwertig in verwendung habe, bleibt
mir nur noch der Weg über eine Anpassung des CCP1COUNT wertes. Schade,
hatte mehr Vertrauen in den internen Oszillator gesteckt.
Vielen Dank für die Hilfe! :)
LG Markus
Markus B. schrieb:> Schade, hatte mehr Vertrauen in den internen Oszillator gesteckt.
Selbst 1% Genauigkeit wäre für eine Uhr bei weitem nicht ausreichend.
2,5% widerspricht aber sogar den Spezifikationen hinten im Datenblatt.
(Da steht +-2%)
Markus B. schrieb:> nachdem ich leider den sekundären Oszillator nicht nutzen kann
Und was ist mit dem primären Oszillator? Sind RA6/RA7 auch schon
entgültig vergeben, oder kannst du sie für einen externen Quarz frei
machen.
Einzig die Pins RB5 und RB2 sind noch frei, wobei RB2 noch für einen
Näherungssensor vorgesehen ist, der hätte allerdings den INT2
draufgeschalten der sich ja auch durchaus eignen würde denke ich :)
nachdem die Platine schon geätzt ist werde ich erstmal die manuelle
kalibrierung versuchen. Der Epson IC ist aber ein guter Tipp, wenn es zu
einer neuen Version kommt bei ich den ein!
Markus B. schrieb:> Der Epson IC ist aber ein guter Tipp, wenn es zu> einer neuen Version kommt bei ich den ein!
Hmm - wäre es bei einer evtl. neuen Version nicht geschickter, einen
Quarz am Microcontroller selbst vorzusehen? Notfalls (wenn wirklich alle
Pins für I/Os verplant sind) halt einen Controller mit ein paar Pins
mehr...
Noch eine kleine Ergänzung:
Der Timer Pre-Load Wert sollte immer in der ersten Zeile der IRQ Routine
gesetzt werden. Dann hat der Rest innerhalb der IRQ Routine keinen
Einfluss mehr auf die Zyklus-Zeit;if-Abfragen brauchen mal mehr mal
weniger Zeit...
Den Timer Preload braucht man nicht, wenn man den Timer so wie schon
geschehen mit einem CCP Modul kombiniert.
Nur wenn das nicht möglich ist, sollte man IMO keinen Wert laden,
sondern addieren. Dann ist es relativ egal, zu welchem Zeitpunkt dies
geschieht.
Markus B. schrieb:> da ich> diese Pins (SOSCI, SOSCO) bereits anderwertig in verwendung habe,
Kannst du vielleicht die Pins kurzzeitig für eine Kalibrierroutine frei
machen? Oder OSCTUNE des PICs bzw. den CCP1COUNT Kalibrierwert mit einem
Uhrenquarz vor dem Einsetzen in die Schaltung in einem Sockel in einer
separaten Schaltung kalibrieren?
Vielleicht hilft folgende App Note:
http://ww1.microchip.com/downloads/en/AppNotes/00244a.pdf
Ausserdem sollte
#define CCP1COUNT 19999
definiert werden. Timer wird nämlich beim nächsten Clock Event nach dem
CCP1 Event genullt. Wenn du CCPR1 auf 20000 definierst, hat die CCP
Periode 20001 Timer-Takte.