Hallo,
mal ein paar Gedanken zu den hier angesprochenen Problemen bei der Realisierung serieller synchroner Kommunikation bzw zur Rückgewinnung des Signaltaktes aus dem Nutzsignal:
eine Möglichkeit wäre es, das Startframe auszumessen. Benötigt würde hierfür ein externer Interrupt am AVR, der auf Flankenwechsel konfiguriert ist, sowie ein Timer.
Die HDLC-Startframes lauten 01111110, d.h. sie beginnen einem Flankenwechsel. Wird ein solcher empfangen, startet der Timer und mißt die Zeit zum abschließenden Flankenwechsel. Bei einer angenommenen Datenrate von 1200Bd beträgt die erwartete "Länge" eines Bits 833ns, zwischen den beiden Nulldurchgängen müßten also (7 * 833ns = ) 5,83ms liegen. Liegt die wirklich gemessene Zeit nun außerhalb eines bestimmten Toleranzbereiches, so ist das Startframe ungültig und wird verworfen. Anderenfalls wird nun anhand der gemessenen Zeit eine Zeitbasis für den Timer berechnet, der nunmehr den genauen Empfangstakt bereitstellt.
Auf Basis dieses Taktes könnte der Rest des Datenpaketes nun bitweise in einen Empfangsbuffer eingelesen (Flankenwechsel-INT nach 833ns = "0", kein Wechsel = "1"), auf einen gültigen Stop-Frame überprüft und dann zur Verarbeitung weitergegeben werden. Mal als Pseudocode:
Eventuell könnte man sogar auf das "Ausmessen" des Start-Frames verzichten und mit festen Timerwerten arbeiten. Da der Timer durch den Interrupt bei jeder empfangenen "0" (also spätestens nach jeweils 6 Bit) neu auf die Flanke synchronisiert wird, sollte sich eine eventuelle Drift doch eigentlich in Grenzen halten?Code:Wenn [externer INT] wenn Bitzähler < 5 ; Bit-Striping, eine "0" nach 5x "1" wird ignoriert schreibe "0" in den Empfangspuffer wenn Bitzähler = 6 ; Stop-Frame empfangen? gib Empfangspuffer aus setzte Bitzähler := 0 lade Timer = 1,5*Bitlänge ; Timer auf "Flanke-zu-Mitte" nächstes Bit starte Timer Ende Wenn [Timer-INT] inkrementiere Bitzähler ; wieviele aufeinanderfolgende "1"-Bits bisher? wenn Bitzähler > 6 ; ungültiger Frame empfangen? setze Fehler-Flag Ende schreibe "1" in den Empfangspuffer setze Timer = Bitlänge ; Timer auf "Mitte-zu-Mitte" nächstes Bit starte Timer Ende
Steckt da irgendwo ein Denkfehler drin, oder könnte das so funktionieren? Daß hier Flanken und keine Pegel ermittelt werden müssen, bringt mich doch etwas ins Trudeln...
Viele Grüße,
Thomas
Lesezeichen