Wie würde ich diesen seriellen 260-kHz-Stream per Software decodieren?

Ich habe diesen seriellen Strom untersucht, der aus einem Scoreboard-Controller kommt, und es scheint ein proprietäres Protokoll zu sein. Wie würde ich versuchen, dies per Software zu dekodieren?

Serieller Stream

Das Startbit ist 7,8 us lang. Alle Datenbits sind etwa 3,85 us groß, was eine Busgeschwindigkeit von etwa 260 kHz ergibt. Ein logisches HIGH-Bit beginnt mit einer HIGH-Periode von 3,1 us und dann einem LOW von ~800 ns. Ein logisches LOW-Bit ist dasselbe, aber die Perioden werden umgeschaltet. Jedes Paket besteht aus 255 Bits, sodass jede Millisekunde etwa ein Paket gesendet wird.

Ich habe daran gedacht, auf die steigende Flanke zu triggern und dann nach einer kurzen Verzögerung den Pin-Pegel zu lesen, aber ich glaube nicht, dass ein Interrupt-gesteuertes Schema wegen des Overheads so gut funktionieren würde.

Irgendwelche Ideen?

Welches Mikro willst du verwenden?
Ich glaube nicht, dass ein AVR dafür schnell genug sein wird, also benutze ich einen Teensy 3.0.
Nicht sicher, wie dies ein Duplikat ist? Die Signale sind nicht gleich (eines ist RS232-ähnlich und das andere ein proprietäres Protokoll). Stellen Sie auch andere Fragen ... Hier wird gefragt, wie eine serielle Hochgeschwindigkeitsleitung effizient decodiert werden kann, nicht die Identifizierung.
Sie könnten sich ein programmierbares Logikgerät ansehen, obwohl die Entwicklung einer zyklusgezählten Lösung auf einem Mikrocontroller, der dieser Aufgabe gewidmet ist, tatsächlich einfacher sein kann. Ich wäre versucht, zuerst eine Reihe von Daten mit einem billigen Streaming-Logikanalysator auf Festplatte zu erfassen und sie offline zu decodieren, um sicherzustellen, dass ich das Format verstehe.
Sie müssen den Rezensenten verzeihen. Manchmal suchen sie nur nach oberflächlichen Ähnlichkeiten, bevor sie eine Frage als Duplikat schließen. Dies ist eindeutig eine andere Frage und verdient eine Antwort, insbesondere angesichts der Tatsache, dass die andere Frage sowieso keine Antwort hatte.
@DaveTweed Entschuldigung, ich war einer der Schuldigen. Beide Fragen stammten von derselben Person, betrafen serielle Protokolle mit Anzeigetafeln und hatten ähnlich aussehende Zeitdiagramme (obwohl ich bei genauerem Hinsehen feststellen kann, dass sie unterschiedlich sind). Also kam ich zu dem Schluss, dass es Duplikate gab.

Antworten (3)

Sie sagen, dass der Overhead der Interrupt-Behandlung zu hoch wäre, aber ich glaube nicht, dass das unbedingt stimmt. Ein billiger Mikrocontroller ist möglicherweise nicht in der Lage, den Datenstrom sinnvoll zu verarbeiten, aber er sollte leistungsfähig genug sein, um als Ad-hoc-Konverter zu dienen.

Nehmen wir als Beispiel einen AVR-Chip: den ATmega328P, der als Kern des Arduino-Entwicklungsboards dient. Bei der maximalen Taktrate von 20 MHz erhalten Sie 77 Taktzyklen pro Bit. Laut Datenblatt (Seite 15) dauert es etwa 7 Taktzyklen, um in eine ISR einzutreten, und 4 Zyklen, um sie zu verlassen.

Angenommen, Sie verbringen die Hälfte jedes Datenbits in einer Spin-Schleife und warten auf den richtigen Zeitpunkt, um die Eingabe abzutasten, bleiben Ihnen außerhalb des Interrupt-Handlers etwa 27 Zyklen pro Bit. Die meisten AVR-Befehle sind Single-Cycle, also sollte genug Zeit sein, um die Bits in Bytes zu rahmen und sie auf eine SPI-Verbindung zu Ihrem Host-Prozessor zu schieben.

(Ich habe das Problem der Erkennung von Startbits beschönigt. Eine Möglichkeit besteht darin, einen der eingebauten Timer am Anfang jedes Bits zurückzusetzen und den Ausgangsvergleich zu verwenden, um festzustellen, ob das Intervall zwischen zwei steigenden Flanken einen Schwellenwert überschreitet. )

+1. Ja, ein 25-Takt-Spin-Loop bei 20 MHz ist ziemlich vernünftig. Vielleicht könnte die Startbit-Erkennung in diese 25 Takte passen? Die verbleibende Zeit entspricht in etwa der eines ATmega328 bei 10 MHz – Viele Leute betreiben den ATmega328 bei 10 MHz oder weniger und erledigen nützliche Dinge.

Ich habe solche Signale mit AVRs dekodiert. Ich habe es mit einem Pin-Wechsel-Interrupt und einem freilaufenden Timer gemacht. Sie könnten dies auch mit einem Capture-Eingang am Timer tun, aber ich wachte auch mit den Daten auf, also brauchte ich die asynchrone Erkennungsfunktion.

Im Grunde habe ich jedes Mal, wenn ich einen Pin-Wechsel-Interrupt bekam, auf die Zeit und den Zustand des Pins geschaut. Ich könnte dann sagen "der Pin war 3us hoch" oder "der Pin war 3us niedrig" und die 1 oder 0 in ein Eingangsdatenwort verschieben. Ich habe ein @#define@ verwendet, um die Schwellenzeit eines Hochs oder Tiefs zu bestimmen, und habe empirisch einen guten zu verwendenden Wert ermittelt. Meine empfangenen Datenwörter waren 33 Bit lang, also markierte ich, nachdem ich 33 Bit gezählt hatte, den Empfang als abgeschlossen und markierte die Hauptroutine, um das Datenwort tatsächlich zu verifizieren und zu decodieren.

Aus Gründen der Robustheit habe ich auch einen Timer zurückgesetzt, der eine Periode von etwa 10 ms hatte. Wenn dieser Interrupt ausgelöst wurde, bedeutete dies, dass ich mein Empfangssubsystem zurücksetzen sollte, da keine Daten eingingen und mein Bitzähler nicht genug Daten gezählt hatte, um die Nachricht als vollständig zu betrachten.

Eine Möglichkeit, dies zu dekodieren, besteht darin, es zu invertieren und dann einem UART zuzuführen, der auf 2,6 Mbit / s eingestellt ist (etwas extrem, aber einige UARTs können so hoch eingestellt werden).

Die ansteigende Flanke jedes Impulses würde für den UART zu einer fallenden Flanke – einem Startbit – werden, und jede Art von Impuls würde ein einzigartiges Datenmuster im UART-Empfänger erzeugen: Eine „1“ würde zu 0x80, eine „0“ würde zu 0x80 0xFE, und ein "Startbit" würde 0x00 werden (und möglicherweise einen "Overrun"-Fehler verursachen). Die Firmware würde diese Bytewerte in Bits umwandeln und dann das Protokoll entsprechend decodieren.

Es ist möglich, dass Sie den UART auf 1,3 Mbit/s einstellen und zwei der Signalimpulse pro Byte erhalten – die Dekodierung wird etwas kniffliger, aber Sie müssten nur mit der halben Interrupt-Rate fertig werden.

  • 0x00 → Startimpuls
  • 0x7F → 0 gefolgt von 0
  • 0x0F → 0 gefolgt von 1
  • 0x74 → 1 gefolgt von 0
  • 0x04 → 1 gefolgt von 1

Ein völlig anderer Ansatz wäre die Verwendung eines Paares retriggerbarer monostabiler Multivibratoren . Eine wäre auf eine Periode von etwa 1,9 µs eingestellt; es würde eine Taktflanke in der Mitte jedes Bits erzeugen. Der andere würde auf eine Periode von etwa 5 µs eingestellt werden; es würde den "Start"-Impuls erkennen.

Sie würden diese Signale dann an einen SPI-Slave-Port Ihres Mikros anschließen: das ursprüngliche Datensignal an MOSI, das Taktsignal an SCLK und das Startsignal an SSEL. Die SPI-Schnittstelle würde 8 Bits gleichzeitig sammeln und sie mit einer Rate von etwa 32 kB/s an die Firmware liefern.