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.
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
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
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
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...
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.
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
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.
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
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 :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.