Ich habe ein Problem mit meiner RS485 Schnittstelle. Ich frage mich ob das Problem von der Schaltung oder meiner Software herrührt: Ich benutze ein 6Byte langes Protokoll: CMD | ID | Position | State | CRC0 | CRC1 Wenn ich das komplette Kommando vom PC über den RS485 Bus zum Controller sende, passiert nichts. Sende ich allerdings jedes Byte einzeln, also durch meine Eingabe verzögert, funktioniert das Protokoll und der Controller reagiert korrekt darauf. Ich hoffe das es kein Hardware Problem ist, sondern nur von der Software. Was denkt ihr?
:
Bearbeitet durch User
Da waer nun ein Debugkonzept noetig. Wie werden die Nachrichten auseinandergenommen ? - Natuerlich mit einer Zustandsmaschine Dann mach die Zustaende extern sichtbar, zB mit 2 Extra pins, die du hoch und runter ziehst je nach Zustand, in der die Maschine steht. Und dann mit dem Oszilloskop zuschauen.
Fabian S. schrieb: > Was denkt ihr? Ich denke, es liegt an der Übertragungsgeschwindigkeit, an der Verarbeitungsgeschwindigkeit oder an der Hardware.
Fabian S. schrieb: > Sende ich allerdings jedes Byte einzeln, also durch meine Eingabe > verzögert, funktioniert das Protokoll und der Controller reagiert > korrekt darauf. Sendest du wirklich nur das eine Nutzbyte, oder wird da auch noch CR/LF drangehängt? (Eingabetaste) Kurt
100nF schrieb: > 100nF am MAX fehlen. > Du meinst die 100nF zwischen VSS und GND? Die Spannungsversorgung von dem Board wird mit einem Traco erzeugt und sollte sehr geringe Restwelligkeit aufweisen. Die Spannung wird auch durch Caps gestützt und befiltert. > Wie sehen A und B aus? > Habe zZ leider keine Scope-Darstellungen von den Signalen aber im Logic Analyser sieht alles ganz gut aus. Werde die Tage mal Bilder dazu machen. Oh D. schrieb: > Da waer nun ein Debugkonzept noetig. > Wie werden die Nachrichten auseinandergenommen ? > - Natuerlich mit einer Zustandsmaschine > > Dann mach die Zustaende extern sichtbar, zB mit 2 Extra pins, die du > hoch und runter ziehst je nach Zustand, in der die Maschine steht. Und > dann mit dem Oszilloskop zuschauen. > Wie gesagt die States werden alle korrekt erreicht wenn ich die Nachricht Byte-Weise im hterm eingebe und nicht in einem Stück. Ich werde in den kommenden Tagen nochmal herausfinden in wie fern die Bytes verarbeitet werden und wo das Programm hängt bzw. die Nachricht als ungültig verwirft. Stefan U. schrieb: > Vielleicht holt dein Programm die empfangenen Bytes zu langsam ab. > Wie könnte ich es beschleunigen? Ich werde mal ein minimal Beispiel aus meinem Programm extrahieren...
>> Oh D. schrieb: Da waer nun ein Debugkonzept noetig. Wie werden die Nachrichten auseinandergenommen ? - Natuerlich mit einer Zustandsmaschine Dann mach die Zustaende extern sichtbar, zB mit 2 Extra pins, die du hoch und runter ziehst je nach Zustand, in der die Maschine steht. Und dann mit dem Oszilloskop zuschauen. >Wie gesagt die States werden alle korrekt erreicht wenn ich die Nachricht Byte-Weise im hterm eingebe und nicht in einem Stück. Ich werde in den kommenden Tagen nochmal herausfinden in wie fern die Bytes verarbeitet werden und wo das Programm hängt bzw. die Nachricht als >ungültig verwirft. Also werden die states nicht erreicht. Dann miss doch mal nach wie die States sich verhalten wenn alles am stueck kommt.
Fabian S. schrieb: > 100nF schrieb: >> 100nF am MAX fehlen. >> > Du meinst die 100nF zwischen VSS und GND? Die Spannungsversorgung von > dem Board wird mit einem Traco erzeugt und sollte sehr geringe > Restwelligkeit aufweisen. Die Spannung wird auch durch Caps gestützt und > befiltert. Schön. Trotzdem fehlen die 100nF. Ein CAP am anderen Ende vom Board nützt Nix. Der ist viel zu weit weg und viel zu langsam. Gleiches gilt für den Xmega. Der hat 4x VCC/GND. Fehlen 2x 100nF. Das schlimme ist: Es funktioniert trotzdem (meistens). > Habe zZ leider keine Scope-Darstellungen von den Signalen aber im Logic > Analyser sieht alles ganz gut aus. Werde die Tage mal Bilder dazu > machen. Ja, Bitte. Wertest du die Fehlerbits vom UART aus? Hast du Bias Widerstände am Bus? Gemeinsamer GND? Wie erkennt der AVR den Start eines Paketes? 2. RS232 am AVR Vorhanden zum debuggen? > Stefan U. schrieb: >> Vielleicht holt dein Programm die empfangenen Bytes zu langsam ab. >> > Wie könnte ich es beschleunigen? Falsche Frage. Du kannst nur etwas beschleunigen wenn du weist wie schnell es ist. Also setzte bei eintritt in die ISR ein Pin und schalte es beim verlassen wieder aus. Dann Oszi dran und ablesen. Code?
Hallo Fabian S. Es riecht nach einem Timingproblem beim Einschalten des Senders. Heisst der Sender ist noch nicht ganz aktiviert wenn die Daten gesendet werden. Oder er deaktiviert den Sender zu früh. Zusätzlich würde ich prüfen, dass der Empfänger nicht zwischendurch selbst den Sender aktiviert. Gruss Limi
Also ich habe mal ein wenig herumprobiert... Zur Zeit sieht es wie folgt aus: Wenn ich alle Bytes händisch nacheinander sende (quasi mit Verzögerung), werden die Kommandos korrekt erkannt und abgearbeitet. Wenn ich dagegen die Bytes als Burst (direkt nacheinander) sende, wird ein CRC Fehler entdeckt. Daraufhin wird natürlich kein Kommando mehr ausgeführt. Die Signale auf dem USART sehen dann aus wie auf dem beigefügten Screenshot. Man kann hier erkennen, das der Fehler erst nach dem 7. Byte, also dem ersten Byte der zweiten Nachricht auftaucht. Ich denke deshalb, das es kein HW sondern ein SW Problem ist. Ich werde als nächstes ein minimal Beispiel des Programms schreiben, das nur die Kommunikation abarbeitet und keine Kommandos ausführt. Mal schauen ob ich dadurch das Problem eingrenzen kann.
Fabian S. schrieb: > Wenn ich alle Bytes händisch nacheinander sende (quasi mit Verzögerung), > werden die Kommandos korrekt erkannt und abgearbeitet. > Wenn ich dagegen die Bytes als Burst (direkt nacheinander) sende, wird > ein CRC Fehler entdeckt. Hey Fabian, Wie viel Zeit vergeht denn, nach dem Stoppbit bis zum nächsten Startbit? (ich kann das auf deinem Bild nciht genau erkennen) Vielleicht baust du hier mal ein Delay von einer halben "Bit-zeit" ein... oder einfach ein zweites Stoppbit. lg Chris
...ich hatte auch mal ein Problem nach dem aktivieren des RS485 Bausteins (also Driver enable -> High), - da wurde nach dem einschalten des Bausteins vom Empfänger ein Startbit erkannt und somit immer das erste Byte um ein Bit "verschoben". Also Interessant wäre, wenn du dein Uart-Oszilloskop Bild (also die Signale zwischen RS485 Baustein und dem Mikrocontroller) gegen die RS485-Signale vergleichst. Grüße Chris
Christoph R. schrieb: > Hey Fabian, > Wie viel Zeit vergeht denn, nach dem Stoppbit bis zum nächsten Startbit? > (ich kann das auf deinem Bild nciht genau erkennen) Vielleicht baust du > hier mal ein Delay von einer halben "Bit-zeit" ein... oder einfach ein > zweites Stoppbit. > lg Chris Ich sende mit 115200Bd, einer Datenlänge von 8Bit, einem Stopbit und ohne Parity. Jedes Byte dauert laut Logic Analyzer 86.5µs (inklusive Start- und Stopbits). Ein Bit wird in 8.66µs übertragen. Somit wird ein Startbit und 1 Stopbit (mit 8.66µs) pro Wort gesendet.
Christoph R. schrieb: > da wurde nach dem einschalten > des Bausteins vom Empfänger ein Startbit erkannt und somit immer das > erste Byte um ein Bit "verschoben". Und dagegen helfen die Biaswiderstaende... Die sorgen dafuer das der RS485 Bausteine wenn keiner sendet auf den richtigen Pegel fuer den UART am Ausgang geht
Ok. Das könnte wirklich ein Problem sein mit diesen Biaswiderständen... Der Pegel vom nicht-invertierten Kanal (A) ist per default Low, sowie bei Kabal B. (vgl rs485.png) Ich habe den Kanal A testweise mit einen 560 Ohm Widerstand auf 5V gezogen (externe Spannungsquelle mit gemeinsamer Masse). Leider bleibt Kanal A dann immer auf einem Pegel "kleben". (vgl kleber.png) Anbei nochmal eine Darstellung der Signale wenn der Controller sendet (ohne Polling) -> sender.png
Helmut L. schrieb: > Christoph R. schrieb: >> da wurde nach dem einschalten >> des Bausteins vom Empfänger ein Startbit erkannt und somit immer das >> erste Byte um ein Bit "verschoben". > > Und dagegen helfen die Biaswiderstaende... Die sorgen dafuer das der > RS485 Bausteine wenn keiner sendet auf den richtigen Pegel fuer den UART > am Ausgang geht Hi Helmut, Ich komme eher aus der Software Ecke, - kannst du mir bitte kurz erklären, wo die Widerstände hingehören, die du meinst? sind das die 120Ohm zwischen A und B? lg Chris
Fabian S. schrieb: > Ok. Das könnte wirklich ein Problem sein mit diesen Biaswiderständen... du kannst ja testweise den A-Kanal komplett auftrennen, - sollte dann immer noch nur mit B funktionieren.
Christoph R. schrieb: > Ich komme eher aus der Software Ecke, - kannst du mir bitte kurz > erklären, wo die Widerstände hingehören, die du meinst? sind das die > 120Ohm zwischen A und B? Ne, der 120 Ohm ist der Leitungsabschluss. Du brauchst 2 Widerstaende zusaetzlich. VCC------ca. 1K ------+-----120-----+------ca. 1K----GND | | A (+) B (-) So fallen dann ca. 0.3V am 120 Ohm ab und der Ausgang vom MAX geht auf '1' Pegel. Das ist ja auch der Ruhepegel beim UART. Kommen jetzt Daten an wird dieser Pegel einfach ueberschrieben. Es ist dann ein definierter Pegel da wenn die Gegenstelle auf Tristae geht.
Kann es sein, dass Dein Quarz für diese hohe Übertragungsrate nicht geeignet ist? Das mit den Teilerfaktoren kann ganz schön nerven... Zwei Sachen würde ich Dir empfehlen: 1. Baudratenquarz einbauen. Oder etwas langsamer Babbeln. 2. Das Übertragungsprotokoll mit 2 Stoppbits versehen. Es gibt da ein paar Bitmuster, die die Anfangserkennung, des nächsten Datums erschweren. Vor allem, wenn die Teilung nicht stimmt.
Amateur schrieb: > Kann es sein, dass Dein Quarz für diese hohe Übertragungsrate nicht > geeignet ist? Das mit den Teilerfaktoren kann ganz schön nerven... > > Zwei Sachen würde ich Dir empfehlen: > 1. Baudratenquarz einbauen. Oder etwas langsamer Babbeln. > 2. Das Übertragungsprotokoll mit 2 Stoppbits versehen. > Es gibt da ein paar Bitmuster, die die Anfangserkennung, des > nächsten Datums erschweren. Vor allem, wenn die Teilung nicht > stimmt. Es ist erstaunlich, aber mit 2 Stoppbits funktioniert es! Für mich stellt sich nur die Frage warum es nicht mit einem klappt?!
Leider sind die zwei Stoppbit nicht kompatibel zu dem Rest des Systems... Also geht die Suche nach dem Ursprung des Fehlers weiter
Hi >Leider sind die zwei Stoppbit nicht kompatibel zu dem Rest des >Systems... Wieso nicht? MfG Spess
Fabian S. schrieb: > Leider sind die zwei Stoppbit nicht kompatibel zu dem Rest des > Systems... Das gibt es nicht. Es könnte ja nach dem Zeichen kein weiteres mehr kommen, daher sind 2, 3, viele Stoppbits selbstverständlich korrekt. Empfänger setzen sowieso nur 1 Stoppbit voraus und sind dann zufrieden bis zum nächsten Startbit. Die Einstellung "2 Stopbits" wirkt bei UARTs nur auf den Sender. Wahrscheinlich liegt dein Fehler aber immer noch ganz woanders, denn dass eine fehlerhafte Übertragung durch 1 Stopbit mehr plötzlich funktioniert ist weder normal noch logisch. Georg
Kann es sein, dass die Baudraten von Sender und Empfänger minimal differieren? Wenn die Baudrate des Senders etwas höher liegt als die des Empfängers, dann geht die Synchronisation nach mehreren Bytes verloren. Ein zusätzliches Stopbit beim Sender baut einen Zeitpuffer ein, der es dem Empfänger nach jedem Byte erlaubt, neu auf das nächste Startbit zu synchronisieren. Im Double-Speed-Mode ist der Uart übrigens empfindlicher gegen Baudraten-Unterschiede, lies Dir dazu ggf. auch das Kapitel "Stop bit and next start bit sampling" im Xmgea-Manual durch. Gruß, Stefan
Stefan K. schrieb: > zusätzliches Stopbit beim Sender baut einen Zeitpuffer ein, der es dem > Empfänger nach jedem Byte erlaubt, neu auf das nächste Startbit zu > synchronisieren. Jedes Startbit synchronisiert neu, egal wieviele Stopbits es sind.
Fabian S. schrieb: > Sende ich allerdings jedes Byte einzeln, also durch meine Eingabe > verzögert, funktioniert das Protokoll und der Controller reagiert > korrekt darauf. Fabian S. schrieb: > Es ist erstaunlich, aber mit 2 Stoppbits funktioniert es! Beide Symptome bedeuten eigentlich dasselbe: Es wird eine Pause zwischen den Bytes eingebaut - mehr nicht. Durch Senden von 2 Stoppbits wirst Du überhaupt nicht inkompatibel, sondern Du baust eine Pause von einer Bitlänge ein. Wenn es so funktioniert, lass es so und fertig. Welchen RS485-Adapter benutzt Du eigentlich am PC?
A. K. schrieb: > Stefan K. schrieb: >> zusätzliches Stopbit beim Sender baut einen Zeitpuffer ein, der es dem >> Empfänger nach jedem Byte erlaubt, neu auf das nächste Startbit zu >> synchronisieren. > > Jedes Startbit synchronisiert neu, egal wieviele Stopbits es sind. Wenn der Sender bereits das nächste Startbit sendet, während der Empfänger noch das letzte Stopbit empfängt (genauer: bis zu 11/16 des letzten Stopbits im normal mode oder 13/16 im double speed mode), dann wird das neue Startbit nicht vom Empfänger erkannt, sondern erst eines der folgenden Datenbits als Startbit interpretiert werden. Durch das Senden eines 2.Stopbits verschafft man dem Empfänger eine ganze Bittime zusätzlichen Synchronisations-Spielraum. Siehe auch: http://www.atmel.com/Images/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf 23.8.2 Asynchronous Data Recovery, Seit 288. Gruß, Stefan
Stefan K. schrieb: > Wenn der Sender bereits das nächste Startbit sendet, während der > Empfänger noch das letzte Stopbit empfängt ... dann sind die Bitraten mehr als nur minimal verschieden. Ok, ein zweites Stopbit kann das retten, aber besser wärs dann schon, wenn man an der richtigen Stelle ansetzt.
:
Bearbeitet durch User
A. K. schrieb: >> Wenn der Sender bereits das nächste Startbit sendet, während der >> Empfänger noch das letzte Stopbit empfängt > > ... dann sind die Bitraten mehr als nur minimal verschieden. Ok, ein > zweites Stopbit kann das retten, aber besser wärs dann schon, wenn man > an der richtigen Stelle ansetzt. Ich meine auch nicht, dass man mit dem 2.Stopbit eine falsche Baudrate reparieren soll. Ich möchte einen Hinweis geben, woher es kommen kann, dass die Kommunikation mit dem 2.Stopbit funktioniert. Das Problem ist, dass die Baudraten auf dem Oszi vom Timing korrekt aussehen. Der zulässige Baudratenfehler ist im o.g. Link auf Seite 289 aufgelistet und liegt bei 2% (double speed 1,5%). Das erkennt man auf dem Oszi kaum, wenn man nicht weiß, wonach man suchen soll. Gruß, Stefan
Georg schrieb: > Das gibt es nicht. Es könnte ja nach dem Zeichen kein weiteres mehr > kommen, daher sind 2, 3, viele Stoppbits selbstverständlich korrekt. > > Empfänger setzen sowieso nur 1 Stoppbit voraus und sind dann zufrieden > bis zum nächsten Startbit. Die Einstellung "2 Stopbits" wirkt bei UARTs > nur auf den Sender. > > Wahrscheinlich liegt dein Fehler aber immer noch ganz woanders, denn > dass eine fehlerhafte Übertragung durch 1 Stopbit mehr plötzlich > funktioniert ist weder normal noch logisch. Der Controller um den es geht ist quasi der Empfänger (Slave). Und der Empfang geht ja gerade schief... Und der Sender (Master) kann nicht mit zwei Stopbits senden. Nur mit einem! Helmut L. schrieb: > Hast du auch die Bias Widerstaende eingebaut? Ja ich habe Bias Widerstände in den RS485 Leitungen. Frank M. schrieb: > Welchen RS485-Adapter benutzt Du eigentlich am PC? Ich benutze das Kabel USB-RS485-WE mit FTDI Chip. Helmut L. schrieb: > Nicht raten, einfach mal die Zeiten messen. Dann werde ich wohl mal das Oszi auspacken und versuchen das Timing zu messen. Ein paar zusatz Infos: Ich benutze einen 16MHz Quarz (Reichelt: 16,0000-HC49-SMD). Ich habe noch meine Clock System Konfiguration angehängt.
Lass Deinen Xmega einfach mal ein paar Bytes senden und messe das Timing aus. Das vergleichst Du dann mit dem Timing des Masters (PC). Ergeben sich da Unterschiede, weisst Du, wo Du weitersuchen musst. Beliebter Fehler ist z.B., den Prescaler-Timer des Uarts mit dem Prescale-Faktor und nicht mit dem Prescale-Faktor - 1 zu beschreiben ...
Fabian S. schrieb: > Ich habe noch meine Clock System Konfiguration > angehängt. Das ist etwas verwirrend. Da sind zwar eine Menge Inits, aber welche benutzt du denn jetzt? 'Clock_Init' bspw. startet den internen 32MHz RC Oszillator. 'PLL_Init' basiert derzeit auch auf dem 32MHz RC Osz. Nur 'exClock_Init' scheint das richtige zu sein (ohne jetzt durch die Details zu gehen).
Fabian S. schrieb: > Ein paar zusatz Infos: Ich benutze einen 16MHz Quarz (Reichelt: > 16,0000-HC49-SMD). Ich habe noch meine Clock System Konfiguration > angehängt. Und da sieht man dann, dass Du den internen 32 MHz RC Oszillator benutzt (wenn ich PLL Config richtig interpretiere). Der ist aber viel weniger genau und gerne mal auf VCC Schwankungen empfindlich. Außerdem braucht ein Quarz Zeit zum Einschwingen. Die 256 Clocks scheinen mir viel zuwenig, da nimmt man normalerweise die höchsmögliche Einstellung, was bei anderen Atmels meistens 65K+einige MS ist.
Jim M. schrieb: > Fabian S. schrieb: >> Ein paar zusatz Infos: Ich benutze einen 16MHz Quarz (Reichelt: >> 16,0000-HC49-SMD). Ich habe noch meine Clock System Konfiguration >> angehängt. > > Und da sieht man dann, dass Du den internen 32 MHz RC Oszillator benutzt > (wenn ich PLL Config richtig interpretiere). > > Der ist aber viel weniger genau und gerne mal auf VCC Schwankungen > empfindlich. > > Außerdem braucht ein Quarz Zeit zum Einschwingen. Die 256 Clocks > scheinen mir viel zuwenig, da nimmt man normalerweise die höchsmögliche > Einstellung, was bei anderen Atmels meistens 65K+einige MS ist. OK. Ich habe das Beispiel falsch zusammen kopiert. PLL_init() wird zZ nicht verwendet. Die Einschwingphase habe ich auf 1KCLK erhöht. Weiterhin funktioniert es nicht mit einem Stoppbit aber 1,5 und 2 klappt. Timing Messung werde ich noch machen! Wenn ich allerdings die Baudrate in hTerm auf 115210Bd (also 10Bd höher) einstelle, funktioniert die Kommunikation auch mit einem Stopbit.
:
Bearbeitet durch User
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.