Hallo zusammen Ich baue zurzeit eine digitale Schachuhr frage mich jetzt wie genau diese sein sollte, bzw. wie genau sollte eine Sekunde sein oder anders ausgedrückt, wie viel Sekunden darf sie nach x Stunden falschgehen. Ich weiß genau nicht wie genau DGT oder die anderen dig. Uhren sind. Ich möchte aber mit ähnlicher Genauigkeit haben. Ich hab ein bisschen mit meinem 8Mhz Quarz rumexperimentiert und habe jetzt die Frequenz als Richtwert auf 7998976 Hz gestellt (kann man durch 256 teilen: 31246). Bisher läuft die Testuhr 40 Minuten und geht ein Bruchteil einer Sekunde vor. Was meint ihr, wie genau sollte so eine Uhr sein?
Sam schrieb: > Was meint ihr, wie genau sollte so eine Uhr sein? Da es mit handelsüblichen Quarzen kein Problem darstellt eine Uhr zu bauen, die auch nach Tagen nicht signifikant mehr als 1 Sekunde abweicht, stellt sich doch dieses Problem nicht wirklich.
Hallo Sam, Da die Zeit für beide Spieler gleich lang ist und beim Turnier nicht länger als 0,5 bis 1h gespielt wird, ist es müssig über Sekundenbruchteile zu verhandeln. Quartz-Genauigkeit ist absolut ausreichend. Viele Grüße, korax
Fra Nk schrieb: > Hallo Sam, > > Da die Zeit für beide Spieler gleich lang ist und beim Turnier nicht > länger als 0,5 bis 1h gespielt wird Huch, seit wann das? Ich kenn das noch als "Zwei Stunden für 40 Züge"...
> Was meint ihr, wie genau sollte so eine Uhr sein? So genau, dass es keinem auffällt, dass sie ungenau geht... ;-) > Ich hab ein bisschen mit meinem 8Mhz Quarz rumexperimentiert und habe > jetzt die Frequenz als Richtwert auf 7998976 Hz gestellt Das hört sich an, wie wenn du mit delays rumbastelst... :-/ > läuft die Testuhr 40 Minuten und geht ein Bruchteil einer Sekunde vor. Weil du die Taktfrequenz zu niedrig angegeben hast? Denn tatsächlich könnte es ja sein, dass dein Quarz schneller läuft...
Nimm einen 32.786er, wie in jeder Uhr und gut ist - da hat sich noch niemand über seine Uhr beschwert!
Lothar Miller schrieb: > Das hört sich an, wie wenn du mit delays rumbastelst... :-/ Nein, natürlich mit 8bit Timer. Sonst wär der Teiler von 256 auch nicht wichtig. Ich hab ein bisschen gerechnet dann probiert und so weiter, aber nie länger als ne Stunde laufen lassen (ich will ja heute mit der Zeit noch fertig werden). 56min 1/4Sekunde abweichung. Ich denke das reicht, bei einem Tunier wären das dann eine halbe Sekunde bei 2 Stunden. Genauigkeit von DGT ist: http://www.nextag.de/DGT-Schachuhr-digital-DGT-1532161459/de/spezifikationen-html Genauigkeit: besser als eine Sekunde pro Stunde Das hab ich ja auch. Wie verädert sich die Frequenz vom Quarz über Temperaturschwankungen? z.b. zw. 15 (kalten Raum) - 35 (draußen im heißen Sommer)°C?
Sam schrieb: > Lothar Miller schrieb: >> Das hört sich an, wie wenn du mit delays rumbastelst... :-/ > > Nein, natürlich mit 8bit Timer. Sonst wär der Teiler von 256 auch nicht > wichtig. Wieso Teiler? Wieso 256? Hängst du dich an den Overflow Interrupt? Dazu nimmt man doch den CTC, und das nach Möglichkeit von einem 16 Bit Timer (dann hat man weniger Arbeit :-) http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr http://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC
Noch was zum Delay: Das wär ja grausam wenn bei jedem neuen Befehl die Uhr langsamer tickt bzw. man sie korrigieren muss. micha schrieb: > Siehe auch > http://www.mikrocontroller.net/articles/AVR_-_Die_... > Danach hab ich es berrechnet. Karl heinz Buchegger schrieb: > Wieso Teiler? Wieso 256? > > Hängst du dich an den Overflow Interrupt? > > Dazu nimmt man doch den CTC, und das nach Möglichkeit von einem 16 Bit > Timer (dann hat man weniger Arbeit :-) > > > http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr > Siehe auch > http://www.mikrocontroller.net/articles/AVR_-_Die_... Ich glaub man braucht das gar nicht mit dem Rest / den CTC, denn: bei z.b. 7999999 (schlechteste beispiel), geteilt durch den Prescaler 256 7999999 / 256 = 31249,99609 Also fehlt bei jeder Sekunde ca. ein Timeroverflow -> 255 Takte fehlen (0,99609*256 = 255) Das heißt bei 7999999Hz: 256 / 7999999 = ca. 0,000032 Sekunden fehlen pro Sekunde. Das sind in einer Stunde *3600 = .ca. 0,1152s und an einem Tag *24 = ca. 2.7648s Ich denke bei einer Schachuhr kann man das vernachlässigen (man bedenke, dass das das schlechteste beispiel war). Ich werde mir die CTC trotzdem man anschauen. PS: Ich kenne mich in der AVR programmierung wirklich nicht gut aus. Wenn ich was neues programmieren will, muss ich erst nachschauen wie das beim AVR geht. Bisher weiß ich nur wie Timer, das ganze mit den Ports geht. Vom Rest weiß ich nicht wie man es programmiert, sondern nur das es das gibt und wie es funktioniert. Mein Vorteil ist halt, dass ich C progammieren kann. Noch was, korrigiert mich wenn die Rechnung nicht stimmt. 80min und fast eine halbe sekunde abweichung.
Sam schrieb: > 256 / 7999999 = ca. 0,000032 müsste 255 / 7999999 = ca. 0,000031875 heißen nach einer Stunde sind es dann 0.11475s und nach einem Tag "nur" 2.754s Keine wirklichen Änderungen.
Sam schrieb: > > Ich werde mir die CTC trotzdem man anschauen. Tu das. Funktioniert wie dein bisheriges Schema, nur dass die 256 auch noch variabel sind und du einen anderen Interrupt benutzt. Mehr ist es nicht.
> Ich hab ein bisschen mit meinem 8Mhz Quarz rumexperimentiert > und habe jetzt die Frequenz als Richtwert auf 7998976 Hz gestellt Wie und wo hast du diese Frequenz eingestellt?
Hier:
1 | uint16_t quotient = 7998976 / 256; |
2 | |
3 | while(1) |
4 | { |
5 | if(timercounter >= quotient) |
6 | { |
Bei F_CPU nicht, ich werde delay auch nicht verwenden, und wenn doch ist es egal wenn es nicht genau stimmt. Für die genaue Zeitrechnung verwende ich sowieso den Timer und für den MAX7219 brauch ich kein delay da er bis 10 Mhz ansprechbar ist. Da bin ich mir noch nicht ganz sicher: Muss ich > oder >= benutzen?
Mark Brandis schrieb: > > Huch, seit wann das? Ich kenn das noch als "Zwei Stunden für 40 Züge"... Schnellschach geht bis 1h: http://www.schachakademie.com/schachregeln/schach_schachregeln_fide_anhang_b_schnellschach.htm Und mehr als sagen wir 2h ist unsinnig. Wenn Du normal spielst, brauchst Du keine Uhr.
> uint16_t quotient = 7998976 / 256; Es ist ja eigentlich schon klar, dass deine Uhr falsch geht, wenn du im Programm mit ungenauen und falschen Teilern rechnest... Du hast nun mal einen Oszillator mit 8000000Hz. Und wenn du mit 7998976Hz rechnest, dann kommt ein Fehler von 0,013% heraus. Damit komme ich auf einen Wert von 0,42 sec Abweichung auf die 56 min. Das deckt sich ganz gut mit deiner Beobachtung: > 56min 1/4Sekunde abweichung. Also: alles im zu erwartenden grünen Bereich.... ;-) Nicht der Controller macht den Fehler. Du hast ihn bei der Berechnung gemacht.
Sam schrieb: > Hier: > >
1 | > uint16_t quotient = 7998976 / 256; |
2 | > |
3 | > while(1) |
4 | > { |
5 | > if(timercounter >= quotient) |
6 | > { |
7 | > |
8 | > |
>
Was genau machst du da?
Wenn du mit einem Timer und einem Interrupt arbeitest, stellt sich diese
Frage, bzw. diese Codestelle gar nicht.
Das weiterschalten der Uhr machst du in einem Interrupt und nicht indem
du irgendeine Variable, die ständig ihren Wert ändert, per Schleife
überwachst.
Genau dafür sind Interrupts da! Ein Ereignis (Timer hat einen bestimmten
Wert erreicht) tritt auf, behandle es. Und wenn sich die Behandlung ein
wenig verzögert ist es auch nicht so schlimm, das Interrupt Flag hat
gespeichert, dass das Eregnis aufgetreten ist und bei der nächsten
möglichen Gelegenheit (wenn die Interrupts wieder freigegeben werden)
wird es abgearbeitet.
Fra Nk schrieb: > Mark Brandis schrieb: >> >> Huch, seit wann das? Ich kenn das noch als "Zwei Stunden für 40 Züge"... > > Schnellschach geht bis 1h: > http://www.schachakademie.com/schachregeln/schach_... > Und mehr als sagen wir 2h ist unsinnig. > > Wenn Du normal spielst, brauchst Du keine Uhr. Nein er hat völlig recht, wenn es gibt auch 2 Stunden für 40 Züge, das ist zurzeit die normale Bedenkzeit für Wettbewerbspartien. Wahrscheinlich wird aber bald 90min +30s pro Zug eingeführt. Aber ich werde die Uhr wahrscheinlich fast ausschließlich nur für Blitz einsetzen. Höchtens dann wird sie für 2 Stunden benutzt, wenn ich eine lange Partie Zuhause spiele (höchtens bei vereinsinternen Turnier; außerdem muss der Gegner einverstanden sein). Sie geht jetzt immernoch ziemlich genau eine halbe Sekunden vor innerhalb 2 Stunden. Lothar Miller schrieb: > Das deckt sich ganz gut mit deiner Beobachtung: >> 56min 1/4Sekunde abweichung. > > Also: alles im zu erwartenden grünen Bereich.... ;-) > Nicht der Controller macht den Fehler. Du hast ihn bei der Berechnung > gemacht. > Mit 8Mhz ist die Uhr nachgegangen und so geht sie vor also muss ich was zwischen drin ausrechnen: 7998976 * (1 + .5 / 7200) = 7999531.484 Hz Wie gesagt bisher hab ich ausprobiert. Karl heinz Buchegger schrieb: > Was genau machst du da? > Wenn du mit einem Timer und einem Interrupt arbeitest, stellt sich diese > Frage, bzw. diese Codestelle gar nicht. > Das weiterschalten der Uhr machst du in einem Interrupt und nicht indem > du irgendeine Variable, die ständig ihren Wert ändert, per Schleife > überwachst. > Genau dafür sind Interrupts da! Ein Ereignis (Timer hat einen bestimmten > Wert erreicht) tritt auf, behandle es. Und wenn sich die Behandlung ein > wenig verzögert ist es auch nicht so schlimm, das Interrupt Flag hat > gespeichert, dass das Eregnis aufgetreten ist und bei der nächsten > möglichen Gelegenheit (wenn die Interrupts wieder freigegeben werden) > wird es abgearbeitet. Ich lad dir mal den ganzen Code hoch. Ich hab dir nur die Definitionzeilen gezeigt. Und ja der Max hat einen Decoder aber ich möchte auch Zeichen anzeigen, die mit diesem nicht gehen (nur bevor du fragst wie alle die meinen Code sehen).
Lothar Miller schrieb: > Du hast nun mal einen Oszillator mit 8000000Hz. Und wenn du mit > 7998976Hz rechnest, dann kommt ein Fehler von 0,013% heraus. Der Oszillator mit einem Feld-, Wald-, und Wiesenquarz wird alles mögliche haben, nur nicht genau 8000000Hz. Auch wenn da 8,00 Mhz draufsteht. Insofern ist der Ansatz mit dem durch trial and error angepassten Faktor doch durchaus richtig. Oliver
Verleg das Hochzählen deiner Uhr in den Interrupt
1 | #define F_CPU 7998976
|
2 | |
3 | //Zählvariablen initialisieren
|
4 | volatile uint8_t seconds = 0; |
5 | volatile uint8_t minutes = 0; |
6 | |
7 | volatile uint8_t updateDisplay = 0; |
8 | |
9 | uint16_t nrCalls = 0; |
10 | |
11 | ISR (TIMER0_OVF_vect) |
12 | {
|
13 | nrCalls++; |
14 | if( nrCalls == F_CPU / 256 ) { // es sind genügend Aufrufe |
15 | // für 1 Sekunde erfolgt
|
16 | seconds++; |
17 | if( seconds == 60 ) { |
18 | seconds = 0; |
19 | minutes++; |
20 | if( minutes == 100 ) { |
21 | minutes = 0; |
22 | }
|
23 | }
|
24 | |
25 | updateDisplay = 1; |
26 | }
|
27 | }
|
28 | |
29 | int main(void) |
30 | {
|
31 | //Init MAX7219
|
32 | SPIMasterInit(); |
33 | SetMode(MAX_MODE_NORMAL); |
34 | SetIntensity(0x0F); |
35 | SetDecodeMode(0x00); |
36 | SetScanLimit(0x07); |
37 | SetAll(0); |
38 | |
39 | //8bit Timer Init
|
40 | TCCR0 = (1<<CS00); //Kein Teiler |
41 | TIMSK |= (1<<TOIE0); // Overflow Interrupt erlauben |
42 | sei(); // Global Interrupts aktivieren |
43 | |
44 | updateDisplay = 1; // den ersten Update forcieren |
45 | |
46 | while(1) |
47 | {
|
48 | if( updateDisplay == 1 ) { |
49 | // die aktuelle Uhrzeit holen. Dabei aber dafür sorgen
|
50 | // dass sich die nicht schnell mal ändern kann
|
51 | cli(); |
52 | uint8_t sec = seconds; |
53 | uint8_t min = minutes; |
54 | updateDisplay = 0; |
55 | sei(); |
56 | |
57 | // ab jetzt haben wir alle Zeit der Welt die Zeit auf
|
58 | // die ANzeige zu bringen
|
59 | |
60 | SetDigit( 3, chars[sec % 10] ); |
61 | SetDigit( 2, chars[sec / 10] ); |
62 | SetDigit( 1, chars[min % 10] ); |
63 | SetDigit( 0, chars[min / 10] ); |
64 | }
|
65 | }
|
66 | }
|
Und wie auch schon gesagt: Wechsle auf den 16-Bit Timer, nimm den CTC Modus (üzugehörigen Interrupt) und du bist die Beschränkung, dass du die Quarzfrequenz nur in Vielfachen von 256 vorgeben kannst auch noch los.
Ist das für ein Schachspiel nicht eigentlich egal. Die Uhr wird doch nach jedem Zug wieder auf Null gestellt und läuft doch für beide Spieler gleich "Falsch". Bitte klärt mich auf.
Ok. Hab was gefunden. Sie läuft normal weiter und wird nur angehalten. Aber bei zwei Stunden kommt es nicht auf 1 Sekunde an. Von daher ist die Quarzgenauigkeit ja ausreichend.
007boris schrieb: > Ist das für ein Schachspiel nicht eigentlich egal. Die Uhr wird doch > nach jedem Zug wieder auf Null gestellt und läuft doch für beide Spieler > gleich "Falsch". Bitte klärt mich auf. Im Prinzip ja. (Die Uhr wird nicht auf 0 gestellt. Die Uhr wird von jedem Spieler für sich angehalten und wenn er wieder am Zug ist läuft sie weiter). Allerdings gibt es noch Zusatzregeln, die sagen, dass man für x Züge insgesamt nur eine bestimmte Zeit zur Verfügung hat. Allerdings wird wohl kaum jemand nachmessen, ob die Uhr in 2 Stunden 2 Sekunden zu schnell oder zu langsam gelaufen ist, da das ja für beide Spieler gleichermassen gilt. War aber immer interessant zu beobachten, als im deutschen Fernsehen noch der Herr Pfleger Schachpartien kommentiert hat. Je näher dieses Zeitlimit kam, desto hektischer wurden dann schon mal Züge aus dem Ärmel geschüttelt.
Oliver schrieb: > Der Oszillator mit einem Feld-, Wald-, und Wiesenquarz wird alles > mögliche haben, nur nicht genau 8000000Hz. Dann würde ich den Oszillator auf 8,000000MHz abgleichen und dann im Programm mit 8 MHz rechnen. Das lässt sich doch schön teilen: 8000000 : 200 = 40000 Also ein Timeroverflow nach jeweils 200 Takten und davon 4000, das gibt eine saubere Zehntelsekunde. > Insofern ist der Ansatz mit dem durch trial and error angepassten Faktor > doch durchaus richtig. Hmmm... Nur gibt es nicht viel Spielraum, denn zum Schluss wird noch durch 256 geteilt: >>> uint16_t quotient = 7998976 / 256; Der qoutient ist genau gleich, ob ich da 7998976 oder 7999231 hinschreibe. Es wird eine Pseudogenauigkeit vorgegaukelt.
@Karl heinz Buchegger Du erinnerst mich an die Spieleprogrammierung mit deiner Updateprüfung. Danke für den Tipp. Sollte man aber nicht mit Divisionen sparsam umgehen (bei dem Prog ist das natürlich egal), der Atmega hat doch keine Hardwaredivision, oder hab ich da was falsches gehört. F_CPU wird bei mir mit 8000000UL definiert. Was heißt das UL. Ich hab das aus dem Inet, aber was es heißt weiß ich nicht. 7999488 Hz stimmt übrigens auch nicht ganz, das ist zu hoch. Ich nehm mal (7999488 + 7998976) / 2 = 7999232
Lothar Miller schrieb: > Oliver schrieb: >> Der Oszillator mit einem Feld-, Wald-, und Wiesenquarz wird alles >> mögliche haben, nur nicht genau 8000000Hz. > Dann würde ich den Oszillator auf 8,000000MHz abgleichen und dann im > Programm mit 8 MHz rechnen. Das lässt sich doch schön teilen: > 8000000 : 200 = 40000 > Also ein Timeroverflow nach jeweils 200 Takten und davon 4000, das gibt > eine saubere Zehntelsekunde. Ich hab leider keine Ahnung wie man den pf Wert der Anschwingkondensatoren ausrechnet. >> Insofern ist der Ansatz mit dem durch trial and error angepassten Faktor >> doch durchaus richtig. > Hmmm... > Nur gibt es nicht viel Spielraum, denn zum Schluss wird noch durch 256 > geteilt: >>>> uint16_t quotient = 7998976 / 256; > Der qoutient ist genau gleich, ob ich da 7998976 oder 7999231 > hinschreibe. Es wird eine Pseudogenauigkeit vorgegaukelt. Ich weiß, dass int16 keine Gleitkommazahl ist, was würde das auch bringen. Deswegen nimm ich nur durch 256 teilbare Zahlen. Sollte das nicht reichen kann ich immer noch eine Restkorrektur einbauen wie bei Beitrag "Die genaue Sekunde / RTC"
Sam schrieb: > @Karl heinz Buchegger > > Du erinnerst mich an die Spieleprogrammierung mit deiner Updateprüfung. Der springende Punkt ist der, dass auf diese Art die Uhr auf jeden Fall weiter läuft, selbst wenn dein Programm etwas ganz anderes macht. > Danke für den Tipp. > Sollte man aber nicht mit Divisionen sparsam umgehen (bei dem Prog ist > das natürlich egal), der Atmega hat doch keine Hardwaredivision, oder > hab ich da was falsches gehört. Ist in dem Fall schon ok. Du hast 1 Sekunde Zeit um die Anzeige zu aktualisieren. Da kann man schon ein wenig (8-Bit) dividieren. Grundsätzlich solltest du solche Faustregeln auch als das ansehen, als was sie gedacht sind: Als Faustregeln die einen Leitfaden bilden, mit dem erst mal nicht allzuviel schief gehen kann. Im Einzelfall kann man von diesen Regeln immer wieder einmal abweichen, wenn man sich über die Auswirkungen im klaren ist. In diesem Fall sind die Auswirkungen: 0 > F_CPU wird bei mir mit 8000000UL definiert. > Was heißt das UL. Ich hab das aus dem Inet, aber was es heißt weiß ich > nicht. unsigned long
Der ganze Thread ist doch Quatsch und geht am eigentlichen Problem vorbei. Du musst die Uhr so machen, dass sie so hochtechnisch und hochwissenschaftlich und höchstpräzise aussieht wie möglich (mit gefrästem Schriftzug "Schachuhr CAESIUM NORMAL QUARZ", hochgenauen Lichtschrankentasten, gebürstetes Metallgehäuse mit Fenstern zur Begutachtung der Technik usw.) ist, aber trotzdem die Zeit bei DIR langsamer läuft als beim Gegner.
Grolle schrieb: > Der ganze Thread ist doch Quatsch und geht am eigentlichen Problem > vorbei. > > Du musst die Uhr so machen, dass sie so hochtechnisch und > hochwissenschaftlich und höchstpräzise aussieht wie möglich (mit > gefrästem Schriftzug "Schachuhr CAESIUM NORMAL QUARZ", hochgenauen > Lichtschrankentasten, gebürstetes Metallgehäuse mit Fenstern zur > Begutachtung der Technik usw.) ist, aber trotzdem die Zeit bei DIR > langsamer läuft als beim Gegner. Und wenn der Gegner entscheiden darf auf welcher Seite die Uhr steht? Jetzt mal im Ernst, ich baue mir die Schachuhr aus 2 Zwecken: -Weil es Spaß macht -und weil ich dann eine Digitale uhr hab. und nicht um zu schummeln. Wieso schälts du die Interrupts aus? Was wenn in dieser Zeit ein Overflow stattfindet würde?
Sam schrieb: > Wieso schälts du die Interrupts aus? Damit ich sicher gehen kann, dass das was ich von seconds und minutes auslese auch wirklich zusammengehört und einen Zeitstempel bildet. (*) > Was wenn in dieser Zeit ein Overflow stattfindet würde? Dann wird der zugehörige Interrupt ein klein wenig verzögert und nach dem sei() nachgeholt. Macht aber nichts. Der Timer wird davon ja nicht beeinflusst und läuft unbeirrt weiter. Pünktlich zum nächsten Zeitpunkt wird wieder der Interrupt ausgelöst. (*) Das wird zwar so bei dir nicht auftreten, weil es sich vom Timing her nicht ausgeht. Aber folgendes Szenario Die aktuelle Zeit sei 3 MInuten und 59 Sekunden du liest die Sekunden aus und kriegst klarerweise die 59. Noch ehe du die Minuten auslesen kannst, kommt der Interrupt, der die Uhr um 1 Sekunde weiterschaltet. Die ISR zählt die Zeit hoch auf 4 Minuten und 00 Sekunden. Die ISR ist fertig und im Hauptprogramm gehts weiter mit 'Auslesen der Minuten'. Da kriegst du die 4. Auf deiner Anzeige steht dann 04:59 und nicht 04:00 oder 03:59 wie es eigentlich richtig wäre (je nachdem was man dann als richtig ansieht) Und alles nur, weil dir ein Interrupt zwischen die Sekunden und die Minuten reingefahren ist.
Danke, ich hab dein Prog jetzt mal getestet, aber komischerweise zeigt die anzeige so viele Zahlen an das man nichts erkennen kann, und wartet dann mit einer belibigen Zahl 1 sekunde. Die Einer der Minuten werden dabei immer um 1 oder 2 größer.
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | |
5 | #ifndef F_CPU |
6 | /* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert |
7 | (z.B. durch Übergabe als Parameter zum Compiler innerhalb |
8 | des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die |
9 | "nachträgliche" Definition hinweist */ |
10 | #warning "F_CPU war noch nicht definiert, wird nun mit 8000000 definiert" |
11 | #define F_CPU 7998976 /* Quarz mit 8 Mhz */ |
12 | #endif |
13 | #include <util/delay.h> |
14 | #include <stdlib.h> |
15 | #include "Max7219.h" |
16 | |
17 | uint8_t chars[] = {126,48,109,121,51,91,95,112,127,123}; |
18 | |
19 | //Zählvariablen initialisieren |
20 | volatile uint8_t seconds = 0; |
21 | volatile uint8_t minutes = 0; |
22 | volatile uint8_t updateDisplay = 0; |
23 | uint16_t timercounter = 0; |
24 | |
25 | int main(void) |
26 | { |
27 | //Init MAX7219 |
28 | SPIMasterInit(); |
29 | SetMode(MAX_MODE_NORMAL); |
30 | SetIntensity(0x0F); |
31 | SetDecodeMode(0x00); |
32 | SetScanLimit(0x07); |
33 | SetAll(0); |
34 | |
35 | //8bit Timer Init |
36 | TCCR0 = (1<<CS00); //Kein Teiler |
37 | TIMSK |= (1<<TOIE0); // Overflow Interrupt erlauben |
38 | sei(); // Global Interrupts aktivieren |
39 | |
40 | updateDisplay = 1; |
41 | |
42 | while(1) |
43 | { |
44 | if( updateDisplay == 1 ) |
45 | { |
46 | // die aktuelle Uhrzeit holen. Dabei aber dafür sorgen |
47 | // dass sich die nicht schnell mal ändern kann |
48 | cli(); |
49 | uint8_t sec = seconds; |
50 | uint8_t min = minutes; |
51 | updateDisplay = 0; |
52 | sei(); |
53 | |
54 | // ab jetzt haben wir alle Zeit der Welt die Zeit auf |
55 | // die ANzeige zu bringen |
56 | |
57 | SetDigit( 3, chars[sec % 10] ); |
58 | SetDigit( 2, chars[sec / 10] ); |
59 | SetDigit( 1, chars[min % 10] + 128 ); // + 128 für den Trennpunkt |
60 | SetDigit( 0, chars[min / 10] ); |
61 | } |
62 | |
63 | } |
64 | } |
65 | |
66 | ISR (TIMER0_OVF_vect) |
67 | { |
68 | timercounter++; |
69 | if( timercounter >= 31246 ) // es sind genügend Aufrufe für 1 Sekunde erfolgt |
70 | { |
71 | seconds++; |
72 | if( seconds == 60 ) |
73 | { |
74 | seconds = 0; |
75 | minutes++; |
76 | if( minutes == 100 ) |
77 | { |
78 | minutes = 0; |
79 | } |
80 | } |
81 | updateDisplay = 1; |
82 | } |
83 | } |
Müsste doch so stimmen, oder?
Sam schrieb: > Und wenn der Gegner entscheiden darf auf welcher Seite die Uhr steht? Da muss dann eben ein wenig clever sein :-) Ein kleiner Magnet im Kugelschreiber vor der Uhr informiert dann die Uhr auf welcher Seite ich drücke :-)
Sam schrieb: > Müsste doch so stimmen, oder? Wir haben beide vergessen timercounter in der ISR wieder auf 0 zu setzen. Nachdem 1 Sekunde vorbei ist, geht ja die Zählung der ISR Aufrufe wieder von vorne los.
1 | ISR (TIMER0_OVF_vect) |
2 | {
|
3 | timercounter++; |
4 | if( timercounter >= 31246 ) // es sind genügend Aufrufe für 1 Sekunde erfolgt |
5 | {
|
6 | timercounter = 0; |
7 | ....
|
> Und wenn der Gegner entscheiden darf auf welcher Seite die Uhr steht? Eben, gerade DA muss ja das Entwickler-Know-how zur Entfaltung kommen. Die gehackte Backdoor mit Geheimpasswort in der Schachuhr sozusagen. Wir sind doch in einer Demokratie, da muss man es ja so machen wie unsere zahlreichen Vorbilder ganz oben und ganz unten. "Gaming the system for your own advantage", das Motte unserer Epoche. <sarcmarc url="http://02d9656.netsoljsp.com/SarcMark/modules/user/commonfiles/loadhome.do ">
Hab ich echt übersehen, danke. Sind wiedermal die Fehler an denen man stundenlang verzweifeln könnte und ein anderer findet sie sofort (einmal hab ich in einem anderen Prog ein = statt ein == gemacht, das hat wirklich stunden gedauert bis ich das fand). Ich hab da noch ein anderes Problem, vielleicht hast du erfahrung damit. Ich muss um mein Mega zu programmieren ihn manchmal fest in den Sockel drücken. Wie bekomm ich ihn da rein, dass er auch so bleibt, ohne ihn irgendwie anzukleben, bzw. zu verzinnen?
verzinnen auf keinen Fall. Was ist das für einer? DIP Gehäuse? Ich würde mal den IC aus dem Sockel nehmen, dann links und rechts an den schmalen Seiten anfassen und die Beinchen gleichmässig mit mässigem Druck gegen die Tischplatte ein wenig nach innen biegen. Aber nur wenig! Andere Seite genauso. Scheint so, dass du einen billigen Sockel mit Blechkontakten hast, aus dem sich der Mega immer wieder mal ein wenig rausarbeitet. Andere Möglichkeit: Einen Sockel mit gedrehten Kontakten kaufen und den in deinen Programmiersockel stecken oder überhaupt den Sockel austauschen. Dann sollte der Spuk auch ein Ende haben.
Ist Dip der hier, nur schmaler als auf dem bild: http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=C131;GROUPID=3215;ARTICLE=8222 superflach und gedreht ist der auch, nur die Beine des Megas sind leicht verbogen.
Man bekommt auch den schiefsten Prescaler gebacken, indem man folgendes macht: #define F_CLK 8000000UL // Die Quarzfrequenz #define PRESCALER 256 // Konfiguration des Vorteilers im Timer unsigned long Timer = 0; ISR (TIMER0_OVF_vect) { Timer += PRESCALER; if (Timer >= F_CLK) { Timer -= F_CLK; Sekunde++; // usw... } } Oben bei der Quarzfrequenz darf dann auch eine tatsächlich gemessene Frequenz eingetragen werden, womit obszöne Genauigkeiten erreichbar sind ;-)
Eddy Current schrieb: > Oben bei der Quarzfrequenz darf dann auch eine tatsächlich gemessene > Frequenz eingetragen werden, womit obszöne Genauigkeiten erreichbar sind > ;-) Die aber nicht stimmt, oder hast du ein Quarz mit der Toleranz 0%.
Sam schrieb: > Eddy Current schrieb: >> Oben bei der Quarzfrequenz darf dann auch eine tatsächlich gemessene >> Frequenz eingetragen werden, womit obszöne Genauigkeiten erreichbar sind >> ;-) > > Die aber nicht stimmt, oder hast du ein Quarz mit der Toleranz 0%. Was er meint ist. Benutz es. Lass die Uhr eine Woche laufen, rechne dir die tatsächliche Quarzfrequenz aus und trag sie auf den Taktzyklus genau ein und alles ist gut. Bei einigermassen gleichbleibender Temperatur verändert auch der Quarz seine Frequenz nur wenig. Mit deinem Schema kannst die Quarzfrequenz nur in Vielfachen von 256 einfliessen lassen. Mit seinem Schema gehts auf die Schwingung genau.
Achso sorry hab ich falsch verstanden. Ja das stimmt natürlich. Eine Woche? Ich denke ein paar Stunden reichen, so über die Nacht, das soll ja ne Schachuhr werden und keine Uhr (so ne uhr fänd ich irgendwie zu einfach und zu primitiv).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.