-
Also die Ungenauigkeit des Taktes sollte für dich nicht wahrnehmbar sein - das bewegt sich im Bereich der ppm.
Ich vermute eher, dass der nicht richtig schlafen geht oder sowas.
Und verlege mal die ganze Rechnerei vom INT in die Main-Loop!
Im INT nur noch ein Flag setzen und das dann in der Main abfragen.
Wenns gesetzt ist einmal rechnen, shiften, schlafen.
-
Also momentan schläft er gar nicht weils ichs noch auskommentiert habe nach deinem Ratschlag.
Ich verlege das ganze dann wie du sagst in die Main Loop und dann sehen wir weiter aber erstmal werd ich jetzt pause machen und die uhr einfach nen paar stündchen laufen lassen und die abweichung checken.
Ich danke euch ganz herzlich für die hilfe und im besonderen Stefan_z der mir jetzt die letzten Denkanstösse gegeben hat!
-
Dim sek_flag as bit
ISR:
Set sek_flag
Return
Main:
If sek_flag = 1 then
<Rechnerei>
else
Sleep
end if
-
Hab ich eingebaut allerdings noch ohne Sleep. Die Led spinnt trotzdem irgendwie. In unregelmäßigen Abständen Toggelt die Led nicht. Ich kann da kein System hinter feststellen. Es passiert einfach nicht immer.
Woran kann das noch liegen? Naja ich teste jetzt mal wieder die genauigkeit der Uhr. Ich hatte noch einen fehler in der Software, sodass die Sekundenvariable nicht von 0 bis 59 gezählt hat sondern von 1 bis 59 und somit immer eine Sekunde zuwenig pro Minute gezählt wurde.
Hier der Übersichtlichkeit halber nochmal der neue Code:
Code:
$regfile = "m8def.dat"
$crystal = 8000000
'Ports einstellen
Config Portb.0 = Output 'SRData
Config Portb.3 = Output 'PWM
Config Portd.7 = Output 'SCK
Config Portd.6 = Output 'RCK
Config Portd.5 = Output 'Reset
Config Portd.2 = Output 'LED
Config Pinc.3 = Input 'Taster1
Config Pinc.4 = Input 'Taster2
Config Pinc.5 = Input 'Taster3
'Alias definieren
Rck Alias Portd.6
Sck Alias Portd.7
Datasr Alias Portb.0
Resetsr Alias Portd.5
Led Alias Portd.2
Pwm Alias Portb.3
Taster1 Alias Pinc.3
Taster2 Alias Pinc.4
Taster3 Alias Pinc.5
'Portpegel setzen
Rck = 0
Sck = 0
Datasr = 0
Resetsr = 1
Led = 0
Pwm = 1
Taster1 = 1
Taster2 = 1
Taster3 = 1
'Timer konfigurieren
Config Timer1 = Timer , Prescale = 256
Enable Timer1
On Timer1 Sekundentakt
Enable Interrupts
Timer1 = 34285
'Config Timer2 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 1
'Variablen definieren
Dim Sek_flag As Bit
Dim Sekunden As Integer
Dim Minuten As Byte
Dim Stunden As Byte
Sekunden = 0
Minuten = 0
Stunden = 12
'Bitmuster erstellen und Array befüllen
Dim Stundenarray(12) As Word
Dim Minutenarray(12) As Byte
Dim I As Byte
Dim Stdpos As Byte
Dim Minpos As Byte
Minutenarray(1) = &B00000000 'Voll
Minutenarray(2) = &B10000001 'Fünf nach
Minutenarray(3) = &B10000010 'Zehn nach
Minutenarray(4) = &B00010001 'Viertel nach
Minutenarray(5) = &B00100110 'Zehn vor Halb
Minutenarray(6) = &B00100101 'Fünf vor Halb
Minutenarray(7) = &B00100000 'Halb
Minutenarray(8) = &B00101001 'Fünf nach Halb
Minutenarray(9) = &B00101010 'Zehn nach Halb
Minutenarray(10) = &B01010000 'Viertel vor
Minutenarray(11) = &B01000010 'Zehn vor
Minutenarray(12) = &B01000001 'Fünf vor
Stundenarray(1) = &B0000000100000000 'Eins
Stundenarray(2) = &B0000001000000000 'Zwei
Stundenarray(3) = &B0000010000000000 'Drei
Stundenarray(4) = &B0000100000000000 'Vier
Stundenarray(5) = &B0001000000000000 'Fünf
Stundenarray(6) = &B0010000000000000 'Sechs
Stundenarray(7) = &B0100000000000000 'Sieben
Stundenarray(8) = &B1000000000000000 'Acht
Stundenarray(9) = &B0000000000010000 'Neun
Stundenarray(10) = &B0000000000100000 'Zehn
Stundenarray(11) = &B0000000001000000 'Elf
Stundenarray(12) = &B0000000010000000 'Zwölf
'Hauptschleife
Do
If Sek_flag = 1 Then
If Sekunden < 59 Then
Sekunden = Sekunden + 1
Else
Sekunden = 0
Minuten = Minuten + 1
End If
If Minuten >= 59 Then
Minuten = 0
Stunden = Stunden + 1
End If
If Stunden > 12 Then
Stunden = 1
Minuten = 0
End If
Sek_flag = 0
End If
'Arrayposition berechnen Bsp: Minuten = 3 ===> Arrayposition 1 muss ausgegeben werden
Minpos = Minuten / 5
Minpos = Minpos + 1
'Überprüfen ob die Stunde + 1 ausgegeben werden muss. Bsp: 05:31 ===> Halb Sechs
Stdpos = Stunden
If Minuten >= 5 Then
Stdpos = Stdpos + 1
End If
'Stundenarray an der Position "Stunden" in die Schieberegister takten
For I = 0 To 15 Step 1
Datasr = Stundenarray(Stunden).I
Toggle Sck
Toggle Sck
Next A
'Minutenarray an der Position "Minpos" in die Schieberegister takten
For I = 0 To 7 Step 1
Datasr = Minutenarray(Minpos).I
Sck = 1
Sck = 0
Next A
'Latch der Schieberegister auf Ausgänge schalten
Rck = 1
Rck = 0
'In Idle Mode wechseln zum strom sparen und um unnötiges beschreiben der Schieberegister
'zu vermeiden. Geweckt wird im Sekundentakt des Timers.
'POWER IDLE
Loop
End
'Interrupt Routine für den Timer1. Läuft Sekündlich über.
Sekundentakt:
Timer1 = 34285
Toggle Led
Sek_flag = 1
Return
-
LED auch mit dem Flag machen im Main-Loop (wird aber nicht viel helfen :-) )...
Ansonsten bau halt ne Terminal-Ausgabe fürs Debugging ein.
-
Ja das ist wohl ehr unwahrscheinlich das das was bringt. Ich hab noch eine vermutung:
Kann es sein das es daran liegt, dass ich momentan den internen RC Oszillator benutze und trotzdem an XTAL ein 8MHz Quarz hängt und das mir da irgendwie zwischen funkt? Ich kann momentan das externe Quarz nicht aktivieren weil mein Programmer kein Quarz hat und ich somit nicht mehr programmieren könnte nach dem umfusen. Ich hab in meiner Werkstatt aber noch nen anderen ISP liegen mti Quarz. Den werd ich wohl mal holen und dann umfusen auf externen Takt.
Hat sonst noch einer eine Idee woran diese Taktaussetzer liegen könnten? Die Uhr lief jetzt 7 Stundne über nacht und ich hab schon eine Abweichung von mehr als 5 Minuten...
-
Ich wundere mich grad im Nachhinein, wieso du nicht einfach nen Uhrenquarz und die eingebaute Uhrenroutinen nutzt :-)
Deine Abweichung liegt so bei 2% wenn ich richtig gerechnet habe...
Das ist garnicht mal soo ungenau, der interne R-Oszi kann mehr :-)
-
Ja Uhrenquarz... Das hätte ich selbstverständlich benutzen können aber später ist man immer schlauer ^^
Kanns also sein das die abweichung wirklich am RC Oszillator liegt? Naja ist ja sowieso spekulation. Ich werds einfach mal testen mit Quarz.
Danke!
-
Der interne is auf jeden fall recht ungenau, ja.
Man kann den aber auch noch irgendwie kallibrieren - musste mal googeln.
-
So!
Ich hab jetzt mal das externe Quarz aktiviert und siehe da: Die Uhr läuft bisher sehr genau. Mal sehen wies morgen früh aussieht!
Ich hätte nicht gedacht das der interne Oszillator SO ungenau ist aber aus Fehlern wird man ja bekanntlich schlau.
Jetzt hab ich noch eine winzig kleine Frage: Der Timer muss ja vorgeladen werden um genau eine Sekunde zu realisieren. Hierbei sagt RN Wissen das der korrekte Wert 34285 bei einem Prescaler von 256 ist. Ich hab jetzt allerdings noch ein Berechnungstool aus irgend einem Forum runtergeladen und da unterscheidet sich der Wert um 1 (34286).
Was ist jetzt richtig und was falsch? Ich denke das der unterschied wirklich fast nichts ausmacht aber so eine Uhr läuft ja nicht nur eine Woche sondern wohl ehr ein Jahr da wird sich der unterschied schon bermerkbar machen fürchte ich.
Um zu einem Abschluss zu kommen: Danke Stefan für deine wirklich sehr gute Hilfe! Das Problem mit der teilweise hängenden Status LED habe ich gelöst bekommen indem ich auch das LED Toggeln in die Main Loop gepackt habe auch wenn ich mir nciht im geringsten erklären kann warum das was gebracht hat ^^