Forum: Mikrocontroller und Digitale Elektronik Seriell-zu-Analog Konvertierung


von Kirkenes (Gast)


Lesenswert?

OK, der Betreff mag verwirren, mein Problem ist folgendes:

Ich bekomme seriell 16-Bit-Daten in einem sehr eigenwilligen Format 
gesendet. Faktisch sieht es so aus, dass 20 Bit übertragen werden, darin 
sind 3 zu ignorierende sowie ein Prüfsummenbit enthalten. Das Ende eines 
solchen Frames wird über einen Puls auf einer Sync-Leitung 
gekennzeichnet und jedes Bit wird über eine Clock-Leitung mit jeweils 
einer fallenden Flanke als gültig markiert.

Ich suche jetzt eine preiswerte Lösung, dieses Signal zu decodieren und 
die 16 Bit Nutzlast in einen Analogwert umzuwandeln. Das Empfangen und 
der DAC sind kein Problem. Wo ich jetzt Ideen benötigen würde, wäre der 
Teil mit der Decodierung: wie macht man das am cleversten und 
preiswertesten? Ach ja, Datenleitungen (also die, auf denen die 
Datenbits übertragen werden) gibt es drei Stück.

FPGA-Programmierung kann ich gar nicht, C/C++ und ähnliches ist hingegen 
kein Problem. Der Clock läuft mit 2 MHZ, es kommen als 100000 
Datenpakete pro Sekunde rein.

Ich bin für jeden Denkanstoß dankbar :-)

von H.Joachim S. (crazyhorse)


Lesenswert?

Hm, bei 20 Datenbits ist es ein bisschen blöd mit Hardware-SPI-Empfang, 
können meist nur vielfache von 8bit.
Könnte man per Software-SPI machen, Interrupt auf fallende clk-Flanke, 
Daten sortieren, per Hardware-SPI auf den D/A-Wandler. Da fängt aber 
rel. schnell an, CPU-Takte zu zählen, sollte aber mit nem 16MHz-AVR 
machbar sein.
Reine (einfache) Hardware wäre auch denkbar, wenn die Daten in einem 
sinnvollen Format vorliegen (24bit-Schieberegister, 
16bit-parallel-D/A-Wandler an die passenden Ausgänge anschliessen, 
Übernahme mit dem Synch-Signal.

von Amateur (Gast)


Lesenswert?

@ H.Joachim

Da dürften die AVRs bis 20 MHz mächtig ins Schwitzen kommen.

Flanke detektieren,
Wert speichern und schieben,
Prüfbits auswerten,
gelegentlich D/A-Wandler (???) programmieren.

Und das während 10 Tacktzyklen...

von Moritz A. (moritz_a)


Lesenswert?

H.Joachim Seifert schrieb:
> Hm, bei 20 Datenbits ist es ein bisschen blöd mit Hardware-SPI-Empfang,
> können meist nur vielfache von 8bit.

Das würde ich so nicht unterschreiben.

Zumindest bei Atmel im SPI-Slave-Modus wird der SPI-Interrupt sowohl 
ausgelöst, wenn das Schieberegister "voll" ist, als auch wenn SS high 
geht.

Somit gäbe es hier schon schön alle 8 bit sowie am Ende der Übertragung 
(Sync-Leitung auf SS) einen Interrupt.

So ein xMega A1 oder A3 bietet schon von Haus aus 4 SPI-Interfaces und 
interne 32MHz, womit ggüber den 3x2MHz (+output) noch einiges an Luft 
bleibt, insbesondere da der komplette Empfang bis auf gelegentliches 
Empfangsregister kopieren in Hardware geschieht. Eventuell könnte hier 
durch Nutzung des DMA-Controllers nochmal Rechenzeit gespart werden.

Aber so wie ich den OP verstehe geht es ihm nicht um den Empfang, 
sondern um das dekodieren des ganzen.

Es wäre schon einmal interessant, wo sich das Prüfsummen- und die zu 
ignorierenden Bits befinden. Sind das die vier letzten, oder ist das 
erste Byte nur zur Hälfte Nutzdaten?

Leider hast du auch nicht verraten, wie dein DAC seine Daten gerne 
hätte. Sofern dir hier eine Auflösung von 12bit reicht, könntest du auch 
gleich die im XMega nehmen, der hat 2 DAC mit je 2 Buffern (also 4 
Kanäle), jeder DAC kann 1MSPS bei von dir geforderten 0.1MSPS pro Kanal.

von Kirkenes (Gast)


Lesenswert?

Moritz A. schrieb:
> Aber so wie ich den OP verstehe geht es ihm nicht um den Empfang,
> sondern um das dekodieren des ganzen.

Mit Empfang meine ich den elektrischen Teil, d.h. das Signal von der 
Leitung popeln und in einen Logikpegel für die CPU umwandeln. Das 
Einlesen dieser Signale hätte ich jetzt schon bei "decodieren" 
eingeordnet.

> Es wäre schon einmal interessant, wo sich das Prüfsummen- und die zu
> ignorierenden Bits befinden. Sind das die vier letzten, oder ist das
> erste Byte nur zur Hälfte Nutzdaten?

Die drei zu ignorierenden Bits liegen vorne, das Prüfsummen- bzw. 
Paritätsbit kommt zum Schluss.

> Leider hast du auch nicht verraten, wie dein DAC seine Daten gerne
> hätte. Sofern dir hier eine Auflösung von 12bit reicht, könntest du auch
> gleich die im XMega nehmen, der hat 2 DAC mit je 2 Buffern (also 4
> Kanäle), jeder DAC kann 1MSPS bei von dir geforderten 0.1MSPS pro Kanal.

Nö, es muss schon ein 16Bit DAC sein, d.h. so wie ich das bisher sehe, 
müssen für jeden Zyklus 24 Bit in selbigen geschoben werden (zumindest 
habe ich bisher keinen reinen 16-Bit-DAC gefunden, der nicht zusätzlich 
noch ein paar Steuerbits haben will und nicht horrend teuer ist).

von Moritz A. (moritz_a)


Lesenswert?

Um ehrlich zu sein, dann sehe ich da das riesige Problem nicht.

Nutze wie beschrieben 3xHardware-SPI für die Eingänge, shifte die Daten 
passend zurecht, und schicke das ganze zum Hardware-SPI raus.

Wenn du für das ganze jetzt die vier DMA-Kanäle mit entsprechendem 
Source/Destination-Increment verwendest, brauchst du wohl neben der 
Initialisierung nur noch 4 Interrupt-Routinen die dir mitteilen wenn 
einer der vier DMA-Transfers fertig ist.

Somit hast du das Lesen von dreimal je 3Byte sowie verschicken von 
3x3=9Byte  komplett asynchron aufs DMA ausgelagert, und brauchst nur 
noch passende Statusflags in deiner main ob neue Daten ankamen, musst da 
die Daten evtl. überprüfen und dann passend für den DAC bereitmachen.

Sinnvollerweise würde ich für den Ausgang den Speicher doppelt 
vorhalten, eine Region zum darauf arbeiten und auf der anderen arbeitet 
der DMA-Controller. Damit kann es dir nicht passieren, dass du gerade im 
Senden befindliche Daten aus versehen bearbeitest.

von Bernhard F. (bernhard_fr)


Lesenswert?

Die Frage mag jetzt vieleicht zwar dumm klingen, denn so ein Parity-bit 
wird ja nicht nur zum Spaß übertragen...

Soll das Parity-bit ausgewertet werden?

Und wenn ja:

Gehören die zu ignorierenden 3 bits mit zur Berechnung dessen?
Was soll passieren wenn ein Paritätsfehler auftritt? Frame einfach 
verwerfen und gut ist?

von Kirkenes (Gast)


Lesenswert?

Moritz A. schrieb:
> Um ehrlich zu sein, dann sehe ich da das riesige Problem nicht.
>
> Nutze wie beschrieben 3xHardware-SPI für die Eingänge, shifte die Daten
> passend zurecht, und schicke das ganze zum Hardware-SPI raus.

Ich sehe das Problem im Sync-Signal. Bei SPI ist dieses während der 
ganzen übertragung aktiv, richtig? In dem Fall ist das Sync aber nur auf 
das letzte Bit aktiv, es ist halt wirklich ein Synchronisationsignal und 
nicht wie bei SPI ein Schreibsignal.

von Kirkenes (Gast)


Lesenswert?

Bernhard F. schrieb:
> Was soll passieren wenn ein Paritätsfehler auftritt? Frame einfach
> verwerfen und gut ist?

Ja

von Moritz A. (moritz_a)


Lesenswert?

Kirkenes schrieb:
> Ich sehe das Problem im Sync-Signal. Bei SPI ist dieses während der
> ganzen übertragung aktiv, richtig? In dem Fall ist das Sync aber nur auf
> das letzte Bit aktiv, es ist halt wirklich ein Synchronisationsignal und
> nicht wie bei SPI ein Schreibsignal.

Du musst aufpassen, was Aktiv heißt. CS ist Aktiv-Low.

Ich verstand das Ausgabeformat so, dass die Quelle immer 20 Bit schickt, 
und daraufhin Sync einmal hoch-pulst. Wenn keine Daten kommen, steht 
auch die Clock-Leitung  still. Ansonsten ließen sich ja keine Daten 
nicht von Null-Daten unterscheiden.

Was passiert bei SPI? Für eine Übertragung wird CS Low-gesetzt, über 
MOSI/CLK die Daten auf die Taktflanken synchronisiert ausgegeben, am 
Ende der Übertragung wird CS High gezogen.

Also entspricht das ganze wirklich 1:1 SPI, auch wenn die Daten anders 
heißen.

Falls Sync wirklich mit dem letzten Bit und nicht erst danach 
hochgeht, lässt sich hier über ein Schieberegister (74HC4015 o.ä.)  an 
der Clock-Leitung die Weitergabe des Sync-Impulses wunderbar um ein Takt 
verzögern.

: Bearbeitet durch User
von Andreas D (Gast)


Lesenswert?

Da ich ein PSoC-Fan bin, wuerde ich einen PSoC verwenden,
und dort in der erhaltenen programmierbarne Logik das Schiebe-Register
(mit sync - Signal) implementieren.
PSoC 3 oder 4 reicht wahrscheinlich, die PSoC 4 sind gerade sehr 
guenstig.

Andreas

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.