Forum: Mikrocontroller und Digitale Elektronik RS485 - Lange Pausen zwischen Datenpaketen


von Olaf R. (gruser)


Angehängte Dateien:

Lesenswert?

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);
    }
  }

von Olaf R. (gruser)


Angehängte Dateien:

Lesenswert?

Hier noch das erste Bild im Anhang - das Hochladen hat irgendwie nicht 
funktioniert.

von Ralf (Gast)


Lesenswert?

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

von Olaf R. (gruser)


Lesenswert?

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

von Ralf (Gast)


Lesenswert?

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

von was-willst-du (Gast)


Lesenswert?

@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).

von Olaf R. (gruser)


Lesenswert?

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

von sfhgsfhfgh (Gast)


Lesenswert?

rs485 gibts auch 4-drähtig, dann voll duplex

von Ralf (Gast)


Lesenswert?

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

von Olaf R. (gruser)


Lesenswert?

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

von STK500-Besitzer (Gast)


Lesenswert?

>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.

von Olaf R. (gruser)


Lesenswert?

Läuft man eigentlich Gefahr, dass ein RS485-Transceiver bei einem 
Buskonflikt beschädigt wird?

von STK500-Besitzer (Gast)


Lesenswert?

Das wäre ein Kurzschluß. Ich vermute, dass die Dinger kurzschlussfest 
sind, kann es aber nicht genau sagen.

von Ralf (Gast)


Lesenswert?

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

von Helmut L. (helmi1)


Angehängte Dateien:

Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.