Hallo
Ich möchte auf dem STM32F4 den USART6 verwenden und habe ihn als Sender
konfiguriert. Das Problem dabei ist, dass der USART die Daten nicht
sofort versendet, sondern erst wenn er 1024 Bytes gesammelt hat (das
Programm sendet jede Sekunde ein Zeichen und nach 1024 Sekunden kommen
alle auf einmal). Wie bringe ich denn den USART dazu die Daten sofort zu
versenden?
Hier noch meine Initialisierung:
usart schrieb:> while (USART_GetFlagStatus(USART6, USART_FLAG_TC) == RESET);> USART_SendData(USART6, c);
Man müßte wissen, was diese Routinen machen.
TC abzufragen, ist eher ungeschickt, zumal es auch irgendwo gelöscht
werden müßte.
TXE zu verwenden, dürfte geschickter sein, da es nach der Datenausgabe
automatisch wieder gesetzt wird.
usart schrieb:> Das Problem dabei ist, dass der USART die Daten nicht> sofort versendet, sondern erst wenn er 1024 Bytes gesammelt hat (das> Programm sendet jede Sekunde ein Zeichen und nach 1024 Sekunden kommen> alle auf einmal).
Klingt so als würde erst ein Buffer voll laufen und dann würde gesendet
werden. Mal ganz unabhängig davon (kenne des STM nur vom Namen) warum
überträgst du denn nur mit einer Baudrate von 1? Das erscheint mir wenig
sinnvoll zu sein.
usart schrieb:> USART die Daten nicht> sofort versendet, sondern erst wenn er 1024 Bytes gesammelt ha
Der USART hat keinen so großen Puffer, aber ein eventuell vorhandener
USB2UART oder USB2RS232 Wandler könnte solches Verhalten zeigen. Was für
ein Gerät nutzt Du an dieser Stelle?
Michael Köhler schrieb:> Klingt so als würde erst ein Buffer voll laufen und dann würde gesendet> werden. Mal ganz unabhängig davon (kenne des STM nur vom Namen) warum> überträgst du denn nur mit einer Baudrate von 1?
Die Baudrate ist nicht 1, ich sende nur ein Zeichen pro Sekunde. Die
Baudrate beträgt 2 MBaud.
@Jim und Lothar
Ich habe die Leitung mit dem Logikanalyser kontrolliert. Die Daten
bleiben wirklich im µC bis er seinen Puffer leert.
m.n. schrieb:> TXE zu verwenden, dürfte geschickter sein, da es nach der Datenausgabe> automatisch wieder gesetzt wird.
Ich habe folgendes getestet mit gleichem Ergebnis:
>Ich habe die Leitung mit dem Logikanalyser kontrolliert. Die Daten>bleiben wirklich im µC bis er seinen Puffer leert.
Der STM hat keinen internen Buffer der 1024 Byte gross ist.
Das Problem wird die Routine sein die Printchar() aufruft.
usart schrieb:> Der Fehler lag gar nicht beim STM32 sondern beim printf Befehl.
Was mal wieder zeigt, dass das Problem meist nicht im gezeigten Code
steckt, sondern ganz woanders. printf hattest Du bis dato noch nichtmals
erwähnt.
Ich habe keine Ahnung vom STM, aber wenn es ein stdio-ähnliches printf()
gibt, dann vielleicht auch ein fflush(), mit dem man die Ausgabe
erzwingen kann? Das könnte unter bestimmten Umständen effizienter sein
als den Ringbuffer komplett abzuschalten.
Frank M. schrieb:> Was mal wieder zeigt, dass das Problem meist nicht im gezeigten Code> steckt, sondern ganz woanders. printf hattest Du bis dato noch nichtmals> erwähnt.
Richtig. Allerdings funktionierte printf auch schon seit Tagen mit
Uart3. Ich hab keine Ahnung durch welche Änderung das jetzt plötzlich
gepuffert ist.
Ich wüsste eigentlich nicht was der Puffer überhaupt bringen sollte. Ob
man es in einen Puffer schreibt oder direkt dem USART übergibt ist
eigentlich egal, außer man verwendet DMA.
usart schrieb:> ch wüsste eigentlich nicht was der Puffer überhaupt bringen sollte. Ob> man es in einen Puffer schreibt oder direkt dem USART übergibt ist> eigentlich egal
Nö, direkt in den USART passt nur ein Byte, in den Puffer halt mehr.
Der Vorteil vom Puffer, man braucht sich nicht um jedes Zeichen einzeln
kümmern.
usart schrieb:> Ich wüsste eigentlich nicht was der Puffer überhaupt bringen sollte. Ob> man es in einen Puffer schreibt oder direkt dem USART übergibt ist> eigentlich egal, außer man verwendet DMA.
Nehmen wir an, Du müsstest 1000 Bytes schreiben. Wenn Du keinen
Ringbuffer hast, musst Du nach jedem Zeichen warten, bis es gesendet
wurde, bis Du das nächste Zeichen dem USART übergeben kannst[1].
Währenddessen etwas anderes zu machen, damit Dein µC die ganze Zeit
während der Übertragung nicht brachliegt, ist dann schon etwas knifflig
zu bewerkstelligen.
Wenn Du die 1000 Byte in einen Ringbuffer schreibst, brauchst Du dafür
einen Bruchteil der Zeit und hast den Rest der Zeit frei, etwas anderes
zu tun.
Wenn Du nur ein "Hello, World"-Programm schreibst, dann gebe ich Dir
recht. Dann brauchst Du tatsächlich keinen Buffer. Aber diese Art von
Programmen schreibt man recht selten für µCs ;-)
[1] Diese Aussage stimmt nicht ganz, beschreibt es aber grob.
usart schrieb:> Die Baudrate ist nicht 1, ich sende nur ein Zeichen pro Sekunde. Die> Baudrate beträgt 2 MBaud.
Also ein Baudrate von 1 würde dir genügen? Ich frag nur aus Interesse.
Ich war noch nie in der "Bedrängnis" nur ein Zeichen pro Sekunde zu
übertragen. Daher meine Neugierde.
Michael Köhler schrieb:> Ich war noch nie in der "Bedrängnis" nur ein Zeichen pro Sekunde zu> übertragen. Daher meine Neugierde.
Könnte sein, dass das ein "Alive" Signal ist, mit dem eine Komponente
mitteilt, dass sie noch da ist, aber gerade keine Daten hat...
Manchmal kann es sogar sein, dass eine serielle Schnittstelle ein halbes
Jahr lang gar nichts überträgt. Und dann ganz schnell wieder viele
Daten, wenn ich z.B. meine Telefonanlage wieder umkonfiguriere.
Frank M. schrieb:> Wenn Du die 1000 Byte in einen Ringbuffer schreibst, brauchst Du dafür> einen Bruchteil der Zeit und hast den Rest der Zeit frei, etwas anderes> zu tun.
Das ist richtig. Die gleiche Zeit brauche ich dann aber für den
blockierenden Transfer. Ich finde ein Buffer macht nur Sinn wenn der
Transfer DMA oder Interrupt basiert ist.
Das eine Zeichen pro Sekunde war übrigens ein Startzeichen für kommende
Debugausgaben. Die waren aber bei dem Test ausgeschalten. Daher wurde
immer nur das Startzeichen alleine gesendet.