Hallo,
ich habe für eine Funkuhr den DCF77 Code von der Webseite ulrichradig.de
genommen. Dieser funktioniert auf einem ATmega8 auch wunderbar. Ich
möchte jedoch statt der Lokalzeit die Zeit in UTC (GMT) ausgeben, da ich
wenig C Kentnisse habe fällt mir das aber recht schwer. Zunächst habe
ich einfach 2 Stunden von der Variablen hh abgezogen, da kamen aber
immer wieder seltsame Zeiten bei heraus. Ausserdem wäre das nicht schön,
da ich so zur Uhrzeitumstellung immer wieder die Zeitdifferenz
umprogrammieren müsste oder den Atmega8 austausche...
Ich habe gesehen, dass im Zeitcode des DCF77 die Bits 17 und 18 die
Information MEZ oder MESZ angeben. Wie komme ich nun im Quellcode an die
Information der beiden Bits dran und wie kann ich dementsprechend daraus
mir die UTC Zeit errechnen?
Wer kann mir geeignete Denkanstöße bzw. Hilfestellungen geben.
Grüße
Nein! Ehrlich? Wow - hätte ich jetzt nicht gedacht - Spaß beiseite: Mag
denn jemand sinnvolle Hilfen geben und schreibt auch die Ansätze oder
nicht?
Grüße
P.S.: Da will man einmal was selbst machen und nur nach Hilfestellungen
bzw. Ideen oder Stichwörtern und nicht der Lösung fragen und da kommen
so geniale Antworten die null konstruktiven Inhalt besitzen. Man sollte
doch mal drüber nachdenken ob in einem technischen Forum eine solche Art
der Beanwortung sinnvoll ist...
Hi, Pascal,
würdest Du meinen Stundensatz zahlen, dann würde ich mich mit Freude in
den Quellcode stürzen und Dir die Lösung präsentieren.
Aber wie alle Fragesteller hier zahlst Du keinen Stundensatz. Warum soll
ich mir Mühen machen für eine Lösung, die Du bei etwas mehr Übung in C
selber herausfinden könntest?
Ulrich Radig hat sein Programm gut kommentiert, Deine Frage zu
beantworten kostet nur Mühe. Wenn Du dazu nicht bereit ist, wazu sollte
ich es sein?
Deine "beleidigte Leberwurst-Antwort" mit "man sollte mal drübe
nachdenken" weise ich als Unverschämtheit zurück.
Mit solchen Unverschämtheiten wirst Du hier keine Freude haben.
Ciao
Wolfgang Horn
P.S. In dem Programm, das ich von Ulrich kopiert habe, ist "hh"
deklariert als unsigned char. Wenn Du 1 - 2 rechnest, kommt kein 23 bei
raus, sondern 255.
>würdest Du meinen Stundensatz zahlen, dann würde ich mich mit Freude in>den Quellcode stürzen und Dir die Lösung präsentieren.
Er ist aber nicht in deinen Betrieb gekommen um Hilfe zu bekommen,
sondern in ein MC-Forum.
Wenn du nicht helfen willst, schreib doch einfach garnix.
Oder hast du einfach zuviel Zeit dich in Foren rumzutreiben und deinen
Frust abzulassen weil niemand deinen Stundensatz zahlen will ?
@Jürgen: Du sprichst mir aus der Seele. Es gibt in so vielen Foren Leute
die unglaublich viele Beiträge schreiben aber nichts sinnvolles
Anzubieten haben.
@Pascal: Naja du hättest den Code schon mitliefern können. So müssen wir
extra danach suchen...
Hier ein Vorschlag. "//Anpassen der gewünschten..." ab da isses neu. Der
Rest ist aus clock.c.
Hallo Jürgen,
Hallo Stephan,
vielen Dank für Eure Antworten und das Verständnis. Ich dachte schon im
Internet läuft jetzt nichts mehr richtig...
Ich habe den Quellcode nicht dabeigeschrieben bzw. kopiert da ich nicht
wusste ob ich das machen darf wegen Copyright usw - ist ja nicht mein
geistiges Eigentum...
@Stephan:
Ich habe den Schnipsel mal so darein getan, jetzt bekomme ich nur noch
einen Fehler, hab auch mal danach gesucht, da heißt es ich muss
irgendwie den Wert "Casten" - habe aber keine Ahnung was es mir sagen
soll, habe mal in einem Tutorial danach gesehen verstehe aber absolut
nichts was die von mir wollen.
Also, der Compiler sagt mir dieses:
../clock.c:75: warning: left shift count >= width of type
In der Zeile 75 steht das:
1
mesz = dcf_rx_buffer & (1<<17);
und ganz oben in clock.c habe ich ergänzt
1
//Mitteleuropäische Sommerzeit oder nicht
2
volatile unsigned char mesz;
3
4
//Zeitverschiebung in Uhrzeit einrechnen - Wert in Stunden
5
volatile unsigned char zz;
Dachte jetzt einfach irgendwie das nach diesem System hier einzurechnen:
1
flags.dcf_sync = 1;
2
3
//Anpassen der gewünschten Zeitzone, zz gibt die Verschiebung
4
//in Stunden an
5
6
mesz = dcf_rx_buffer & (1<<17);
7
8
if (mesz = 0)
9
{
10
zz == 1; //minus 1 Stunde Verschiebung nach UTC wenn
11
//Winterzeit
12
}
13
else
14
{
15
zz == 2; //minus 2 Stunden Verschiebung nach UTC wenn
16
//Sommerzeit
17
}
18
19
if (hh < zz)
20
{
21
hh = (24 - (zz - hh));
22
// .. Datum noch anpassen .. -- ToDo !!!
23
}
24
else
25
{
26
hh -= zz;
27
}
28
}
29
else ....
Was mache ich noch falsch oder wie muss ich besser gesagt mesz
deklarieren damit das nicht mehr einen Fehler gibt?
Grüße und nochmals DANKE!
Pascal
Pascal schrieb:
> Also, der Compiler sagt mir dieses:> ../clock.c:75: warning: left shift count >= width of type
Damit sagt er dir, dass ein "int" nur 16 Bits hat, 1<<17 also Unsinn
ist.
@A.K.
Ja, soweit verstehe ich es mittlerweile auch, aber auch ein volatile
long long mesz; bringt mir keinerlei Änderung, dann müsste doch
eigentlich alles reinpassen?
@STK500-Besitzer
Klar, Tippfehler.
Standardfehler. Quizfrage: Welchen Datentyp hat der Ausdruck 1<<17 ?
Kleiner Tip: Die Frage ist direkt so beantwortbar, ohne den Kontext zu
kennen und auch nicht vom Prozessor oder Compiler abhängig.
A. K. schrieb:
> Standardfehler. Quizfrage: Welchen Datentyp hat der Ausdruck 1<<17 ?
Der Datentyp nützt Dir bloß nichts, der Ausdruck ist compilerabhängig:
Auf nem 32-Bitter wird der Ausdruck das gewünschte Ergebnis liefern.
Auf nem 8- oder 16-Bitter ist er 0.
Peter
Peter Dannegger schrieb:
>> Standardfehler. Quizfrage: Welchen Datentyp hat der Ausdruck 1<<17 ?> Der Datentyp nützt Dir bloß nichts, der Ausdruck ist compilerabhängig:
Im Gegenteil. Zwar ist das Ergebnis abhängig vom Compiler, aber der
Datentyp und dessen Wertebereich sind dabei die entscheidenden Faktoren.
Aber nur der Wertebereich ist abhängig vom Compiler, der Typ nicht.
Pascal G. schrieb:
> Hmm, schöne Sache, stehe im Dunklen. Was muss ich machen um den Fehler> nicht mehr zu bekommen, selbst ein long long bringt keine Abhilfe!?
Ich versuche gerne, Leute zum selber denken zu bewegen. Aber wenn das
nicht funktioniert: Ein Ausdruck a<<b mit a und b vom Typ "int" ist
immer auch vom Typ "int", egal was dabei als Ergebnis rauskommt und egal
ob a und b Konstanten sind oder nicht. Eine numerische Konstante wie 1
ist vom Typ "int". Also ist 1<<17 auch "int", aber darin bei 16 Bits
nicht darstellbar.
Der Standardfehler liegt in der Annahme, dass in einem Statement
long x = a << b;
der Typ "long" Auswirkung auf die Rechung rechts davon hätte. Hat er
nicht. Da wird erst gerechnet und danach - zu spät - in "long"
konvertiert. Der Datentyp des Ausdrucks a<<b und daher auch das Ergebnis
sind unabhängig davon, in welchem Kontext das steht.
Also: 1L<<17 verwenden.
Wenn die Abfrage nur auf == und != 0 stattfindet, ist es egal, an
welchster Stelle das Bit ist.
Oder schaut einfach mal nach, wie die Variable dcf_rx_buffer definiert
ist...
Grüße,
Martin
Hallo,
Sorry. Natürlich klappt das nicht. Wie schon gesagt wurde ist eine Zahl
im Compiler automatisch ein Integer und eben nur 16 Bit breit. Casten
bedeutet, dass der Compiler wenn möglich z.B. aus einem 16-Bit Integer
ein 32/64-Bit Long macht. Folgendes funktioniert jetzt. Habs getestet:
1
mesz=dcf_rx_buffer&((long)1<<17);
Das (long) ist der Cast.
Das ist aber extrem krass ;-D. Deswegen machs einfach direkt mit einem
32Bit Wert.
Was ist daran krass? (long)1 ist übrigens identisch mit 1L. Und der
Compiler rechnet das selber, so dass zwischen 1L<<17 und 0x20000 kein
Unterschied besteht, aber 1L<<17 ist verständlicher.
Hallo Leute!
Erstmal Danke für die schöne Diskussion und die vielen Ideen usw. Ich
habe heute endlich Zeit gefunden das ganze einmal auszuprobieren.
Ich habe leider noch nen Fehler drin, denn irgendwie erkennt der aus Bit
17 bzw. 18 des DCF Signals noch nicht das Sommerzeit ist. Habe mal den
Sourcecode mit dabeigetan, vielleicht findet ihr ja den Käfer in der
clock.c oder main.c?!?
Ausserdem habe ich jetzt noch das Problem, dass auf der seriellen
Schnittstelle der Text nicht mehr im Sekundentakt "sauber" geschrieben
wird, es wird immer mal eine Sekunde in der Anzeige übersprungen. Habe
schonmal mit dem Wert
1
//Wait a short time
2
for (long i=0;i<50000000;i++){};
ein wenig gespielt und auch die Geschwindigkeit der seriellen
Schnittstelle auf 38K4 hochgesetzt, bringt aber auch nichts. Dazu auch
irgendwelche Ideen?
Grüße Pascal
Pascal G. schrieb:
> Ich habe leider noch nen Fehler drin, denn irgendwie erkennt der aus Bit> 17 bzw. 18 des DCF Signals noch nicht das Sommerzeit ist.
Tja
mesz = dcf_rx_buffer & (1L<<18);
maskiert aus dcf_rx_buffer nur das interessierende Bit frei.
Dieses Bit ist nach wie vor an Bitposition 18.
Wenn du diesen long wert danach an einen unsigned char zuweist, werden
alle Bits, die überzählig sind, also alles von Bit 8 an aufwärts,
einfach weggeschmissen. Und damit ist dann auch das dich interessierende
Bit Geschichte.
Wenn du haben willst, dass mesz entweder 0 oder 1, ist je nachdem ob das
Bit gesetzt ist oder nicht, dann sei explizit (Das empfiehlt sich
sowieso immer für einen Anfänger)
1
if(dcf_rx_buffer&(1L<<18))
2
mesz=1;
3
else
4
mesz=0;
Dann klappts auch mit der Sommerzeit
Wenn dich dann die C-eritis gepackt hat, kannst du das auch kürzer
schreiben
1
mesz=((dcf_rx_buffer&(1L<<18))!=0);
aber für den Anfang ist ein explizites if sicherlich einfacher zu lesen.
Pascal G. schrieb:
> wird, es wird immer mal eine Sekunde in der Anzeige übersprungen. Habe> schonmal mit dem Wert>
1
//Wait a short time
2
> for (long i=0;i<50000000;i++){};
3
>
> ein wenig gespielt und auch die Geschwindigkeit der seriellen> Schnittstelle auf 38K4 hochgesetzt, bringt aber auch nichts. Dazu auch> irgendwelche Ideen?
Ja.
Schmeiss den Müll raus und mache den Update, wenn sich die Sekunden
verändert haben.
1
intmain()
2
{
3
...
4
unsignedcharold_ss;
5
6
....
7
8
old_ss=255;
9
10
//Ausgabe der Zeit auf der Seriellen Schnittstelle und dem LCD in einer Endlosschleife
Hallo K.H. Buchegger,
vielen Dank für Deine tollen Antworten, darauf wäre ich nie gekommen.
Ich glaube ich muss mich mal tiefer mit der C Programmierung
beschäftigen. Gibt es da speziell für diese Bedürfnisse ein gutes
Tutorial oder Buch wo alles nacheinander erklärt wird so das man es ohne
große Kenntnisse versteht aber trotzdem nicht langwierig wird?
Wegen den Updates der Daten auf der Schnittstelle / dem LCD:
Jetzt in dem Style kommt das Update nur alle 2 Sekunden!? Soll ich da
irgendwie noch einen Timer Interrupt wirken lassen oder so damit es
besser klappt?
Grüße
Pascal G. schrieb:
> Wegen den Updates der Daten auf der Schnittstelle / dem LCD:> Jetzt in dem Style kommt das Update nur alle 2 Sekunden!? Soll ich da> irgendwie noch einen Timer Interrupt wirken lassen oder so damit es> besser klappt?
Ich denke, die Ausgabe an sich dauert schon zu lange. Du gibst ziemlich
viel über die UART/LCD aus und das ist nicht gerade das schnellste.
Kürze die Ausgabe etwas zusammen (bzw. gib am LCD tatsächlicgh nur die
Dinge aus, die sich auch verändert haben. Tag, Monat, Jahr verändern
sich praktisch nie, werden aber jede Sekunde erneut aufs Display
formatiert. Das muss nicht sein und würde Zeit sparen. Selbiges für
Stunden und Minuten
Ach ja, da sollte man noch einmal umdrehen
Hallo,
also meine DCF77 Uhr läuft nun seit ein paar Wochen ohne weitere
Probleme. Ich habe nun die letzten Tage probiert mit der oben erwähnten
lib von U.Radig im CGRAM des LCD eigene Zeichen zu generieren (will den
DCF77-Sync mit einer Art Antenne darstellen). Dazu habe ich probiert mit
lcd_write etwas zu machen, leider kann ich sobald ich da irgendwas sende
nur noch wirre Zeichen auf dem Display sehen. Eignet sich denn die Radig
Lib dazu eigene Zeichen (acht Stück laut Datenblatt) ins Display zu
schreiben? Falls ja, wie macht man das? Die Suche brachte mich immer nur
auf Seiten mit Assembler-Code.... Ausserdem wollte ich ungern die Radig
Lib gegen eine andere austauschen...
Grüße