ThSteier
16.10.2006, 17:23
Hallo,
mal ein paar Gedanken zu den hier (https://www.roboternetz.de/phpBB2/viewtopic.php?t=24181) 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:
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
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?
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
mal ein paar Gedanken zu den hier (https://www.roboternetz.de/phpBB2/viewtopic.php?t=24181) 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:
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
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?
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