Hallo, Leute!
Ein kleines Problem plagt mich seit zwei Tagen: Man stelle sich vor, ich
hätte ein IC, das ich um Mitternacht mit Spannung versorge und ab dann
jede sekunde ein internes Register von Null an um eins erhöht. Jetzt sei
es zwei Uhr mittags und ich lese das Register mal aus und habe somit die
Zahl der vergangenen Sekunden (Das Ding sendet 4 Bytes mit LSByte first
- muss also die 4 Einzelbytes noch "zusammenkleben".). Mit ein bisschen
Rumrechnen lässt sich doch jetzt sagen, wie spät es ist. Und das soll
ein AVR programmiert in GCC tun. Er tut es auch. Allerdings läuft
irgendwas schief bei manchen Uhrzeiten. Der Fehler müsste so um 17:00
rum auftreten. Ich hab mal ein Codesnippet angehängt und wäre dankbar,
wenn Ihr mal drüberschauen könntet...
Die Kommunikation ist übrigens okay, d.h., die empfangenen Variablen
entsprechen den Registerinhalten in der RTC.
Ungefähr 17:00? Nicht vielleicht 18:12:16? (18*3600+12*60+16 == 65536)
-- riecht nach einem Überlauf.
Außerdem wird dir der Modulo-Operator (%) sehr weiterhelfen.
Ich würde deine Berechnung ein bisschen umstellen:
1
/* Prototyp */
2
uint8_tempfangen(void);//Besser einen sprechnederen Namen nehmen
Ich Depp... Natürlich "|" statt "+"... Okay, das ist besser,
funktioniert aber immer noch nicht wirklich. Scheint wohl etwas mit der
Bereichsüberschreitung zu tun zu haben. Muss irgendwie rauskriegen, wie
ich aus den 4 einzelnen Bytes, eine 4-Byte-var machte, die der AVR
arithmetisch beackern kann. Wenn ich Deinen Code mal übertrage, bekomme
ich jensets von 00:04:15 (das sind 255 (!) sekunden) sozusagen einen
"Neustart" der Uhr. Aber besten Dank schonmal für den oder-hint!
Thomas wrote:
> Ich Depp... Natürlich "|" statt "+"...
Das ist in dem Fall völlig Wurscht.
Entscheidend ist, dass bei
(uint32_t)empfangen()<<8
das uint8_t Ergebnis von empfangen() zuerst mal auf 32 Bit
aufgeblasen wird, bevor es nach links verschoben wird.
> Okay, das ist besser,> funktioniert aber immer noch nicht wirklich.#
Zeig noch mal deinen jetzigen Code
Eigentlich schieb ich auch nach links, hab nur in meiner Verzweiflung
das mal mit rechts durchgetestet und vergessen, es wieder zu ändern. In
Echtigkeit schieb ich nach links.
Kann es sein das du hier alle bits invertierts (~) ?
uint8_t ow_rtc_1st=~(_1w_receivebyte());
uint8_t ow_rtc_2nd=~(_1w_receivebyte());
uint8_t ow_rtc_3rd=~(_1w_receivebyte());
uint8_t ow_rtc_4th=~(_1w_receivebyte());
versuch es doch mal so
uint8_t ow_rtc_1st=(_1w_receivebyte());
uint8_t ow_rtc_2nd=(_1w_receivebyte());
uint8_t ow_rtc_3rd=(_1w_receivebyte());
uint8_t ow_rtc_4th=(_1w_receivebyte());
Gruss Helmi
Ja, ich invertiere alle Bits, aber das ist Absicht. Wie gesagt, an der
Kommunikation hängts nicht, sondern eher an der "Zusammenführung" oder
Berechnung...
die Berechnung ist meiner Meinung nach richtig, also
entweder es kommen andere Daten als du erwartest,
oder die Ausgabe der Ergebnisse ist falsch!
Wie ist denn das genaue Verhalten der Zeitanzeige?
Ist das Bei-255-Sekunden-Schlapp-Mach-Problem immer noch da, oder lag
das nur an der verkehrten Schieberichtung? In meinen Augen scheint die
Umrechnung der Sekunden in hh, mm und ss korrekt zu sein.
Ein möglicher Fehler liegt aber im Einlesen der 4 Bytes: Hast du
sichergestellt, dass sich die Werte während des Einlesens nicht
ändern? Bspw. dadurch, dass du die 4 Bytes auf Hardwareseite latchst?
Sonst kann (und wird) es hin und wieder passieren, dass der
Sekundenwechsel genau während des Einlesens der Bytes stattfindet.
Die gelesenen Werte sind dann falsch.
Kontrollieren kannst du dies, indem du die 4 Bytes ein zweites Mal
einliest. Haben sie den gleichen Wert wie beim ersten Mal, sind die
Werte ok. Wenn nicht, hast du einen Sekundensprung erwischt. Die Werte
müssen dann korrigiert oder - und das ist die sicherere Methode - ein
drittes Mal eingelesen werden.
Dann gibt die Daten doch einmal einzeln aus also ow_rtc_1st ..
ow_rtc_4st und dann die zusammenfassung seconds
wenn in z.B. in ow_rtc_1st = 0x12
ow_rtc_2st = 0x34
ow_rtc_3st = 0x56
ow_rtc_4st = 0x78
dann muss in Seconds = 0x78563412 sein
wenn das dann gleich ist müsste die zusammenfassung ok sein
Gruss helmi