Forum: FPGA, VHDL & Co. serielle Kommunikation RS-485 zwischen FPGA und DSPACE


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jonas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe mal eine Frage bezüglich der seriellen Kommunikation. Da ich 
nicht wirklich weiter komme, dachte ich, ich versuche mir mal Hilfe 
ranzuholen. Ich habe schon viele Foren Beiträge gelesen, wurde daraus 
aber nicht wirklich schlauer.

Ich versuche eine serielle Kommunikation zwischen einem FPGA und einem 
DSPACE herzustellen. Dafür will ich die RS-485 Schnittstelle verwenden. 
Auf den FPGA will ich einen UART-Code (vhdl) flashen und den DSPACE 
entweder als Empfänger oder Sender verwenden. Es geht mir erstmal darum, 
dass die zwei Geräte untereinander kommunizieren können.

Der UART-Code soll dafür sorgen, dass die Signale richtig empfangen bzw. 
gesendet werden. Hierfür tastet er das Signal ab und erkennt die Start 
Bit, 8 Data Bits und die Stop Bit. Die Clock-Frequenz und die Baudrate 
gebe ich dabei vor (50 MHz und 115200 baud). Den UART-Code habe ich 
unten verlinkt.


Nun zu meinen Fragen:

1) Die RS485 Schnittstelle arbeitet mit den Spannungspegeln von maximal 
-7V (logisch '1') und +12V (logisch '0'). Da der untere Pegel (-7V) die 
'1' darstellt, muss das Signal invertiert werden. Dies geschieht über 
einen TTL to RS485 Converter.  Dies habe ich zumindest nach meiner 
Recherche so verstanden. Ist das richtig so? Es sollte dann ja reichen, 
wenn er das Signal auf -5V und +5V konvertiert oder?


2) Ich verstehe noch nicht so ganz, wie die Signale aus meinem UART Code 
den Signalen A und B der RS-485 Schnittstelle entsprechen. Die Leitungen 
A und B sollen ja symmetrisch sein, d.h. A ist das Komplementär von B 
und umgekehrt. Der UART Code gibt ja aber nur ein Signal raus, entweder 
RX oder TX. Geschieht die Invertierung des zu sendenden bzw. zu 
empfangenden Signal dann ebenfalls in dem Converter oder wie muss ich 
das implementieren? Ist mein UART-Code generell korrekt für eine RS-485 
Schnittstelle?


3) Ich bin noch nicht genau schlau daraus geworden, wie ich meine 
Signale mit dem Converter verbinden muss. Angennommen der FPGA soll 
senden und der DSPACE empfangen. Der FPGA bekommt von mir den zu 
sendenen Wert über das i_TX_Byte Signal zugewiesen (z.B. X"AA"). Die 
Clock erhält er auch intern. Über einen Knopfdruck gebe ich dem FPGA das 
Signal, dass er senden darf (i_TX_DV). Aus meinem Verständnis her würde 
ich dann das TX Signal (o_TX_Serial) an den Converter führen (an TX). 
Ich verstehe aber nicht, wie ich meine restlichen Signal herausfürhren 
soll, da ich ja effektiv nur 2 Leitungen habe. Bei meinem aktuellen Code 
brauche ich ja aber z.B. mein o_TX_Done Signal, damit eine neue 
Übertragung beginnen kann



Ich wäre über jede Hilfe sehr dankbar, da ich jetzt echt schon lange 
daran sitze und am mittlerweile echt am verzwifeln bin.

Meinen UART-Code habe ich von hier:
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html

Bei UART_RX habe ich die Signal o_RX_DV und o_RX_Byte auskommentiert, da 
diese ja nur Feedback über eine richtige Übertragung geben. Soll ich die 
Signal bei UART_TX dann auch auskommentieren (also o_TX_ACTIVE und 
o_TX_Done)? Das macht den Code aus meiner Sicht aber fehleranfälliger. 
Der Code ist soweit ich weiß, aber auch für alle 9 Pins des Sub-D 
Steckers gedacht.

von Duke Scarring (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Jonas schrieb:
> Ich versuche eine serielle Kommunikation zwischen einem FPGA und einem
> DSPACE herzustellen.
Meine Kommunikation mit DSPACE läuft über einen Browser, das Internet 
und deren Webserver.

Du darfst gerne konkreter werden, welche Hardware tatsächlich zum 
Einsatz kommt. Auch auf FPGA-Seite.

> Es sollte dann ja reichen,
> wenn er das Signal auf -5V und +5V konvertiert oder?
Mit diesen Spannungen bekommst Du Deinen FPGA mit Sicherheit kaputt, 
wenn die direkt auf die Pins gehen.

Der Leitungstreiber macht üblicher die Pegelanpassung und die 
differentielle Signalaufbereitung.

Mit welchen Spannungen Dein FPGA arbeiten kann, kannst Du aus dem 
Datenblatt entnehmen. Wenn Du ein fertiges Board hast, hat der Designer 
sich üblicherweise für eine feste Logikspannung entschieden (die aber je 
nach Pin auch anders sein kann, Stichwort: IO-Bänke).
Heutzutage sind da maximal Spannungen von 3,3 V üblich, z.T. deutlich 
weniger.

Duke

von D-spacer (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
RS-485-Converter/Driver ans FPGA und einen käuflichen an den PC.

von Jonas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Also auf der FPGA Seite ist ein Spartan 6 Board. Das FPGA (XC6SLX100) 
liegt auf einem Trägerboard TE0603.
Auf der DSPACE Seite ist der Prozessor eine DS1007 Prozessor Karte und 
ein DS2202 Board auf dem direkt die RS485 Schnittstelle vorhanden ist. 
Das heißt auf dieser Seite stecke ich den Sub-D ganz normal ein.

So wenn ich das jetzt richtig verstanden habe geht ich jetzt auf der 
anderen Seite (FPGA) Seite von dem Sub-D Stecker auf einen 
Treiberbautstein (z.B. MAX490CSA+), welcher mit 5V versorgt wird und 
mein Signal in 3.3V umwandelt, sodass das FPGA Board dies vertragen 
kann. Der Treiberbaustein invertiert das Signal und löst bzw. stellt die 
Differenz der Leitungen A und B auf.

Stimmt das so? Vielen DAnk schonmal für die schnelle Antwort

von Martin S. (strubi)


Bewertung
0 lesenswert
nicht lesenswert
Moin,

ohne jetzt den VHDL-Code angesehen zu haben: Schau dir doch erst mal die 
Funktionsweise eines RS485-Transceivers an, angefangen mit den einfachen 
MAX485 (aber in 3.3V Ausführung). Wichtig ist nur der DE, der bestimmt, 
wann der Treiber auf den Bus treibt, während eines Datenpakets im 
half-Duplex-Betrieb geht der bloss HIGH. Beim einfachen UART wird der 
RTS für den DE 'missbraucht', das geht auch in den meisten Fällen. Nur 
wenn die Timings kritisch sind (Modbus oder Realtime-Systeme) kann's mit 
der software-mässigen Implementierung knifflig werden, dann empfiehlt 
sich ein UART-Core mit HW-implementiertem RS485-Modus. Ist aber erst mal 
was für später...

Hier grad noch einen Link ausgegraben:

https://www.logic-control.com/datasheets/4/Tech%20Note/The%20Secrets%20of%20RS-485%20Half%20Duplex%20Communication.pdf

von Jonas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Also ein RS485 transceiver wird nach meinem Verständnis mit einer 
Spannung versorgt(hier 3.3V). Die Pins für die eigentliche RS485 Leitung 
sind dann A und B (oder D+ und D-), wobei A das Komplementär von B ist 
und umgekehrt. Das sind dann die beiden Leitungen, die ich auch an den 
Sub-D Stecker anschließen kann. Über den D Eingang bekommt der RS485 
Transceiver den DATA Input und über R den DATA Output.

Der DE Pin (Driver Enable) ist der wichtigste Pin (wahrscheinlich um 
Kollisionen zu vermeiden) und gibt an, ob Daten gesendet werden (dann 
High-Pegel). Das heißt, wenn ich das so richtig verstehe sollte ich 
diesem Pin das Signal o_TX_Active meines UART Codes zuweisen, damit ich 
sagen kann, wann Daten gesendet werden sollen.
Ich verstehe aber nicht wie der RTS (Request to send) für den DE 
missbraucht wird. Der DE gibt doch an, wann Daten gesendet werden. Der 
RTS gibt doch aber bevor die Daten gesendet werden ein Signal, dass 
signalisiert, dass gleich Daten gesendet werden

Der RE Pin (Receiver Enable) gibt an, ob der Receiver empfängt (mit 
einem Low Pegel). Wenn ich diesen Pin frei lasse, ist dann der Receiver 
dauerhaft aktiv, solange der Transceiver nicht aktiv ist? Ich vermute 
mal nein...

von D-spacer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Jonas schrieb:
> Ich verstehe aber nicht wie der RTS (Request to send) für den DE
> missbraucht wird. Der DE gibt doch an, wann Daten gesendet werden. Der
> RTS gibt doch aber bevor die Daten gesendet werden ein Signal, dass
> signalisiert, dass gleich Daten gesendet werden
>
> Der RE Pin (Receiver Enable) gibt an, ob der Receiver empfängt (mit
> einem Low Pegel). Wenn ich diesen Pin frei lasse, ist dann der Receiver
> dauerhaft aktiv, solange der Transceiver nicht aktiv ist? Ich vermute
> mal nein...

Das ist ok wenn das timingmässig passt.
In Einzelfällen hat man einen langsamen Receiver, der das Ready signal 
haben mus, bevor es beginnt. Wenn das aber echt hardware ist, muss der 
Sender sicherstellen, dass er nicht beginnt zu senden, solange der 
andere oder "ein anderer" aktiv ist. Das ist eine Aufgabe der time slot 
Verwaltung im System.

HW-technisch ist das Jacke wie Hose.

Wir haben solche Signale auch schon über Gates gezogen, um sie noch ein 
paar Dutzend ns zu verschleppen, damit es keine Kollisionen gibt.

Mal dir mal ein Timing auf.

von Duke Scarring (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Jonas schrieb:
> Der DE Pin (Driver Enable) ist der wichtigste Pin (wahrscheinlich um
> Kollisionen zu vermeiden) und gibt an, ob Daten gesendet werden (dann
> High-Pegel).
Richtig.
So wie im Anhang sollte es nicht aussehen.

Duke

von Martin S. (strubi)


Bewertung
0 lesenswert
nicht lesenswert
Jonas schrieb:

>
> Der DE Pin (Driver Enable) ist der wichtigste Pin (wahrscheinlich um
> Kollisionen zu vermeiden) und gibt an, ob Daten gesendet werden (dann
> High-Pegel). Das heißt, wenn ich das so richtig verstehe sollte ich
> diesem Pin das Signal o_TX_Active meines UART Codes zuweisen, damit ich
> sagen kann, wann Daten gesendet werden sollen.
> Ich verstehe aber nicht wie der RTS (Request to send) für den DE
> missbraucht wird. Der DE gibt doch an, wann Daten gesendet werden. Der
> RTS gibt doch aber bevor die Daten gesendet werden ein Signal, dass
> signalisiert, dass gleich Daten gesendet werden
>

Mach doch mal ne Simulation, damit man deine Timings sieht. Kann schon 
klappen bei ner niedrigen Baudrate.
Ein dauernd toggelndes TX_Active für jedes einzelne Byte kann allerdings 
unter Umständen Probleme machen, insbesondere wenn du was wie Modbus 
laufen hast, da sind die Timings und Timeouts essentiell.
Mit dem RTS hast du mehr softe Kontrolle über den enable über die Dauer 
deines Datenpakets, bzw. harte Kontrolle wenn du einen RS485_MODE 
implementierst.

> Der RE Pin (Receiver Enable) gibt an, ob der Receiver empfängt (mit
> einem Low Pegel). Wenn ich diesen Pin frei lasse, ist dann der Receiver
> dauerhaft aktiv, solange der Transceiver nicht aktiv ist? Ich vermute
> mal nein...

Den Pin solltest du typischerweise nicht floaten lassen, da er 
invertiert, hängt man ihn normalerweise mit dem DE zusammen, am FPGA 
kannst du sie ja logisch gleichzeitig treiben und hältst dir weitere 
Optionen ("Shutdown/Loopback") offen.

von Jonas (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Duke Scarring schrieb:
> Richtig.
> So wie im Anhang sollte es nicht aussehen.

Ja das macht Sinn. So sieht es bei mir aber derzeit nicht aus

Martin S. schrieb:
> Mach doch mal ne Simulation, damit man deine Timings sieht. Kann schon
> klappen bei ner niedrigen Baudrate.
> Ein dauernd toggelndes TX_Active für jedes einzelne Byte kann allerdings
> unter Umständen Probleme machen, insbesondere wenn du was wie Modbus
> laufen hast, da sind die Timings und Timeouts essentiell.
> Mit dem RTS hast du mehr softe Kontrolle über den enable über die Dauer
> deines Datenpakets, bzw. harte Kontrolle wenn du einen RS485_MODE
> implementierst.

Ich habe meinen UART-Code in ModelSim bereits simuliert. Dort klappt 
alles soweit. Mein TX_Active toogelt aber quasi pro Byte. Die Baudrate 
ist 115200 und die Clock des FPGA 50 MHz. Ich würde gerne ein Bild der 
Simulation anhängen, allerdings ist es schwer dort alles zu erkennen. 
Ich habe es dennoch mal angehangen. Nach dem Senden wird bei mir 
testweise ein Byte zum Empfangen geschickt.
Mit meiner aktuellen Baudrate würde ich schätzen, dass das toggle nicht 
zu stark ist.

Den DE und RE Pin werde ich dann zusammen schalten

von Jonas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe nochmal eine Frage:
Auf der DSPACE-Seite sitzt jetzt eine DS1007 Prozessorkarte und eine 
DS2202 HiL I/O Karte inkl. Controller Panel. Auf dem Panel befindet sich 
die Schnittstelle RS232/RS422, an die ich gerne mit meinem Sub-D Stecker 
gehen möchte. Damit ich eine serielle Kommunikation zwischen dem FPGA 
und DSPACE über RS485 herstellen kann, muss ich ja auf der DSPACE Seite 
einstellen können, wann der Sender und wann der Empfänger aktiv ist, 
damit es nicht zu Kurzschlüssen kommt.
So wie ich das verstanden habe ist der UART Code, sowie der 
Treiberbaustein für RS232 bzw. RS485 ja bereits in dem DSPACE Board 
verbaut, d.h. ich habe da ja nicht wirklich Einfluss drauf. Schaltet das 
DSPACE Board dann automatisch zwischen Sender und Empfänger über das RTS 
Signal hin und her oder muss ich da noch was machen?

Leider ist in der Uni das passende Handbuch zu der Karte abhanden 
gekommen, sodass ich dort nicht direkt reinschauen kann..

Ich wäre über jede Hilfe sehr dankbar :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.