Guten Tag,
mit dem anschließenden Code, möchte ich eine Synchronisation mit dem
DCF77-Signal erreichen. Zu den Prinzipien der Erkennung
und der Dekodierung brauch ich keine Hilfe. Diese sind mir klar und
sollte vor der Programmierung wohl überlegt sein.
Mein Problem richtet sich dabei in der Umsetzung mit VHDL.
Kurz zur Erläuterung. Ich habe zwei Prozesse wobei der erste Prozess
einen Zähler mit einem sauberen 100Hz Takt bei einer
abgetasteten logischen Null hoch zählt und bei einer abgetasteten
logischen Eins zurücksetzt.
Ist der Zählerwert über dem Wert 179 (entspricht 1,79 s) wird eine
Synchronisation erwartet (das DCF77 Signal ist bei Synchronisation
mindestens 1,8 s logisch null) .
Über ein Flag-Signal sec_59 wird nun der zweite Prozess freigeschaltet,
der auf eine steigende Flanke des DCF77 Signals wartet.
Dann wurde eine Synchronisation gefunden (Störungen bitte zunächst
unbeachtet lassen).
Nun die alte Leier: die Simulationen funktionieren, die Realität sieht
aber so aus:
Erste Synchronisation wird erkannt, darauffolgende Synchronisation aber
nicht, danach folgt wieder eine Synchronisation und anschließend wieder
nicht.
Leider sehe ich in der logischen Beschreibung keine Hinweise auf diesen
reproduzierbaren Fehler und ich vermute eher, das es an meiner
Programmierweise liegt, da ich in VHDL noch wenig erfahren bin.
Vielleicht erkennt jemand absolute "NoGos" in dem Code oder mögliche
Fehlerfälle.
Ein Kommilitone meinte, ich solle das nicht so mit zwei Prozessen machen
und lieber eine Statemachine programmieren.
Vielen Dank für die mögliche Hilfe.
Olaf
Olaf Schulz schrieb:> Ist der Zählerwert über dem Wert 179 (entspricht 1,79 s) wird eine> Synchronisation erwartet (das DCF77 Signal ist bei Synchronisation> mindestens 1,8 s logisch null) .
...
> Erste Synchronisation wird erkannt, darauffolgende Synchronisation aber> nicht, danach folgt wieder eine Synchronisation und anschließend wieder> nicht.> Leider sehe ich in der logischen Beschreibung keine Hinweise auf diesen> reproduzierbaren Fehler und ich vermute eher, das es an meiner> Programmierweise liegt, da ich in VHDL noch wenig erfahren bin.
Ich kenne zwar null von Deinem VHDL, aber grau ist alle Theorie.
Und Du verläßt Dich offenbar zu sehr auf die Theorie.
Und vernachlässigst das praktische Zeitverhalten von realen DCF-Modulen.
Reale DCF-Module geben nämlich nicht immer Impulse von der theoretisch
zu erwartenden Impulsdauer (0,1 bzw. 0,2s) ab, sondern oftmals auch
etwas längere Impulse.
So dauern dann beispielsweise die theoretisch 100ms langen Impulse am
DCF-Modul dann z.B. 120 bis 130 ms und die theoretisch 200ms langen
Impulse beispielsweise 220 bis 230 ms.
Demzufolge wäre z.B. wenn der letzte gesendete Impuls ein 230 ms langer
Impuls ist die Pause bis zum nächsten Impuls nicht "mindestens 1,8 s
logisch null" sondern nur 1,77 s lang.
Und mit so einem DCF-Modul angeschlossen greift Dein Code mit:
MAX_COUNT:natural:=179
natürlich immer dann voll ins Klo, wenn die letzte Absenkung in der
Minute kein 100ms-Impuls sondern ein 200ms Impuls ist, der praktisch
aber 230 ms lang ist und demzufolge nur zu 1,77s Absenkung führt und
nicht zu 1,79s.
Versuch's vielleicht mal mit:
MAX_COUNT:natural:=170
und teste einfach auf mindestens 1,7s ohne einen gesendeten Impuls!
Du verwendest zwei Takte (clk100Hz, DCF77). Das schreit nach
Clock-Domain-Crossing.
Ich würde den Code ändern, so das er mit dem schnellsten Takt läuft. Auf
den langsameren Signalen wird dann eine Flankenerkennung gemacht.
Duke
Hallo Jürgen,
gerade Duschen und fast am Verzweifeln, danke für deine Antwort. Das
klingt in sich schlüssig, so mal bei den Tests das letzte Bit immer eine
Eins war und sich nicht geändert hat (Parität Datum). Ich habe zwar eine
"Schutzzeit" eingebaut, da die 100Hz clk ja asynchron zum DCF77 Signal
läuft (in dem Fall: 179-1 zu den 180 also 2 => 20ms).
Ich werde dass ausprobieren und dann berichten. Man sollte die Realität
stets mit dem Oszi abbilden und weniger mit dem Kopf...
Dank für Deine schnelle Antwort.
Olaf Schulz schrieb:> process (reset,clk100Hz,DCF77,sec_59_release)> process (reset,DCF77,sec_59)
Arg viel Zeug in diesen Sensitivlisten...
> if (rising_edge(DCF77)) then
Das ist kein Takt, sondern nur ein Signal, das 1. einsynchronisiert und
dann 2. auf eine Flanke untersucht werden muss.
Kurz: wenn ein Anfänger mehr als 1 Signal bei rising_edge() oder
falling_edge() oder bei 'event hat, dann wird er früher oder später
diese Erfahrung machen:
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
Wenn du darüber nachgedacht hast, dann darfst du dir das mal genauer
ansehen:
http://www.lothar-miller.de/s9y/categories/56-DCF77 ;-)
> Ein Kommilitone meinte, ich solle das nicht so mit zwei Prozessen machen> und lieber eine Statemachine programmieren.
Auch knapp vorbei...
Wobei du natürlich auch schon eine FSM in deinem Design hast, denn jeder
Zähler ist schon ein Zustandsautomat, wenn auch ein einfacher...