Implementierung der Kompensation der Leitungsausbreitungsverzögerung für den BiSS-Master in der Software

7

Nach einer Frage, die ich vor einiger Zeit gestellt habe: Einfache Implementierung der BiSS C-Schnittstelle für einen Positionsgeber . Ich habe einen einfachen BiSS-Master (Punkt zu Punkt) implementiert, um mit einem Encoder zu kommunizieren. Bei Frequenzen unter 2 MHz und kurzer Kabellänge funktioniert die Software mit dem SPI-Modul auf dem PIC-Mikrocontroller einwandfrei.

Ich habe jedoch versucht, hohe Geschwindigkeit (3 bis 10 MHz) und ein 10 m Kabel, das funktionieren sollte. Ich bin auf ein Problem mit der Ausbreitungsverzögerung gestoßen. Es scheint, dass das Protokoll eine Implementierung einer Zyklus-für-Zyklus-Verzögerungskompensation benötigt.

Ein Ausschnitt aus TI TIDU410 zeigt das Problem

Ich habe einen Ansatz versucht, bei dem ich von der Startsequenz (ACK und Startbit) abhängig bin und das Ergebnis um 1 oder 2 oder 3 Bit verschiebe, je nachdem, wie viele Takte das Startbit zu spät war. Aber es funktioniert nicht immer, das Problem scheint zu sein, dass die Daten um einen Bruchteil der Uhr verschoben werden können (z. B. 1/8, 1/4, 1, 1,5), sodass MISO nicht rechts dekodiert Zeit die ganze Zeit.

Hat jemand Gedanken darüber, wie eine solche Funktion in einem Mikrocontroller richtig implementiert werden kann? (Ich kann bei Bedarf ein paar diskrete Komponenten und Logikgatter hinzufügen), aber kein FPGA.

* EDIT (Screenshot vom Oszilloskop) mit Standard-SPI-Funktionen * Geben Sie hier die Bildbeschreibung ein

Screenshot vom Oszilloskop, wenn Daten ohne Wartezeit oder Funktion direkt in den SPI-Puffer gestellt werden Geben Sie hier die Bildbeschreibung ein

Screenshot im gepufferten Modus, 2 SPI-Schreibvorgänge. Beachten Sie, dass das Signal sauber ist, aber die Oszilloskopsonde und der Erdungsstift beim Aufnehmen des Fotos nicht im Leerlauf waren. Geben Sie hier die Bildbeschreibung ein

ElectronS
quelle
Was ist Ihre mcu Taktrate?
BeB00
@ BeB00, ich laufe mit 60MIPS, 16.67ns ist die Anweisungszeit (falls Sie sich über Bitbanging wundern)
ElectronS
Nun, Sie können die Funktionsweise des SPI-Peripheriegeräts nicht ändern. Bit-Banging ist also so ziemlich das einzige, was Sie tun können, es sei denn, Sie möchten einen externen Chip erhalten. Für 10 MHz wären 80 MIPS komfortabler, aber 60 könnten funktionieren
BeB00
1
Können Sie Master to Slave implementieren und dann für die Slave-Antwort die Rollen tauschen, sodass der ursprüngliche Master die Uhr vom neuen Master (dem früheren Slave) übernimmt? Gibt es genug Intelligenz am Slave-Ende, um dies umzusetzen?
Andy aka
1
Äh, ich weiß nicht, ob Andy das gemeint hat, aber die Antwort traf mich wie ein Sturm. Verwenden Sie SPI im Slave-Modus und verwenden Sie einen anderen Pin (unter Verwendung von Ausgangsvergleich oder Ähnlichem), um das Taktsignal für PIC- und BISS-Slave zu erzeugen. Auf diese Weise bleibt das Taktsignal ohne Unterbrechungen konstant. Wenn Sie die Uhr, die zum PIC geht, irgendwie steuern, können Sie die Verzögerung kompensieren, wie im BISS-Protokoll angegeben
Dorian

Antworten:

4

Ich gehe davon aus, dass die Verzögerung irgendwie konstant ist oder einen kleinen Jitter aufweist und das Signal in gutem Zustand zu SPI gelangt.

Nach den Beobachtungen von OP wurde aktualisiert, dass die SPI-Kommunikation nicht aufeinander folgt, wie ich angenommen habe, sodass einige Bits zwischen den Frames verloren gehen.

Nach Andys Hinweis aktualisieren, besteht die richtige Lösung darin, sowohl den BISS-Sensor als auch den PIC-SPI im Slave-Modus zu verwenden und zwei Takte zu generieren, die entweder extern von einem PIC-Ausgang oder intern über einen Timer-Ausgangsvergleich oder auf andere Weise gesteuert werden

Wenn beide Takte in "1" im Leerlauf sind, starten Sie DMA für den SPI-Empfang, starten Sie den BISS-Schnittstellentakt, bündeln Sie das ACK-Bit und starten Sie dann den PIC-SPI-Takt. Die Probenahme in der Mitte gewährleistet einen ausreichenden Gefahrenabstand. Die Daten werden in Worten ausgerichtet, es ist keine Verschiebung erforderlich. Der zweite DMA für die Dummy-Übertragung wird nicht mehr benötigt.

Im Microchip-Dokument zum Ausgangsvergleichsmodul finden Sie Seite 9, wie Sie mit dem Ausgangsvergleichsmodul eine Uhr ab einem hohen Pegel erzeugen. Die Geschwindigkeit kann bis zu 1/8 Systemuhr betragen.

Abhängig von den PIC-Funktionen kann es möglich sein, dass der SPI-Clock-Pin (Eingang, da wir SPI im Slave-Modus verwenden) mithilfe von PPS angesteuert wird, ohne einen anderen Pin und eine externe festverdrahtete Verbindung zu verwenden.

In diesem Fall kann die Karte unter Verwendung der folgenden Softwareverschiebung ohne Hardwaremodifikation verwendet werden.

Verwenden der OP-Lösung zum Verschieben verzögerter Daten:

Um zuverlässige Messwerte zu erhalten, müssen Sie zunächst das Dateneingabe-Abtastphasenbit SMPx ändern, um die Daten am Ende anstatt in der Mitte abzutasten, wie ich es nehme. Oder in der Mitte, wenn es jetzt am Ende ist

Geben Sie hier die Bildbeschreibung ein

(Das Bild hat einen Fehler, die erste Kante des "Samples am Ende" ist keine aktive Lesekante.)

Es wäre besser, per Software zu wissen, welche Sample-Kante besser zu verwenden ist.

Die Beschreibung bezieht sich auf SPI-Slave-Verschiebungsdaten an der ersten fallenden Flanke. Für die BISS-Schnittstelle, die ACK an der zweiten ansteigenden Flanke verschiebt, können Sie die erforderlichen Korrekturen vornehmen, indem Sie der Verzögerung 0,5 Tckh oder 1,5 Tckh hinzufügen.

Stellen Sie Ihre SPI-Uhr auf den höchsten verwendbaren Wert Ckh (Tckh-Periode), zählen Sie die Bits, bis ACK eintrifft, ändern Sie das Dateneingabe-Abtastphasenbit SMPx, senden Sie eine weitere Nachricht und zählen Sie die Bits erneut.

Dadurch erhalten Sie eine Annäherung an die Verzögerung um eine halbe Taktperiode. Verwenden Sie diese Option, um den Abtastpunkt für die Uhr auszuwählen, für die Sie tatsächlich Ck (Tck-Periode) verwenden. Wenn die Geschwindigkeit, die Sie verwenden, höchstens halb ist, reicht es aus.

Wenn die Messwerte bis ACK die gleiche Anzahl von "1" haben, liegt die Verzögerung zwischen (N_ones) x Tckh und (N_ones + 1/2) x Tckk

Wenn der Endwert eine "1" mehr hat, liegt die Verzögerung zwischen (N_ones + 1/2) x Tck und N_ones + 1 x Tck

Zurück zur Uhr, die Sie tatsächlich verwenden werden. Wenn eine Multiplikation der Taktperiode Tck den Verzögerungsbereich berührt, verwenden Sie das Sample in der Mitte, wenn nicht, verwenden Sie das Sample am Ende. Wenn Sie Ckh mehr als doppelt verwendet haben, verwenden Sie die Abtastzeit, die am weitesten vom Verzögerungsbereich entfernt ist.

Aktualisieren Sie, korrigieren Sie die invertierte Darstellung des Signals im Text und fügen Sie zum besseren Verständnis eine Grafik hinzu

Gleiche Anzahl von Personen mit schneller Uhr, Verzögerung zwischen 5 und 5,5 Tckh:

Geben Sie hier die Bildbeschreibung ein

Die Abtastung in der Mitte mit der schnellen Uhr zeigt eine zusätzliche "1" an. Verzögerung zwischen 5,5 und 6 Tckh. ( 6 "1" für die Abtastung in der Mitte, nicht 5 wie im Bild )

Geben Sie hier die Bildbeschreibung ein

Verwenden Sie bei Verwendung des SPI-Takts die Abtastflanke, die am weitesten vom Verzögerungsbereich entfernt ist. Geben Sie hier die Bildbeschreibung ein

Die Diagramme wurden mit dem WaveDorm-Online-Editor erstellt

Dorian
quelle
In Bezug auf den ersten Satz gelangt das Signal in sehr guter Form zu SPI (ich bestätige mit Oscillscope mit kurzer GND-Leitung). Die Verzögerung sollte für eine bestimmte Konfiguration (Geschwindigkeit und Länge) konstant sein.
ElectronS
Was Sie präsentiert haben, ist brillant, da ich gerade an der fallenden Flanke abtastet. Ich werde versuchen, dies mit der Geschwindigkeit zu ändern, bei der es nicht funktioniert, und die Ergebnisse sehen. In diesem Fall werde ich eine Art Kalibrierungsfunktion erstellen, die die auswählt Abtastpolarität basierend auf einigen Lesezyklen. Ich werde zurückkommen, wenn ich das Ergebnis bestätigen kann, danke :)
ElectronS
Nach einer Stunde Test hat die von Ihnen vorgeschlagene Lösung teilweise funktioniert (einige Bits sind immer noch falsch), nachdem ich das Problem gefunden habe. Es befindet sich in der Pause zwischen den gesendeten Wörtern. Da ich 16-Bit-Architektur und SPI im 16-Bit-Modus (Wort nicht Byte) verwende und 2 Wörter sende / empfange, gibt es eine Pause von ungefähr 3 Takten zwischen den 2 Wörtern. Diese Verzögerung verursacht ein Problem mit dem Verzögerungskompensationsalgorithmus. JETZT scheint es, als hätte ich herausgefunden, ob ich diese Verzögerung beseitigen kann oder PIC32 (32-Bit-SPI) verwenden muss. Haben Sie irgendwelche Gedanken?
ElectronS
Ich habe einen Screenshot zur Frage hinzugefügt ...
ElectronS
1
Ich wusste, dass der SPI-Slave Daten in SPIbuf haben muss, und ich tat dies, bevor ich die Uhr (Ausgangsvergleich) in der BISS-Lesefunktion erzeugte. Das erste Mal, wenn die Uhr in diesem Moment generiert wird (in OC initalize), befinden sich Zeichen im Puffer. Deshalb habe ich den Punkt verpasst. Es war also wirklich schwierig, das Problem zu kennen. Ich werde eine Antwort mit den Tipps und Tricks veröffentlichen, wenn das helfen würde. aber wirklich danke für die Geduld und die gute Hilfe, die ich brauchte, um mit einem anderen Ingenieurkollegen zu interagieren und mich selbst herauszufordern, hätte es ohne SIE nicht geschafft :))
ElectronS