Hallo, habe folgendes Problem: Ich habe 60 identischen Platinen für ein Gerät, maschinell bestückt. Diese haben eine ATXMEGA, der über einen FT234 und USB mit dem Rechner verbunden werden kann. Nun habe ich bei drei Platinen das Problem, dass vom Controller gesendete Daten vefälscht werden. Ich habe versucht das Problem zu reproduzieren, indem ich stumpf 200 mal eine "1" sende, sowohl gepufferte Ausgabe als auch direktes Beschreiben des DATA-Registers und Warten auf das DRE-Flag. Der Fehler äußert sich wie folgt: Es werden korrekt ein paar Einsen gesendet, dann wird aus der 0x01 eine 0x81, dann eine 0x80, 0x40 ,0xC0, 0x80, 0xA0 und 0xE0. Das Schema ist immer gleich, wobei die Anzahl der einzelnen Zahlen variiert. Takt ist intern 32Mhz Einstellungen sind:Baudrate 256000, BSEL = 436 BSCALE = -6, alternative Einstellungen habe ich ausprobiert (BSEL = 872, BSCALE = -7), RTS/CTS Flow Control Bei anderen Platinen kann ich das Problem nicht provozieren, weshalb ich irgendwas an der Hardware vermute. Macht der z.B. FTDI komische Sachen, wenn ein Kondensator nicht verbunden ist (kleines Package, Beinchen nicht sauber gelötet o.ä.)? Kann der Takt des ATXMEGA so stark abweichen, dass die Baudrate nicht stimmt? Leider habe ich aktuell kein Oszi zur Hand um die Leitungen anzuschauen. Was könnte die Ursache sein. Grüße und Danke im Vorraus, Alex
Alexander H. schrieb: > Kann der Takt des ATXMEGA so stark > abweichen, dass die Baudrate nicht stimmt? Interner Oszillator? Ja, dann kann der zu stark abweichen.
Hallo H. H., danke für deine schnelle Antwort, Ich sollte vielleicht noch erwähnen, dass das Problem bei 115200 Baud nicht auftaucht.
Alexander H. schrieb: > danke für deine schnelle Antwort, > Ich sollte vielleicht noch erwähnen, dass das Problem bei 115200 Baud > nicht auftaucht. Der FT234 kann wie sein Vorgänger FT232 Baudraten mit ziemlich großer Genauigkeit erzeugen, auch dank des gebrochenrationalen Teilers. Die Formel im Datenblatt sagt Baudrate = 3e6 /(n+x) Wobei n der Ganzzahlanteil und x der gebrochenrationale Anteil ist, welcher mit einer Auflösung von 1/8 = 0,125 angegeben werden kann. Bei 256000 Baud kommt da 11,71875 raus, gerundet 11,75, macht einen Fehler von 0,3%. Das ist kein Problem. Fragt sich, ob am PC die Baudrate korrekt konfiguriert wurde und nicht einfach auf 250000 Baud gerundet wurde. Wobei, wenn die meisten der 60 Platinen funktionieren, sollte das OK sein. Die Fehler sind Einzelfehler. Das können Lötfehler sein, aber auch Frequenzfehler im AVR, warum auch immer. Letzteres kann man prüfen, indem man an einem OCRx Pin einen Takt ausgibt, der ist starr an den internen Oszillator gekoppelt. Die Frequenz kann man sehr genau messen.
Hallo Falk, Danke für die Antwort. Wenn ich das Manual des Controllers richtig verstanden habe, kann man die Genauigkeit des 32Mhz-Oszillators über die DFLL verbessern. Allerdings werde ich nicht ganz schlau daraus, wie. Meine momentane Clock-Iinitialiserung sieht so aus:
1 | CCP = CCP_IOREG_gc; |
2 | OSC.CTRL = OSC_RC32MEN_bm; |
3 | while(!(OSC.STATUS & OSC_RC32MRDY_bm)); |
4 | CCP = CCP_IOREG_gc; |
5 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc; |
Wie aktiviere ich denn die Run-Time-Calibration mittels DFLL? Das würde ich mal als erstes noch probieren.
Alexander H. schrieb: > Hallo H. H., > danke für deine schnelle Antwort, > Ich sollte vielleicht noch erwähnen, dass das Problem bei 115200 Baud > nicht auftaucht. Die wichtigste Info, so ganz nebenbei... Welchen Schluss ziehst Du selbst aus dieser Information?
Alexander H. schrieb: > Ich habe 60 identischen Platinen für ein Gerät, maschinell bestückt. > Diese haben eine ATXMEGA, der über einen FT234 und USB mit dem Rechner > verbunden werden kann. Dann programmiere mal deinen Controller so, daß er die Daten mit 2 (zwei) Stopbits sendet. Ich habe schon bei vielen USB<-->Seriell Konvertern erlebt, daß sie mit nur einem Stopbit gelegentlich Probleme haben. Nicht oft, aber gelegentlich. W.S.
Jester schrieb: > Alexander H. schrieb: >> Hallo H. H., >> danke für deine schnelle Antwort, >> Ich sollte vielleicht noch erwähnen, dass das Problem bei 115200 Baud >> nicht auftaucht. > > Die wichtigste Info, so ganz nebenbei... Welchen Schluss ziehst Du > selbst aus dieser Information? Hallo Jester, was möchtest du mir damit sagen? Ein Halbierung der Baudrate und damit Verdopplung der Übertragungszeit ist keine echte Option, da recht viele Daten übertragen werden.
Alexander H. schrieb: > Hallo Jester, was möchtest du mir damit sagen? Er möchte dir damit sagen, dass du ein Clock Problem bei den Platinen hast die nicht funktionieren.
Alexander H. schrieb: > Meine momentane Clock-Iinitialiserung sieht so aus: > CCP = CCP_IOREG_gc; > OSC.CTRL = OSC_RC32MEN_bm; > while(!(OSC.STATUS & OSC_RC32MRDY_bm)); > CCP = CCP_IOREG_gc; > CLK.CTRL = CLK_SCLKSEL_RC32M_gc; Ähhhm, CCP, configuration chance protection darf man nicht so naiv schreiben! Damit das sehr knappe Timing auf das Register IMMER eingehalten wird, gibt es ein Macro, das man auch nutzen sollte. Beitrag "Re: AVR128, CCP und Optimierung" Außerdem müssen zu dem Zeitpunkt die Interrupts global ausgeschaltet sein, damit dort nix reinspuckt. Das sichert das Macro NICHT. Kann sein, daß das nicht dein Problem ist, es kann aber dazu werden.
Falk B. schrieb: > Ähhhm, CCP, configuration chance protection darf man nicht so naiv > schreiben! Damit das sehr knappe Timing auf das Register IMMER > eingehalten wird, gibt es ein Macro, das man auch nutzen sollte. Ich werde es beherzigen, danke für den Hinweis.
W.S. schrieb: > Dann programmiere mal deinen Controller so, daß er die Daten mit 2 > (zwei) Stopbits sendet. Ich habe schon bei vielen USB<-->Seriell > Konvertern erlebt, daß sie mit nur einem Stopbit gelegentlich Probleme > haben. Nicht oft, aber gelegentlich. Das habe ich jetzt probiert, und das scheint zu helfen, jedenfalls geht es jetzt. Was mich wundert ist, dass es auch dann funktioniert, wenn ich am Rechner bei der Einstellung des seriellen Ports Stopbits = 1 auswähle. Kann mir das noch jemand erklären?
Alexander H. schrieb: > Was mich wundert ist, dass es auch dann funktioniert, wenn ich am > Rechner bei der Einstellung des seriellen Ports Stopbits = 1 auswähle. > Kann mir das noch jemand erklären? Ja sicher, denn 2 Stoppbits sind gleichbedeutend mit 1 Stoppbit + 1 Bit Sendepause. Nur anders herum geht es nicht. Wenn der Empfänger 2 Stopbits erwartet und nur 1 bekommt, stellt er einen Stopbitfehler fest, wenn ohne Pause Daten gesendet weden. Denn dann folgt auf das Stopbit (1) sofort das Startbit (0).
Wenn ich also Daten vom Rechner zum Controller übertrage, dürfte das deiner Erklärung nach nicht funktioniern. Tut es aber.
Alexander H. schrieb: > Wenn ich also Daten vom Rechner zum Controller übertrage, dürfte das > deiner Erklärung nach nicht funktioniern. Tut es aber. Dann hast du sie nicht vestanden.
> Dann hast du sie nicht vestanden.
Gib mir noch eine Chance.
Also wenn ich es richtig verstanden habe, dann ist dem Rechner egal wenn
ein Stopbit eingestellt ist, weil er ein Stopbit erwartet und zwei
bekommt, was für ihn wie ein langes Stopbit aussieht. Ich hab jetzt
nochmal das Manual bemüht. Dort steht, dass beim Framing Error nur auf
das erste Stopbit geschaut wird, auch wenn zwei eingestellt sind,
weshalb das auch unkritisch ist. Dann bekommt der Controller ohne
zusätzliche Pause das nächste Datenbyte übertragen (Startbit).
Ich möchte es ja nur verstehen.
:
Bearbeitet durch User
Alexander H. schrieb: >> Dann hast du sie nicht vestanden. > > Gib mir noch eine Chance. > > Also wenn ich es richtig verstanden habe, dann ist dem Rechner egal wenn > ein Stopbit eingestellt ist, weil er ein Stopbit erwartet und zwei > bekommt, was für ihn wie ein langes Stopbit aussieht. Naja, eher der FT234. Der kann unt tut auch die Stopbits auswerten und im Fehlerfall diesen signalisieren. > Ich hab jetzt > nochmal das Manual bemüht. Dort steht, dass beim Framing Error nur auf > das erste Stopbit geschaut wird, auch wenn zwei eingestellt sind, > weshalb das auch unkritisch ist. Das ist der AVR. > Dann bekommt der Controller ohne > zusätzliche Pause das nächste Datenbyte übertragen (Startbit). Genau. Dabei ist es dann egal, ob der Datenstrom zum AVR 1 oder 2 Stopbits nutzt.
Falk B. schrieb: > Naja, eher der FT234. Der kann unt tut auch die Stopbits auswerten und > im Fehlerfall diesen signalisieren. Ist das so? Falls ja, wäre es standardwidrig (ich kann mir kaum vorstellen, dass so ein Unsinn in einem FTDI-Produkt steckt). Die Sache mit 1,5 oder 2 Stopbits sollte lt. Standard immer nur den Sender interessieren. Der Empfänger hat ein Stopbit zu erwarten. Alles was danach kommt ist einfach "idle" oder halt das Startbit des nächsten Worts. Das ergibt sich nicht nur aus dem Wortlaut des Standards, sondern auch völlig zwanglos und vollkomen logisch aus dem einzigen Grund, warum es diese Stopbit-Variationen überhaupt in den Standard geschafft haben. Und das ist: Ausweitung der möglichen Taktabweichung zwischen Sender und Empfänger. Sobald aber auch der Empfänger sich für die Zahl der Stopbits interessiert, wird dieser einzige Zweck längerer Stopbits ad absurdum geführt. Vielleicht kannst du ja mal Zitate aus dem DB des FT234 liefern, die deine Meinung belegen könnten. Tipp: Du wirst keine finden...
c-hater schrieb: >> Naja, eher der FT234. Der kann unt tut auch die Stopbits auswerten und >> im Fehlerfall diesen signalisieren. > > Ist das so? Keine Ahnung. AVRs und viele andere Mikrocontroller erkennen einen Frame Error bei fehlerhaftem Stopbit. Es ist nur eine Vermutung.
Hallo, nachdem ich jetzt die Zeit hatte, mich nochmal ausführlich mit der oben beschriebenen Thematik zu beschäftigen und die Signale mit einem Oszi anzuschauen, konnte ich das Problem lösen und möchte das hier nur noch ergänzen. Also, es war wie von euch vermutet. Bei einem Gerät, das bei der Kommunikation richtig rumgezickt hat, konnte man sehen, dass der 32MHz-Oszillator über 5% zu schnell lief. Es gab dadurch auch signifikante Frequenzunterschiede zwischen der RXD-Leitung (vom FTDI gesteuert) und der TXD-Leitung (vom uC gesteuert). Gelöst hab ich das Problem mithilfe des folgenden Eintrags, wo beschrieben ist, wie man den 32MHz-Oszillater mithilfe der DFLL gegen den internen, genaueren 32kHz-Oszillator abgleicht. https://www.avrfreaks.net/s/topic/a5C3l000000UXZyEAO/t142872 Danke nochmal und Grüße, Alex
Kaum macht man es richtig, schon funktioniert's! Immer wieder erschreckend! ;-)
Mit der gleichen Methode habe ich vor einigen Jahren die serielle Kommunikation auf einem Xmega128D3 stabil bekommen. Ohne DFLL funktionierte es bei schon mit 115200 Baud instabil, und war deutlich temperaturabhängig.
Beitrag #7253734 wurde vom Autor gelöscht.
Bei dem Gerät hier auch. Allerdings scheint das ein sporadisches Problem zu sein. Habe ganz viele Geräte hier, die ohne die Stabilisierung auch mit 256000 Baud laufen.
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.