Hallo, ich verwende die UART Library von Peter Fleury, die arbeitet ja bekanntlich mit Ringpuffer für senden und empfangen. Ist vor allem der Sendepuffer unbedingt erforderlich? Ich möchte meine serielle Übertragungsgeschwindigkeit maximieren und der Ringpuffer bremst etwas
Kommt darauf an, was dir wichtig ist. Wenn dein µC außer senden, senden, senden nichts anderes zu tun hat, nimm keinen Buffer für max. Performance. Wenn dein µC aber andere Aufgaben hat, und das Senden sozusagen nebenbei, im Hintergrund, mit minimaler CPU-Last laufen soll, nimm einen Buffer.
Stefan schrieb: > Ist vor allem der > Sendepuffer unbedingt erforderlich? Ich möchte meine serielle > Übertragungsgeschwindigkeit maximieren und der Ringpuffer bremst etwas Hallo, warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären?
>Übertragungsgeschwindigkeit maximieren
Deine Baudrate soll also > 1MBd sein?
Uart schrieb: > Kommt darauf an, was dir wichtig ist. > > Wenn dein µC außer senden, senden, senden nichts anderes zu tun hat, > nimm keinen Buffer für max. Performance. > > Wenn dein µC aber andere Aufgaben hat, und das Senden sozusagen > nebenbei, im Hintergrund, mit minimaler CPU-Last laufen soll, nimm einen > Buffer. interessante Erklärung, danke wenn ich dem Controller sag er soll senden, dann macht der in der Tat sonst nichts mehr außer die Daten so schnell wie möglich raus zu schippern U.R. Schmitt schrieb: > warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären? der Controller muss den "Füllstand" der Puffer aktuell halten und das kostet etwas Zeit Entwickler schrieb: > Deine Baudrate soll also > 1MBd sein? Ich hab nen recht langsamen Quarz zwecks Stomverbrauch aber ich möcht mich so stark wie möglich an die maximal mögliche Geschwindigkeit annähern
>Ich hab nen recht langsamen Quarz zwecks Stomverbrauch
Und wie hoch ist Deine Datenrate? 10kB/s?
Nimm einen schnelleren Quarz und lege den Prozessor in Arbeitspausen
schlafen; Mittagsschlaf ist auch immer gut :-)
Im Moment ist sie bei knapp 5 kByte/s aber ich hab noch eine Bremse drin die ich (noch) nicht beheben kann. dann werd ich vermutlich 10+ kByte/s haben aber dann begrenzt mir der Ringpuffer schön langsam. Der Puffer halbiert in etwa meine max. Sendegeschwindigkeit es sollten 20kByte/s möglich sein denk ich
Stefan schrieb: > U.R. Schmitt schrieb: >> warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären? > > der Controller muss den "Füllstand" der Puffer aktuell halten und das > kostet etwas Zeit Bitte was??? Das einzige was bei einem Ringpuffer passiert ist, daß wenn ein Byte gesendet wurde per Interrupt eine kleine Funktion angesprungen wird, die nachschaut ob noch ein Byte da ist, das gesendet werden soll und danach den Lesezeiger im Ringpuffer verschiebt, bzw. wenn der schon am Ende des Puffers ist ihn wieder an den Anfang stellt. Das sollte selbst mit nichtoptimiertem C nicht viel mehr als 30 Assemblerbefehle dauern, mit Assembler sollte man es unter 20 hinkriegen. Beim Empfang ist es noch einfacher. Sobald ein Byte empfangen wurde, wird es (wieder via Interruptfunktion) an die Stelle des Schreibzeigers gesetzt und der eins erhöht, bzw. wieder an den Anfang gesetzt. Was jetzt noch fehlt ist die Overflow Prüfung, das ist ein einfacher Vergleich der beiden Zeiger auf Gleichheit. Damit kommst Du auf jeden Fall mit Lesen oder Schreiben auf einen Durchsatz über 100000 Byte pro Sekunde plus zusätzliche Zeit für ein Hauptprogramm. (bei angenommen 8 Millionen Assemblerbefehle pro Sekunde)
Ein Betrieb ohne Puffer ist dann sinnvoll, wenn die Daten kontinuierlich ermittelt und ausgegeben werden sollen. Du erhälst alle 50µs einen neuen Wert und gibst ihn direkt aus. Dann klappt das mit 20kB/s. Werden aber in 50µs 10 Werte erzeugt, ausgegeben und dann neue ermittelt, bremst die Warterei auf die UART Deinen Programmfluß. Man kann einen Puffer geschickt programmieren, dass er 20-30 Zyklen braucht. Bei 3,6864MHz würde der Interrupt unter 10µs ablaufen. Das ist allemal geschickter, als 25µs auf einen freien Sendepuffer zu warten. Um die Interrupts zu reduzieren, kann man das komplette Ende von Tx abwarten und dann gleich zwei Bytes auf einmal schreiben.
Stefan schrieb: > Ich hab nen recht langsamen Quarz zwecks Stomverbrauch aber ich möcht > mich so stark wie möglich an die maximal mögliche Geschwindigkeit > annähern Im Worst-Case hast Du 80 Zyklen pro Byte frei, da kann bequem ein Interrutphandler den FIFO auslesen und die Bytes Startbit an Stopbit rausrotzen. Ich kenne die Fleury-Lib nicht, aber in der Codesammlung findest Du meine FIFO, die ist ziemlich optimiert. Wenns Dich dann immer noch ausbremst, dann hast Du zu viele andere Interrupts, die die CPU stressen, vielleicht ne SW-PWM. Dann geh eben mit dem Quarz hoch, der MAX232 zieht ja schon mehr, als der AVR. Peter
U.R. Schmitt schrieb: > Stefan schrieb: >> U.R. Schmitt schrieb: >>> warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären? >> >> der Controller muss den "Füllstand" der Puffer aktuell halten und das >> kostet etwas Zeit > > Bitte was??? > Das einzige was bei einem Ringpuffer passiert ist, daß wenn ein Byte > gesendet wurde per Interrupt eine kleine Funktion angesprungen wird, die > nachschaut ob noch ein Byte da ist, Da Atmel auch mitgedacht hat, ist in der UART ein kleiner Buffer eingebaut (1 Zeichen). Den Interrupt bekommt man bereits, wenn man wieder ein Zeichen in den Buffer nachstopfen kann, d.h. noch während ein anderes Zeichen gerade über die Drähte rausgeklopft wird, lädt die ISR die UART schon wieder mit dem nächsten Zeichen nach. -> das Senden geht auch mit Ringbuffer nahtlos und ohne Zeitverzug solange man die Interrupts nicht mutwillig extrem lange abgeschaltet lässt.
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.