Hallo, ich sende von einem PC Daten an einen PIC-Prozessor und dieser sendet 2 Bytes zurück (prinzipiell zu erkennen auf Bild 1), was auch funktioniert. Wenn mit Hilfe eines Interrupts ein Byte vom PIC empfangen wird, läuft unten genannter Code ab (Rücksendung der 2 Bytes). Ich hatte nur die Möglichkeit eine lange Pause zu programmieren, so dass sicher ist, dass der PC den Bus wieder freigegeben hat (s. pause(500)) - denn das dauert nicht immer gleich lang (s. auch Bild 2). Gibt es hier die Möglichkeit über eine Flag sofort loszulegen, sobald der Bus frei ist? Danke für eure Hilfe ;) Gruß Olaf while (1) { if (Counter==1) { pause(500); PORTD = 0b.0000.0010; delay_mks(1000); TXREG = test; while(!TRMT==1); // Solange hier warten bis Transmittpuffer leer ist delay_mks(1000); PORTD = 0b.0000.0000; delay_mks(1000); PORTD = 0b.0000.0010; delay_mks(1000); TXREG = addr; while(!TRMT==1); // Solange hier warten bis Transmittpuffer leer ist delay_mks(1000); PORTD = 0b.0000.0000; delay_mks(1000); } }
Hier noch das erste Bild im Anhang - das Hochladen hat irgendwie nicht funktioniert.
Wofür ist delay_mks(1000)? 1 Sekunde warten? Wozu? Wenn ein Byte gesendet wurde, kannst du doch das nächste direkt rauspusten. Bei RS485 wird normalerweise wirklich mit Timeout gearbeitet, d.h. der Sender hat eine maximale Zeit, in der er auf Empfang schaltet, und der Empfänger hat eine minimal längere Zeit, bis er auf Senden schaltet. So wird verhindert, dass es zu Kollisionen kommt. Andere Ansätze lassen den RS485-Empfänger immer aktiv und prüfen das was sie gerade rauspusten gegen das was reinkommt und können so Kollisionen erkennen. Die 500ms am Anfang sind ein bisschen viel, finde ich. Wie funktioniert denn die Richtungsumschaltung am PC? Über DTR? Ralf
Hallo Ralf, > Wofür ist delay_mks(1000)? 1 Sekunde warten? Wozu? Das sind 1000 Mikrosekunden bzw. 1 ms. wobei ich sagen muss die Funktion basiert auf einem 4 MHz Takt und ich verwende einen 20 MHz Quarz - somit sind es rund 200 Mikrosekunden in Realität - muss die Funktion noch entsprechend anpassen. Die kurze Pause habe ich zur Anschaulichkeit reingenommen um es auf dem Oszi überprüfen zu können ob es funktioniert. > Bei RS485 wird normalerweise wirklich mit Timeout gearbeitet, d.h. der Sender hat eine maximale Zeit, in der er auf Empfang schaltet, und der Empfänger hat eine minimal längere Zeit, bis er auf Senden schaltet. Wenn es so ist bin ich ja gar nicht so falsch prinzipiell. Habe nur das Problem dass der PC manchmal deutlich länger braucht - verwende SerialPort in einem VB-Programm. > Die 500ms am Anfang sind ein bisschen viel, finde ich. Sind real nur 100ms wegen dem höheren Takt, allerdings ist dies immer noch recht lang - wenn Übertragung über definierte Zeitscheiben läuft, muss ich einmal schauen was üblich ist. Vielleicht kann ich meinen PC ja doch überreden schneller zu werden, oder ich lasse es auf eine Kollision ankommen und fange den Fehler ab indem ich das entsprechende Byte noch einmal sende. > Über DTR? Ja genau, damit übernimmt der PC die Kontrolle über den Bus. Grüße Olaf
Hi Olaf, okay, das mit dem delay_mks ist jetzt klar... Ich hätte ne Idee, die dich evtl. von den Timing-Problemen bzgl. Umschaltung komplett befreit (und zwar auf jedem Rechner), und so gut wie keine negativen Nebenwirkungen hat. Du könntest einen FT232R verwenden. Damit hast du die Anbindung über USB. Den FT232R kann man so konfigurieren, dass er RS485-Treiber automatisch ansteuert, daher fällt in der Applikation das Umschalten per Software weg. Für deinen Controller ändert sich nichts, da alle Änderungen quasi auf der PC-Seite stattfinden, also vor dem RS485-Treiber deines µCs. Ich nehme an, du hast RS485 gewählt, weil deine Schaltung relativ weit weg vom steuernden PC ist, oder? Sonst kannst du ja den FT232R gleich direkt mit dem µC verknubbeln. Ralf
@Olaf: Kannst Du die Wahl RS485 noch mal überdenken, oder ist das eine Vorgabe? Eine RS422 hat diese Timingprobleme nicht, da es einen TX- und einen RX-Pfad gibt, ist mindestens genauso robust in der Übertragung (Längen, Störungen).
Hallo zusammen, schönen Dank für eure Rückmeldungen. Allerdings möchte ich mein Design nicht ein weiteres Mal umwerfen, der FT232R ist schon ein aufwändigerer Baustein den ich ungerne noch mit aufs Board nehmen würde - zumal es meines Erachtens auch ein wenig oversized wäre bei dem Problem. Es sollte doch ein Flag geben dass man zur Steuerung nehmen könnte, so wie man auch TXREG mit der Schleife "while(!TRMT==1);" gut steuern kann - vielleicht finde ich noch etwas im Datenblatt des PIC16F877. @ was-willst-du: Wie gesagt ich habe die Platinen soweit fertig und will nicht wieder umsatteln, zumal der RS422 nur 10 Empfänger verwalten kann, das reicht bei mir leider nicht. Gruß Olaf
Der FT232R muss ja nicht unbedingt aufs Board, da könntest du auch einmal eine Schaltung aufbauen, und über diese dann weiterhin RS485 machen. Wie gesagt, der FT232R hat ja dafür eine Betriebsart. Zu der Sache mit dem Flag, du hast doch bereits ein Flag, nämlich das Sende-Flag TRMT. Wenn die Übertragung eines Bytes beendet ist, UND es das letzte zu übertragende Byte war, dann Richtung umschalten. Ralf
Zum Thema Flag: Der PC sendet Daten an den Controller, dieser empfängt die Daten (bzw. die Adresse) in der Interrupt-Routine - leider gibt der PC aber den Bus nicht wieder sofort frei nach dem Versenden der Adresse. DTR bleibt noch eine zeitlang eingeschaltet (unterschiedlich lang) und blockiert den Bus. Somit hat der PIC ein Problem den frühesten Zeitpunkt zu finden für die Rücksendung von Daten. Es müsste doch ein Busy-Flag geben, das anzeigt, ob ein anderer Teilnehmer noch die Kontrolle über den Bus hat. Hatte noch mal im Datenblatt gesucht aber nix gefunden. Gruß Olaf
>Es müsste doch ein Busy-Flag geben, das anzeigt, ob ein anderer >Teilnehmer noch die Kontrolle über den Bus hat. Hatte noch mal im >Datenblatt gesucht aber nix gefunden. Gibt's aber nicht. Es gäbe die Möglichkeit, einen CAN-Transceiver statt des RS485-Transceivers zu benutzen, und dann das gesendete Byte gleich weider zu empfangen und mit dem zu vergleichen, was man gerade gesendet hat. Gib es einen Fehler, passiert noch irgendwas auf dem Bus, und man muß etwas warten, bevor man das Byte noch einmal schickt. Das geht nicht unbedingt mit RS485-Transceivern, weil die im Ausgang sehr niederohmig sind.
Läuft man eigentlich Gefahr, dass ein RS485-Transceiver bei einem Buskonflikt beschädigt wird?
Das wäre ein Kurzschluß. Ich vermute, dass die Dinger kurzschlussfest sind, kann es aber nicht genau sagen.
Die nicht bestimmbare Zeit des Umschaltens vom PC von Senden zu Empfangen wird an jedem Rechner unterschiedlich sein, das ist ein... ich nenn's jetzt mal "Feature" von Windows. Das heisst, deine 500ms können am nächsten Rechner Baujahr letztes Jahrtausend schon wieder zu wenig sein, selbst wenn du das DTR-Signal nicht manuell bedienst, sondern den Hardware-Handshake des PC-Uarts verwendest (also der Software-Treiber machts dann selbstständig). Wenn dir das egal ist, weil du die Software eh nur auf einem Rechner verwendest, dann lass die 500ms drin. Ansonsten sag ich nur FT232R (spätestens dann, wenn du einen neuen Rechner kaufst - der garantiert keine RS232 mehr haben wird). Ralf
Ich hatte diese Problem letztens auch. Ich hatte das mit folgender Schaltung gelöst. Die umschaltung wird über ein retriggerbares Monoflop gelöst. Baudrate 9600. Für andere Baudraten ist die Zeitkonstante anzupassen Gruss Helmi
Das Problem liegt hier auf der PC-Seite. Eine softwaremäßige Umschaltung des RS485-Treibers per Steuerleitung der seriellen Schnittstelle ist unter einem Betriebssystem (völlig wurscht, ob Windows oder Linux) reichlich träge. Das lässt sich nur durch Deaktivieren des Sende-FIFOs des Schnittstellenbausteines im PC und Verwenden eines eigenen Devicetreibers halbwegs zuverlässig beschleunigen. Das ist deswegen mittelmäßiger Murks. Viel einfacher aber ist die Verwendung von UART-Hardware mit integrierter RS485-Unterstützung, wie es die UARTs von Oxford Semiconductor oder aber eben die USB-RS232-Bridges von FTDI machen. Dann muss das PC-seitige Programm sich überhaupt nicht mehr um die Steuerung des Treibers übernehmen - und die "andere Seite" der Verbindung, der µC, muss auch keine abstrusen Timeouts beim Antworten einhalten.
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.