Forum: FPGA, VHDL & Co. UART Receiver oft Parity Error


von Daniel B. (knalltuet3)


Angehängte Dateien:

Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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

von Daniel B. (knalltuet3)


Lesenswert?

Noch nicht, aber das werd ich jetzt mal machen :)
Danke fuer den Tipp ich meld mich obs geklappt hat!

Gruss,

Daniel

von Daniel B. (knalltuet3)


Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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

von Daniel B. (knalltuet3)


Lesenswert?

> 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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von Daniel B. (knalltuet3)


Lesenswert?

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

von Michael (Gast)


Lesenswert?

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