Hallo! Ich habe folgenes Problem und kann es einfach nicht erklären, vielleicht kann mir einer helfen. :-) Ich habe eine Baugruppe A die hat den HARDWARE UART aktiviert. Meine zweite Baugruppe B da ist der HARDWARE UART nicht mehr zugänglich und ich habe den per Software nachgebildet. Alles mit 4800 Baud 8n1. Stecke ich Baugruppe A an den PC und teste die TX und RX Seite klappt alles wie es soll. Stecke ich Baugruppe B an den PC und teste die TX und RX Seite klappt auch alles wie es sein soll. Und jetzt kommt das "Problem" stecke ich A und B zusammen gehen die Daten vom HUART zwar zun SUART raus, kommen aber nicht korrekt an. :-( Das Problem muß was reproduzierbares sein, denn die Daten die ankommen sind immer gleich flasch. :-( Schicke ich die gleichen Daten mit einen PC auf den SUART stimmt alles... kopfkratz Wo ist mein Gedankenfehler wenn ich es mit einer PC Verbindung verifizieren kann? Gruß AVRli...
>Das Problem muß was reproduzierbares sein, denn die Daten die ankommen >sind immer gleich flasch. :-( Dann stimmen vermutlich die Baudraten nicht überein. Benutzt du Quarze an den uC?
Hallo, vielleicht sind die Pegel nicht leistungsstark genug, ein PC hat normal recht kräftige Treiber drin, wenn man nur einen billigen Max232 Nachbau oder noch schlimmere Schaltungen zur Pegelwandlung nimmt, treten solche Fehler auf. Versuch es mit einem (brz. ja 2) richtigen Max232 oder verbinde mal direkt auf 5 Volt Ebene. Schau dir die Signale am Oszi an, wenn du eins hast. Peter
> wenn man nur einen billigen Max232 Nachbau
zum Beispiel?
Hallo, danke für die Antworten. Ja sind Quarze dran. Beide 18.432... also bei 4800 Baud 0% Error. Ich habe 2 MAX202 dazwischen... die wollte ich drin haben da ich glaube das auf +-8V V Ebene die Störanfälligkeit etwas vermindert wird. Hmm ein Ozzi hab ich, kein Speicherozzi... ich kann lediglich das H/L sehen. Das sieht ordendlich aus. Naja was man so sagen kann bei der Geschwindigkeit. Auf 5V Ebene mal für den Test zu verbinden, versuche ich mal. ;-) Gruß AVRli...
Vielleicht eine dumme Frage, aber hast Du die TX/RX gekreuzt? Denn wenn Du Baugruppe A direkt am PC anschliessen kannst und es läuft, ebenfalls Baugruppe B, dann müssen die Leitungen zwischen A und B gekreuzt sein.
Ja die Leitungen sind schon richtig... ich bin alles nachgerannt mit dem Ozzi. Das Kuriose ist eben wirklich das die ersten beiden Buchstaben immer richtig ankommen. Ich sehe es mit einem JTAG was im RX Buffer steht. Wenn ich mit dem PC Daten reinschicke kommen Pakete mit bis zu 60 Zeichen richtig an. Der Buffer ist nur 60 Zeichen groß. Gruß AVRli...
Hallo, vielleicht sendest du die Zeichen mit dem PC langsamer und ein Zielsystem ist mit der Gechwindigkeit überfordert. Das kann bei einem Softwareuart schnell passieren, dass man den Puffer nicht schnell genug schreiben kann, bevor das nächste Byte kommt. Peter
Also ich habe nun nochmal vergleiche gemacht. Ob es Aufschlüsse zu einer Lösung bringt weiß ich natürlich nicht. Ausgangsgröße sind 26 Zeichen, sende ich diese an einen PC kommen sie immer an! Sende ich diese an mein Modul B kommen immer nur 24 Zeichen an, der Inhalt ist total verwurschtelt aber immer gleich! Sende ich mit einen PC Daten an das Modul B stimmen diese immer. Es fehlt also was... nur warum fehlt es dann nicht wenn ich Daten vom PC absende? 4800 Bd sind doch 4800 Bd oder nicht? :-( Was ich nicht kapiere ist das es klappt wenn ein PC die Daten auf Modul B schickt und das wenn man die Daten von Modul A auf den PC schickt das auch alles iO ist. 5V Ebene klappt auch nicht, ist das gleiche Problem :-( Schönen Abend, AVRli...
@AVRli (Gast) Sachte sachte.. lies dir nochmals das Posting von Severino R. (severino) durch. >Vielleicht eine dumme Frage, aber hast Du die TX/RX gekreuzt? >Denn wenn Du Baugruppe A direkt am PC anschliessen kannst und es läuft, >ebenfalls Baugruppe B, dann müssen die Leitungen zwischen A und B >gekreuzt sein. Ist das wirklich erfüllt?
Ja ganz sicher... ich kann das H/L ja auf der Leitung sehen und das stimmt alles. Die ganzen Verbindungen gehen auf ein Steckboard wo ich dann mit kleinen Brücken in alle Richtungen jumpern kann. Es ist doch 8n1 wie folgt oder? <STARTBIT><D1><D2><D3><D4><D5><D6><D7><D8><STOPPBIT> Da keine Parity verwendet wird taucht das doch auch nicht auf oder? Gruß AVRli...
Bist du dir sicher das dein SW uart funzt? Der Test mit dem PC hilft da nicht, die Controller ICs auf den PCs sind sehr tolerant was das treffen der Baudraten angeht (teilweise) Mess mal die Zeiten genau nach... Bzw. mess die zeiten deiner hw-uart und deiner sw-uart beim Senden eines gleichen Zeichens..
Nein ich bin mir natürlich nicht sicher... :-( Deshalb dachte ich das ich den Soft UART RX überprüfen kann wenn ich den über den PC fütter. Habe am PC 4800 8Bit und 1 Stoppbit eingestellt. Das rennt dann. Ich sehe also genau das was ich vom PC schcke. Nun wie würde man so einen Vergleich messen? Sorry habe "nur" ein normales analoges Hameg Ozzi...
Ich habe ja immer zu wenig im Buffer gehabt und das heist ja das was verloren geht. Nun habe ich es analysiert und es scheint so das mein Soft UART das Stoppbit nicht richtig wertet. Wenn ich in der Baugruppe A den Hardware UART so konfiguriere das er 2 Stoppbits sendet dann klappt es auch mit dem RX des Soft UART. Also muß das Stoppbit am PC wohl auch einen Tick länger sein als beim ATMEL TX. Problem erstmal erklärt, muß der Softuart wohl das Starbit nach dem Stopbit irgendwie verschlucken. Wenn Stoppbit etwas länger dann klappt es. Ich danke Euch! Gruß AVRli...
AVRli wrote: > Ich habe ja immer zu wenig im Buffer gehabt und das heist ja das was > verloren geht. Nun habe ich es analysiert und es scheint so das mein > Soft UART das Stoppbit nicht richtig wertet. Wenn ich in der Baugruppe A > den Hardware UART so konfiguriere das er 2 Stoppbits sendet dann klappt > es auch mit dem RX des Soft UART. Also muß das Stoppbit am PC wohl auch > einen Tick länger sein als beim ATMEL TX. hey, wie realisierst du die Signalabtastung des Tx Signals in deinem Software-UART? Läuft die Abtast-Routine mit genau 4,8 kHz? Realisiert du das über einem Timer? So viel ich weiß hast du bei UART ja keine separate Clock-Leitung? Vielleicht wäre es hilfreich, wenn du über eine separate Leitung ein "Clock-Signal" von A nach B überträgst auf das sich beide Baugruppen synchronisieren können. Vielleicht könntest du durch eine genau Abtastung auf das "verlängerte" Stopp Bit verzichten. Best regards
Oh, hab gerade nochmal bei wiki nachgelesen.. "Die Besonderheit besteht darin, dass bei der üblichen asynchronen Version kein explizites Taktsignal verwendet wird. Stattdessen synchronisiert sich der Empfänger durch den Rahmen bestehend aus dem Start- und Stopp-Bit und einer bestimmten Bitrate, welche manchmal nicht ganz richtig als Baudrate bezeichnet wird. Da der Beginn einer Übertragung mit dem Start-Bit zu beliebigen Zeitpunkten erfolgen kann, wird diese serielle Schnittstelle als asynchron bezeichnet. Im Gegensatz dazu sind synchrone serielle Schnittstellen durch einen bestimmten Bittakt ohne einen Rahmen aus Start-/Stopp-Bit aufgebaut." Also kannst du das mit dem zusätzlichen Takt-Signal zur Synchronisierung vergessen.
AVRli wrote: > Ich habe ja immer zu wenig im Buffer gehabt und das heist ja das was > verloren geht. Nun habe ich es analysiert und es scheint so das mein > Soft UART das Stoppbit nicht richtig wertet. Das ist Quatsch, die Stopbits sind egal. Was passiert, daß Deine SW-UART nicht rechtzeitig für das nächste Startbit bereit ist und dann irgendne Flanke der Datenbits nimmt. Zeig dochmal den Code der SW-UART. Ist die denn auch mit Timerinterrupt und FIFO? Ne SW-UART mit Polling kannste vergessen. Generell braucht man für ne SW-UART viel CPU-Power und sämtliche anderen Interrupts müssen kürzer als eine halbe Bitzeit sein! Peter
Hallo und danke für Eure Geduld, ja ich versuche mal abzureißen wie ich es gemacht habe. Der ganze Ablauf ist aus einem Buch "AVR Mikrokontroller" nicht das einer denkt das wäre hier auf meinem Mist gewachsen. ;-) Das ganze läuft mit einen Timer Int. Ein Bit sample ich 5x also mit 4800 * 5 läuft der SUART im Int. Ich habe eine Quarzfreuqenz von 18.432 MHz. Diese teile ich durch 256 und lade den Timer mit 3 nach. Dann wird der Int alle 5*4800 ausgelöst. RX Code sieht dann so aus (siehe unten). Nach den Infos von Peter stimme ich in die Richtung zu das ich den Punkt verpasse wo das neue Startbit empfangen soll. Achja, buf_suart_rx ist ein Ringbuffer mit einer Größe von 32 und wird im Hauptprogramm leer geräumt. Gruß AVRli... (hoffendlich kann man dem Code folgen...)
1 | //-----------------------------------------------------------------------------
|
2 | //-- RX Software UART Funktion jeden Interrupt verarbeiten --------------------
|
3 | //-----------------------------------------------------------------------------
|
4 | if (rx_status == Rbit) { |
5 | if bit_is_clear(SUART_PIN, SUART_RX_PIN) rsum--; |
6 | else rsum++; |
7 | ricnt--; |
8 | if (ricnt == 0) { |
9 | ricnt = 5; |
10 | rbcnt--; |
11 | |
12 | if (rbcnt > 0) { |
13 | //bit schieben
|
14 | tmp_rx = tmp_rx >> 1; |
15 | if bit_is_set(rsum, 7) CLEAR_BIT(tmp_rx,7); |
16 | else SET_BIT(tmp_rx,7); |
17 | }
|
18 | |
19 | rsum = 0; |
20 | |
21 | if (rbcnt == 0) { |
22 | //byte in den buffer legen
|
23 | buf_suart_rx[pos_in_suart_rx] = tmp_rx; |
24 | pos_in_suart_rx++; |
25 | pos_in_suart_rx = pos_in_suart_rx & (SUART_RX_BUFFER_SIZE - 1); |
26 | rx_status = Ridle; |
27 | }
|
28 | }
|
29 | }
|
30 | else
|
31 | if (rx_status == Rstrt) { |
32 | if bit_is_clear(SUART_PIN, SUART_RX_PIN) rsum--; |
33 | else rsum++; |
34 | ricnt--; |
35 | if (ricnt == 0) { |
36 | if bit_is_set(rsum, 7) { |
37 | rx_status = Rbit; |
38 | ricnt = 5; |
39 | rsum = 0; |
40 | rbcnt = 9; // 8 Datenbit und 1 Stoppbit = 9 !!! |
41 | tmp_rx = 0; |
42 | }
|
43 | else { |
44 | rx_status = Ridle; |
45 | }
|
46 | }
|
47 | }
|
48 | else
|
49 | {
|
50 | if bit_is_clear(SUART_PIN, SUART_RX_PIN) { |
51 | rx_status = Rstrt; |
52 | rsum = 0; |
53 | ricnt = 5; |
54 | }
|
Dein Timer Interrupt läuft also mit 4800 Hz * 5, also 24 kHz Das bedeutet, dass du für die Verarbeitung deiner Interrupt Routine MAXIMAL 41,66 Mikrosekunden Zeit hast (1 / 24 kHz). Schafft es deine Routine nicht die Verarbeitung in 41,66 Mikrosekunden zu gewährleisten, sei es durch sporadisch auftretende sonstige Interrupts (die evtl. höher Prior sind), dann kommt deine Abtastung aus dem Tritt und es wird Mist detektiert. Für mich sieht deine Routine ein bisschen unnötig kompliziert aus. Würde es nicht reichen zu versuchen 2 mal in jedes Bit zu tasten? Damit hättest du mehr Zeit für die Verarbeitung. Also 2 * 4800 Hz = 9600 Hz. Damit hättest du 1 / 9600 Hz, also ca. 104 Mikrosekunden zur Verarbeitung Zeit!
Hi, bei 2 mal bin ich mir echt nicht sicher ob es gut ist. Denn wenn bei 2 eine Abtastung H und eine L war was ist es dann? Vlt. wären 3 Abtastungen ein guter Kompromiß... Ich kann es gerne mal probieren. Doch das eigendlich dekodieren stimmt eigendlich nur das Erkennen wann es wirklich wieder mit einem neuem Bit los geht hinkt. Trotzdem danke! :) Gruß AVRli...
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.