Forum: Mikrocontroller und Digitale Elektronik Pulsweitenmessung und vergleich ohne CPU mit dsPIC33


von Alexander L. (linuxleuser)


Lesenswert?

Hallo,
ich habe ein riesen Problem und brauch schlaue Ideen.

Ich habe folgendes vor:
Von einem FPGA (voraussichtlich Altera CycloneII oder III) soll ein 
serielles Signal synchron auf viele (bis zu über 30!) dsPIC Controller 
gebracht werden und von diesen weiter verarbeitet werden. Auch der Takt 
der dsPIC soll mit dem FPGA synchronisiert sein.
Jetzt wird's tricky: alle dsPIC müssen sowohl untereinander als auch zum 
FPGA galvanisch getrennt sein. Einfache Optokoppler reichen auf grund 
des zu großen du/dt nicht aus. Die Übertragungsstrecke soll daher mit 
LWL Verbindungen realisiert werden. Die Datenrate soll deutlich über 
1Mbit liegen.

Bisher habe ich folgenden Ansatz verfolgt:

Datenübertragung via SPI-Schnittstelle des dsPIC (Slave Mode, 
bidirektional).
Das SPI-Clock Signal wird auch als Taktsignal für den gesamten 
Controller verwendet. Daher muss es permanent anliegen.
Um eine 4. (bzw. insg 30) LWL Verbindung (für den Slave-Select)zu sparen 
habe ich mir überlegt die Pulsweite des Taktsignals (5 MHz!, also 
Datenübertragung mit 5Mbaud) zu Modulieren, und via Input-Capture --> 
DMA-Controller --> Output-Compare mir ein Chip-Select daraus zu 
gewinnen.
Das hat auch soweit alles geklappt bis auf eins: Der Ausgang des Output 
Compare Moduls des dsPIC wird auf die Änderung des Timer-Registers TMR3 
(oder 2, habe in diesem fall TMR3) synchronisiert.
D.h. wenn ich den Timer wie geplant stehen lasse und in TMR3 den 
Referenzwert schreibe um den Wert der aktuellen Pulsbreite via DMA in 
das OC1R Register zu schreiben, passiert am Ausgang einfach nichts.
Leider kann ich das nicht umgekehrt machen da sich TMR3 nicht via DMA 
schreiben lässt. Auch kann ich den Timer nicht einfach laufen lassen und 
so einstellen dass er nur ein kleines Stückchen zählt (oder gar auf der 
stelle tritt), da er keine Auto Reload Funktion hat.

- Controller ist der dsPIC33FJ128MC804
- Taktung: EC Mode, PLL so eingestellt dass sich 40 MIPS bei 5MHz 
ergeben
- daher zählt Timer2 auf 8 (0..7) und Input Capture erfasst bei neg. 
Flanke
- der Timer2 ist mit seinem Reset auf die pos. Fl. des Takts 
synchronisiert
- DMA Channel 0 nimmt IC1BUF und schreibt es in den RAM
- DMA Channel 1 nimmt die Daten aus dem RAM und schreibt sie in OC1R
- Entwicklungsumgebung MPLAB IDE v8.84 / Real ICE
- Pulserzeugung zu Testzwecken mit einem Cyclone 1; 1,25..5 MHz;
- Pulsbreite und Takt vom PC aus einstellbar.

Das funktioniert alles soweit. Mit Real ICE zeigt sich dass alles da 
ankommt wo es hin soll. Aber der Output Compare gibt's nicht raus an den 
Pin (der mit dem Slave-Select verbunden ist).
Wenn ich den Vergleich mit der CPU mache und mir auf einen Port mit LED 
gebe, dann funktioniert alles. Das ist jedoch im Betrieb leider absolut 
unmöglich, da ich nicht jeden 8. Maschienenzyklus einen vergleich mit 
der CPU machen kann, ich will ja auch noch was rechnen.
Außerdem wäre die Verzögerung quasi willkürlich was eine 
Datenübertragung quasi unmöglich machen würde.

Ich habe keine Lust das ganze Projekt in die Tonne zu klopfen (steckt 
Wochenlange Arbeit drin) und mit einem anderen Controller oder 
zusätzlicher externer Hardware (wofür ohnehin kein Platz wäre) von vorne 
zu beginne, hat jemand eine Idee? Wie ich das glatt gebüglet bekomme?

von Bronco (Gast)


Lesenswert?

Bei Deinem konkreten Problem kann ich leider nicht helfen (ist ja auch 
echt High-End, Respekt!).

Aber vielleicht wäre das noch eine Idee:
Ich kenne herstellerspezifische ASICs, bei denen das erste Byte eines 
SPI-Frames die Adresse des zu aktivierenden Bausteins enthält. Diese 
ASICs entscheiden beim Empfang des ersten Bytes on the flight, ob sie 
aktiv werden oder nicht. Das kann der dsPIC natürlich nicht (und auch 
kein anderer µC, den ich kenne).
Eventuell könntest Du dem dsPIC noch einen kleinen CPLD spendieren, der 
etwas ähnliches macht, d.h. das erste Byte herausfiltern und je nach 
Inhalt das SlaveSelect des dsPIC aktivieren.

von Alexander L. (linuxleuser)


Lesenswert?

Die Idee ist schon mal garnicht so verkehrt.
Ich hab auch schon in die Richtung gedacht. Bisher hab ich da nicht 
angesetzt weil zusätzliche Hardware viel Aufwand Bedeutet, neue Platine, 
evt. zu knapper Platz etc.

Aber die Diskussion deiner Antwort mit einem Komilitonen hat mich auf 
eine neue Idee gebracht, also dafür schonmal danke.

Folgendes habe ich mir überlegt:
Da ich aufgrund der Potentialtrennung ohnehin zu jedem Controller eine 
extra Leitung habe brauche ich den Chip Select nicht um ihn tatsächlich 
zu adressieren, sondern "nur" um mitzuteilen wann Daten anliegen und das 
SPI Register shiften soll. Den Takt kann ich wie beschrieben ja nicht 
anhalten, da er auch den Prozessor taktet.
Also, warum nicht permanent senden, und immmer wenn Nullen kommen 
ignorieren?
Das kam bissher nicht in frage, weil dann ein einziger versehentlicher 
Shift (zuviel oder auch zu wenig)mir die Kommunikation komplett lahm 
legt. Die Worte würden alle verschoben ankommen, und wären nichtmehr zu 
gebrauchen.
Wenn ich jetzt aber keine Nullen sondern eine feste, eindeutige Sequenz 
sende, solange ich keine Daten zu übertragen habe, kann ich anhand der 
Sequenz erkennen, ob etwas verrutscht ist, und es korrigieren.

Wenn ich das ganze jetzt nicht mit dem dsPIC, sondern im FPGA detektiere 
und dann in einem Steuerwort dem dsPIC mitteile dass er verrutscht ist 
kann ich sogar synchronisationsfehler, die die CPU betreffen (wenn z.B. 
die PLL aus dem Takt geraten ist da eine EMV-Störung eine Flanke zu viel 
am OSC1 erzeugt hat) erkennen und korrigieren, und das ohne gleich alles 
notabschalten zu müssen (das ganze wird die Steuerung eines sehr 
Leistungsfähigen Stromrichters, da darf nichts verrutschen, sonst geht 
ganz schnell, ganz viel schwarzer Rauch auf!).

Ich werde mal versuchen das Prinzip an meinem Testaufbau umzusetzten, 
falls jemand noch ne Idee/Tips hat, immer her damit.
Auch wenn jemandem einfällt warum meine Idee in die Hose gehen könnte, 
einfach posten. Nochmal jede Menge Arbeit für die Tonne würde ich gerne 
vermeiden.

von Bronco (Gast)


Lesenswert?

Willst Du denn auch Daten vom dsPIC zum FPGA zurücksenden?
Falls nicht könnte ja auch jeder dsPIC einfach mithorchen und sich seine 
Pakete heraussuchen.

von Alexander L. (linuxleuser)


Lesenswert?

Zitat aus meinem letzten Post:
 Da ich aufgrund der Potentialtrennung ohnehin zu jedem Controller eine
 extra Leitung habe brauche ich den Chip Select nicht um ihn tatsächlich
 zu adressieren, sondern "nur" um mitzuteilen wann Daten anliegen
Zitat Ende
Mit Leitung meinte ich eine LWL-Strecke, also Sender, Faser und 
Empfänger.

Ja ich will auch zurücksenden, dass ist aber egal, alle ~30 Controller 
können gleichzeitig Fullduplex kommunizieren.
Es geht um die Synchronisierung der Schieberegister der SPI.
Wenn die beiden Register im Sender und Empfänger nicht synchron shiften 
(also nicht nur zur geleichen Zeit um eins weiter, was die Taktleitung 
ja erledigt, sondern auch mit dem selben Puls ein Wort vollständig), 
dann geht das ganze schief, auch das reine Empfangen.

von Bronco (Gast)


Lesenswert?

Du meinst, Du hast 30 Punkt-zu-Punkt-Verbindungen, aber Du hast keine 
separate SlaveSelect-Leitung dabei?
Und Du willst SlaveSelect nicht permanent aktiv halten, weil Du Angst 
hast, die Synchronisierung zu verlieren?

von Alexander L. (linuxleuser)


Lesenswert?

Richtig.
Aber ich habe nicht nur Angst die Synchronisierung zu verlieren, ich 
muss sie erstmal irgendwoher haben. Woher soll das Programm im dsPIC die 
Information nehmen, wann die SPI loslaufen kann? Er weiss ja nicht wann 
der Master (im FPGA realisiert) anfängt das Senderegister zu schiften.
Genau das ist das Problem.

Zitat:
aber Du hast keine
separate SlaveSelect-Leitung dabei?
Und Du willst SlaveSelect nicht permanent aktiv halten,....
Zitat Ende.

Normal braucht man den Slave-Select ja nicht für eine Punkt-zu-Punkt 
Verbindung, da das clock-Signal der SPI ja nur dann überhaupt auftritt, 
wenn das Master-Register geschiftet wird. Damit ist man sicher Synchron.
Da ich mein Clock Signal aber auch als "Taktgeber" am OSC1 Pin verwende 
würde dann ja der ganze Controller stehen bleiben (bzw. nach einer Weile 
auf den internen Oszillator umschalten). D.h. mein Clock signal liegt 
permanent an.

Ich bin im Moment aber ganz zuversichtlich dass mein neuer Ansatz (mit 
Muster-Sequenz) hinhaut.

von Klaus (Gast)


Lesenswert?

Wäre eine Uart Verbindung für dich nicht vielleicht einfacher? Habe kurz 
ins Datenblatt des 128GP804 geschaut. Dort steht bis 10Mbaud auf der 
Uart allerding nur bei 40mips.
Dann hättest du auch Fullduplex und deine Taktleitung ist unabhängig 
davon. Adressierung brauchste ja anscheinend eh nicht da du mit jedem 
separat kommunizierst und die Fehlererkennung mittels CRC-16 oder so.

Ich habe jetzt nur nicht nachgeschaut ob der dsPIC sich die benötigten 
40mips aus deinem 5Mhz Taktsignal mittels PLL generieren kann.

Frage am Rande. Der Master also der FPGA gibt die Sollwerte an die 
dsPICs und diese Liefern die Messwerte zurück? Also die dsPIC steuern 
die Leistungshalbleiter oder habe ich das falsch interpretiert ?

von Alexander L. (linuxleuser)


Lesenswert?

Du hast richtig interpretiert: Aussteuergrade hin, Messwerte zurück.

Wenn du meinen ersten Post ganz liest, dann stellst du fest, dass der 
dsPIC bei mir im Moment bereits mit 40MPIS aus den 5MHz läuft. Das geht 
also.

Aber... nein, das kommt nicht in Frage.
Im Moment ist eben genau dieses Verfahren im Einsatz (UART) und es 
funktioniert auch.
Erfahrungsgemäß ist damit bei 1Mbaud Schluss (zumindest für diese 
Anwendung).
Außerdem hat diese Vorgehensweise auf die eigentliche Anwendung ein paar 
negative Auswirkungen (neben der zu-viel-Zeit-raubenden 
Übertragungsdauer), die (wenn möglich) vermieden werden sollen. Darum 
dieses Redesign mit SPI.

Mehr wie 5MBaud sind mit der Aktuell verwendeten LWL-Technik höchst 
warscheinlich nicht drin. Und die 10Mbaud im Datenblatt der dsPIC33F 
sind wohl auch eher als sehr optimistischer Wert anzusehen.

Hmmm, aber... naja ich muss die UART Hardware ja nicht als UART 
verwenden...
Danke für den Denkanstoß, mir kommen da ein paar Ideen... da muss ich 
nochmal drüber grübeln, bevor ich über ungelegte Eier gackere.

von Alexander L. (linuxleuser)


Lesenswert?

Also, ich habe das ganze jetzt so realisiert, dass der FPGA anhand der 
erwähnten Mustersequenz erkennt in welchem Zustand sich das SPI Modul im 
dsPIC befindet, und sich daran anpasst.
Das funktioniert echt prima.
Später werde ich das ganze noch so erweiteren dass der FPGA mit einem 
Steuerbefehl dem dsPIC mitteilen kann, wenn dieser "verrutschen" soll, 
und wohin er "rutschen" soll. Aber da ich das im Moment nicht brauche, 
bin ich erst mal zufrieden.
Danke für die Vorschläge.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.