HeeHow! Ich habe auf meinem Spartan 3E Starter Kit einen UART implementiert. Transmit und Receive funktionieren prinzipiell. Bei der Kommunikation in einer Schleife (FPGA sendet an sich selbst. Ueber ein Kabel, nicht intern) treten keinerlei Fehler auf. Lediglich beim Empfangen von Daten von anderen Geraeten schleichen sich sehr haeufig Fehler ein die als Parity Error erkannt werden. Ich habe hier in der Uni die Moeglichkeit genutzt die Signale vor und nach der Pegelwandlung auf dem Starter Kit mittels eines Oszilloskop zu analysieren. Die fehlerhaften Signale unterscheiden sich nicht von Signalen die fehlerfrei erkannt werden. Das legt die Vermutung nahe, dass es ein Timingproblem ist, ich finde aber keinen Fehler in meinem Code (siehe Anhang). Vor den UART ist ne DCM geschaltet, die die 50 MHz auf 14,2857 bricht (Teiler 7, Multiplikator: 2). Mit einem Clk-Teiler von 124 entsteht dann eine Baudrate von 115207 was einem Fehler von 0,000064 gleich kommt, wenn ich richtig gerechnet habe ;) Jemand ne Idee wo das problem liegt?
> Jemand ne Idee wo das problem liegt? Schon mal drüber nachgedacht, das asynchrone externe Signal RxD einzusynchronisieren? (Aka eintakten) Basics: http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
Noch nicht, aber das werd ich jetzt mal machen :) Danke fuer den Tipp ich meld mich obs geklappt hat! Gruss, Daniel
Hab jetzt eine Schaltung eingefuegt, die das Signal "einsynchronisiert". Evtl. ist das auftauchen der Parity Errors jetzt weniger geworden, aber sie treten doch immer noch recht haeufig auf. Ne andere idee?
> Ne andere idee? Das parity-bit wäre erst mal meine kleinste Sorge. Wie sehen die Daten aus? Kommen die immer korrekt an? Das sieht verdächtig aus: > shared variable TxClkDivider : integer := 61; > shared variable RxClkDivider : integer := 30; Ich hätte für den RX-Takt und den TX-Takt gleiche Werte erwartet, denn es soll ja auch die gleiche Baudrate sein... :-/ Ein Tipp: Du mußt nicht so wild hin und herspringen in deiner SM. Sieh dir mal meinen UART an: http://www.lothar-miller.de/s9y/categories/42-RS232
> Das parity-bit wäre erst mal meine kleinste Sorge. Das Parity-Bit an sich macht keine Probleme, damit ist alles in Ordnung. > Wie sehen die Daten aus? Kommen die immer korrekt an? Was meinst du mit wie sehen die Daten aus? Wenns nen Parity-Error gibt kommen sie nicht korrekt an, sonst schon. Oder meinst du die analogen Signale? Die sind wunderschoen und kommen korrekt an. > Das sieht verdächtig aus: > > shared variable TxClkDivider : integer := 61; > > shared variable RxClkDivider : integer := 30; > Ich hätte für den RX-Takt und den TX-Takt gleiche Werte erwartet, denn > es soll ja auch die gleiche Baudrate sein... :-/ 2*62 = 124. Der TxTakt laeuft also mit 115200 baud. Der RxTakt laeuft doppelt so schnell. Das liegt daran, dass immer zwei Zyklen durchlaufen werden. shiftRx und edgeRx. Bei shiftRx werden die Daten übernommen innerhalb von edge Rx sollte dann der "wechsel" des Datensignals liegen. Das ist nach dem Konzept von ALSE.fr Ich schau mir deinen UART mal an. Daniel
> Vor den UART ist ne DCM geschaltet, die die 50 MHz auf 14,2857 bricht > (Teiler 7, Multiplikator: 2). Mit einem Clk-Teiler von 124 entsteht dann > eine Baudrate von 115207 was einem Fehler von 0,000064 gleich kommt, > wenn ich richtig gerechnet habe ;) Richtig gerechnet, aber hübsch aufwendig, die Takterzeugung ;-) Wenn du 50000000Hz durch 115200 teilst, bekommst du 434,0277. Wenn du jetzt 434 als Reload-Wert nimmst, hast du einen Fehler von 0,0064%. Das stimmt (Augen auf, Surprise, Surprise) mit deinem Wert überein :-o Muß ja auch so sein, denn beide Verfahren setzen auf die 50MHz. Nur ist meines weniger aufwendig ;-)
So, ich habe jetzt einen UART von opencores.org getestet und der laeuft Problemlos. Ich habe aber noch nicht weiter nachgeforscht woran es jetzt genau bei "meinem" uart lag. Ausschliessen kann ich aber schon mal die Baud-Rate und ein Tipp von mir liegt auf der Synchronisation der Signale. Ich schau da die Tage noch mal drauf. Gruss und vielen Dank fuer die Unterstuetzung! Daniel
Ich denke das "Einsynchronisieren" wird in deinem Fall nicht das Problem sein, obwohl es nicht schadet. Deine Zustandsmaschine für den RX Pfad reagiert auf jeden Glitch der über RxD einläuft, da RxD nur für einen einzigen Takt lang auf Low liegen muss um die Receiver Statemachine zu triggern. Vorschlag: Debouncing durch Mehrheitsentscheidung. Ich habe das häufiger verwendet und sehr gute Erfahrungen gemacht: Schieberegister zum Eintakten des seriellen Datenstroms mit einem höheren Takt verwenden. Sind alle Bits im Schieberegister "1" dann den internen Zustand auf "1" setzen. Sind alle bits "0" dann auf "0" setzen. Man kann natürlich auch etwas toleranter sein und schon bei einer geringeren Anzahl die Schwelle setzen. Das benötigt aber gleich deutlich mehr logik im Baustein.
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.