Forum: Mikrocontroller und Digitale Elektronik STM32F0 UART :wie kann man ein delay zwischen den Bytes machen?


von Peter (Gast)


Lesenswert?

Hallo.

Ich will mit einem STM32F0 Daten (DMX) versenden und brauche zwischen 
den gesendeten Bytes ein einstellbares delay (0-800us).

Bei 0 (das was ich jetzt habe) Sende ich alles per DMA raus und gut ist.

Aber ich habe bemerkt das der eine oder andere Empfänger damit Probleme 
hat.
Warum auch immer, das müssen wir hier auch nicht klären.

Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?

Irgendwas in Prozessor Hardware wäre mir am liebsten dafür.
Halt etwas was mir keine Performance schluckt.

Peter

von Dennis (Gast)


Lesenswert?

Peter schrieb:
> Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?

Nein, denn der DMA ist ja gerade dafür da möglichst schnell ohne 
Prozessorlast Daten zu schaufeln.

Peter schrieb:
> Irgendwas in Prozessor Hardware wäre mir am liebsten dafür.

Wie wäre es mit den guten alten Interrupts? Damit ist dein Problem 
optimal gelöst, und "es schluckt dir keine Performance".

BTW: Erst Programmieren lernen, dann Datenblätter lesen und verstehen 
lernen (in diesem Fall heisst es "Reference Manual") und dann erst 
Gedanken über "Performance" machen. Diese Vorgehensweise hat sich über 
Jahrzehnte bewährt...

von Programmierer (Gast)


Lesenswert?

Man könnte per Timer in regelmäßigen Abständen einen DMA-Transfer 
auslösen, der immer nur ein Byte in den UART Puffer überträgt. Wenn der 
Timer die 512 erreicht (Überlauf interrupt) ist der gesamte Transfer 
fertig.

von Dennis (Gast)


Lesenswert?

Programmierer schrieb:
> in regelmäßigen Abständen einen DMA-Transfer
> auslösen, der immer nur ein Byte in den UART Puffer überträgt.

Und wo genau liegt dann der Vorteil des DMA??? Ein Byte kann man genauso 
im INT in den TX-Buffer legen und man spart sich die Konfiguration bzw. 
Start des DMA.

Frage mich weshalb jeder so scharf auf den DMA ist, ohne aber die 
eigentliche Funktionsweise zu verstehen.

Programmierer schrieb:
> Wenn der
> Timer die 512 erreicht (Überlauf interrupt) ist der gesamte Transfer
> fertig.

Das musst du mal bitte näher erklären.

von Deepdiver99 (Gast)


Lesenswert?

Ab wie viele Byte's würde sich der DMA Transfer lohnen?

von Falk B. (falk)


Lesenswert?

@ Peter (Gast)

>Ich will mit einem STM32F0 Daten (DMX) versenden und brauche zwischen
>den gesendeten Bytes ein einstellbares delay (0-800us).

Nö. DMX kann die Daten LÜCKENLOS senden. Die einzige Lücke ist zwischen 
den DMX-Zyklen. Die kann man aber leicht mit einem Timer generieren.

>Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?

Mit einem Umweg über einen Timer, ja.

>Irgendwas in Prozessor Hardware wäre mir am liebsten dafür.
>Halt etwas was mir keine Performance schluckt.

Mein Gott, dein STM32 hat genug Power, das alles ohne DMA zu machen. Das 
kann selbst ein kleiner AVR.

von Falk B. (falk)


Lesenswert?

@ Dennis (Gast)

>Und wo genau liegt dann der Vorteil des DMA???

Datentransfer ohne CPU-Belastung.

> Ein Byte kann man genauso
>im INT in den TX-Buffer legen und man spart sich die Konfiguration bzw.
>Start des DMA.

Kostet aber CPU-Zeit (Interrupt), die ggf. was wirklich dringendes zu 
tun hat.

>Frage mich weshalb jeder so scharf auf den DMA ist, ohne aber die
>eigentliche Funktionsweise zu verstehen.

Ist halt trendy ;-)

von Bernd K. (prof7bit)


Lesenswert?

Peter schrieb:
> Aber ich habe bemerkt das der eine oder andere Empfänger damit Probleme
> hat.

Hast Du auch wirklich 2 Stopbits eingestellt?

von Peter (Gast)


Lesenswert?

Es ist leider so das einige billige DMX Lampen es nicht mal schaffen 
diese alte DMX Norm einzuhalten. Darum ist es leider notwendig ein 
Interbyte-Delay einzubauen.

Das der Sinn vom DMA der ist schnell Daten zu transportieren und das 
unabhängig vom Prozessor ist mir klar.

Ich hatte halt nur gehofft das es einen Trick gibt dem ein Delay rein zu 
würgen. So wie waitstates beim RAM, nur mit mehr zeitlichem Spielraum.

Timer mag ich nicht so weil ich schon etliche Interrupts am laufen habe.
Aber dann werde ich hier wohl oder übel an den Prioritäten drehen bis 
alles ohne Jitter läuft.

Peter

von Falk B. (falk)


Lesenswert?

@ Peter (Gast)

>Ich hatte halt nur gehofft das es einen Trick gibt dem ein Delay rein zu
>würgen. So wie waitstates beim RAM, nur mit mehr zeitlichem Spielraum.

Nicht gelesen? Oder nicht verstanden?

>>Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?

>Mit einem Umweg über einen Timer, ja.

Normalfall:

DMA schaufelt direkt auf den UART -> Daten werden lückenlos gesendet.

"Trick":

DMA wird über einen Timer ausgelöst -> Daten werden im Zeitraster mit 
Lücken gesendet, trotzdem muss die CPU nicht arbeiten.

Ob man das beim STM32 so hinkriegt, muss man prüfen. Die ATXmegas können 
es, weil man dort als Triggerquelle Hardwarevents angeben kann.

>Timer mag ich nicht so weil ich schon etliche Interrupts am laufen habe.

Timer ja, aber nicht klassisch per Interrupt sondern als Triggerquelle 
fpr die DMA!

>Aber dann werde ich hier wohl oder übel an den Prioritäten drehen bis
>alles ohne Jitter läuft.

Was für großartige Dinge musst du denn noch so machen? Und gerade das 
Senden von DMX verträgt problemlos Jitter.

von Programmierer (Gast)


Lesenswert?

Falk Brunner schrieb:
> Ob man das beim STM32 so hinkriegt, muss man prüfen.
Ja, natürlich. Sonst wäre DMA da ja ziemlich sinnlos. (Nicht nur) die 
Timer können DMA Events auslösen und dadurch Transfers starten.

von Stefan (Gast)


Lesenswert?

Welche billigen DMX-Lampen brauchen denn so ein Delay? Ein ordentlicher 
DMX-Empfang war doch schon vor 20 Jahren in der 8051-Steinzeit möglich.

Viele Grüße, Stefan

von Bernd K. (prof7bit)


Lesenswert?

Stefan schrieb:
> Welche billigen DMX-Lampen brauchen denn so ein Delay? Ein ordentlicher
> DMX-Empfang war doch schon vor 20 Jahren in der 8051-Steinzeit möglich.

DMX schreibt 2 Stopbits vor und nicht 1. Ich hab ihn schon drauf 
hingewiesen aber er antwortet ja nicht.

von Peter (Gast)


Lesenswert?

Es sind leider recht viele Lampen die nicht mal heute es schaffen 
250Kbaud sauber rein zu holen.
Warum? Wie gesagt das werden wir hier nicht klären können, braucht Euch 
nur mal in den einschlägigen Licht Foren um zu hören.
Auch 2 Stopp Bits helfen nicht immer!
Das sind auch nur 4us, was wie gesagt nicht immer reicht.


Ich hatte nicht daran gedacht das man den Timer ja auch ohne Interrupt 
benutzen kann.
Das vereinfacht das ganze.
Wie ich das nun zum laufen bringe werde ich sehen, kann ja nicht so 
schwer sein.
Ich hoffe das der DMA auch das Zählen der Bytes dann noch machen kann 
wenn ich den über einen Timer triggere.


Alternativ hatte ich mir schon überlegt nur aus den Timerinterrupt 
direkt zu senden. Aber die andere Lösung scheint mir die eleganteste 
Methode zu sein.

Danke Euch,
Peter

von Georg (Gast)


Lesenswert?

Hallo,

du hast doch sicher einen "Heartbeat", einen Timer mit festem Raster, in 
dem du alles möglicher erledigen kannst, ich habe sowas eigentlich immer 
für 1 ms und 10 ms, da sendest du dann halt neben deinen sonstigen 
Aufgaben jedesmal ein Byte über DMX, wenn eines zu senden da ist. 
Einfach und kostet praktisch nichts.

Georg

von Peter (Gast)


Lesenswert?

1ms Raster und 250Kbaud?

Wie soll das gehen?

von ??? (Gast)


Lesenswert?

Peter schrieb:
> 1ms Raster und 250Kbaud?
>
> Wie soll das gehen?

Jede 1ms sendest du ein Byte mit 250kBd (das macht die HW!).

von Georg (Gast)


Lesenswert?

Peter schrieb:
> 1ms Raster und 250Kbaud?
>
> Wie soll das gehen?

Thread lesen - er will es ja gerade langsamer haben. Und die 1ms sind ja 
nicht in Stein gemeisselt.

Ich glaube auch nicht, dass er soviele Lampen hat, dass er den Durchsatz 
von 250 kBaud braucht. Aber was weiss man schon genau.

Georg

von Stefan (Gast)


Lesenswert?

Beim DMA kannst Du angeben, wieviel Übertragungen er machen soll. Danach 
schaltet er sich ab und macht einen DMA-ready-Interrupt.

Für das danach folgende Break musst Du warten, bis der UART idle ist. 
(WichtiG: der DMA meldet Dir "fertig", sobald er alle Bytes an den UART 
geschaufelt hat, der UART ist dann aber noch mit dem letzten Byte 
beschäftigt, also warten, bis der auch idle ist).

Für den Break ist es eine gängige Methode, den UART auf eine niedrigere 
Baudrate (z.B. 100kbaud) zu setzen und ein Null-Byte zu senden. Wenn der 
UART danach wieder idle wird, wieder die 250kbaud einstellen und den 
nächsten Frame senden.

Gruß, Stefan

von 6A66 (Gast)


Lesenswert?

Peter schrieb:
> Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?

Neben den bereits gezeigten Möglichkeiten gibt es die Möglichkeit zwei 
DMAs aufzusetzen. Einen der einen Timer füttert, der Timer löst eine DMA 
Update Event aus und er DMA schreibt einen weiteren Wert in den Timer. 
Die Werte werden in einer Liste gehalten und können dort flexibel 
eingestellt werden.
Der zweite DMA reagiert auch auf ein Event desselben Timers und 
transferiert den Buffer in die UART. Ist HW-nah wie gewünscht, belastet 
die CPU im Transfer nicht (nur wenn die Listen verändert werden müssen) 
bedeutet aber beim Aufsetzen entsprechend Performance.

Ich sehe aber nicht den Vorteil der Lösung gegenüber einer 
interrupt-gesteuertene Übertragung da Du die Listen auch verändern musst 
und das felxibel im Transfer. Würde ich unter den gegebenen Umständen 
per INT machen und nicht per DMA.

rgds

von Peter (Gast)


Lesenswert?

Da ich ein Interface bauen will muss ich auch die kompletten 512 Byte 
senden.
Bevor jemand fragt, das ist nicht mein erstes. Hatte vorher immer avr 
benutzt und da die timer Interrupt Methode benutzt.
der Prozessor war mir aber für rdm zu langsam .
Der m0 passt da besser und die dma timer Methode wird jetzt eingebaut.

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.