Forum: Mikrocontroller und Digitale Elektronik HAL_DAC_Start_DMA-Routine zu langsam - Alternative


von Daniel R. (sparker)


Lesenswert?

Hallo,

ich versuche eine Softwarebasierte Schnittstellenlösung (ist nur ein 
paar Millisekunden pro Sekunde aktiv) zu realisieren und denke, dass die 
bisherig verwendete Routine vor allem bei höheren Datenraten zu langsam 
ist und damit Probleme verursacht. Dazu verwende ich den DAC mit DMA, um 
Signal-Rampen zu erzeugen.

Eigentlich wende ich nur diese Funktion an, es wird nur das Datenfeld 
(hier: interface_zero_low) gewechselt:
1
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*) interface_zero_low, INTERFACE_RAMP_RES, DAC_ALIGN_12B_R);

Dann wird mit einem Timer ein Interrupt generiert und ein weiterer Timer 
für den DAC-Trigger angeworfen. Ist die Rampe fertig (DMA-TC-Interrupt), 
wird der Timer gestoppt und ich bereite die nächste Rampenfunktion vor.

Nun ändere ich eigentlich nur das Feld für die Rampe, daher habe ich mir 
gedacht, so was in der Art sollte reichen, aber es reicht nicht:
1
DMA1_Stream5 -> M0AR = (uint32_t)(&interface_low_return_to_zero);

Irgendwo habe ich das gefunden, hat mich aber auch nicht weiter 
gebracht:
1
DMA1_Stream5 -> NDTR = INTERFACE_RAMP_RES;
2
DMA1_Stream5 -> PAR = (uint32_t)&(DAC -> DHR12R1);
3
DMA1_Stream5 -> M0AR = (uint32_t)(&interface_zero_low);
4
DMA1_Stream5 -> CR = (DMA_SxCR_TEIE | DMA_SxCR_CHSEL | DMA_SxCR_CIRC | DMA_SxCR_DIR_0 | DMA_SxCR_EN | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_PL_0);

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


Lesenswert?

Daniel R. schrieb:
> und denke, dass die bisherig verwendete Routine vor allem bei höheren
> Datenraten zu langsam ist
Was sagen die zugehörigen Messungen? Wo geht die Rechenzeit verloren? 
Hast du für die ganzen Verdachtsmomemte auch Zahlen?

> Irgendwo habe ich das gefunden
Und was tut das? Hast du es mal genauer angeschaut?

Daniel R. schrieb:
> Softwarebasierte Schnittstellenlösung (ist nur ein paar Millisekunden
> pro Sekunde aktiv) zu realisieren und denke, dass die bisherig
> verwendete Routine vor allem bei höheren Datenraten zu langsam ist
Warum fährst du eine Schnittstelle erst mit Vollgas und verbummelst 
danach den Rest der Zeit? Könntest du nicht einfach die Übertragung 100x 
langsamer machen und statt der blitzschnellen kurzen Bursts deine Daten 
langsam und ausdauernd übertragen?

: Bearbeitet durch Moderator
von N. M. (mani)


Lesenswert?

Oder einfach einen 2. DMA konfigurieren und im End ISR des 1. DMA nur 
den DMA Enablen. Also als Ping Pong DMA.
Dann ist das nur der Einsprung in den ISR und setzen eines Start Bits.

von Daniel R. (sparker)


Lesenswert?

Lothar M. schrieb:
> Daniel R. schrieb:
>> und denke, dass die bisherig verwendete Routine vor allem bei höheren
>> Datenraten zu langsam ist
> Was sagen die zugehörigen Messungen? Wo geht die Rechenzeit verloren?
> Hast du für die ganzen Verdachtsmomemte auch Zahlen?
Nein, aber ich merke, dass sich das System "aufhängt" - er springt nie 
wieder in den DMA-TC-Interrupt (und dabei ändere ich nur die zwei 
Timerwerte für die Bitzeit und die Rampenzeit, ansonsten ändere ich 
nichts am Programm).


Lothar M. schrieb:
> Daniel R. schrieb:
>> und denke, dass die bisherig verwendete Routine vor allem bei höheren
>> Datenraten zu langsam ist
> Was sagen die zugehörigen Messungen? Wo geht die Rechenzeit verloren?
> Hast du für die ganzen Verdachtsmomemte auch Zahlen?
>
>> Irgendwo habe ich das gefunden
> Und was tut das? Hast du es mal genauer angeschaut?

Naja, ich habe es nicht genauer angesehen.
Aber eigentlich sollte es so etwas ähnliches wie die C-Funktion 
durchführen, nur halt ohne den ganzen Overhead.

> Daniel R. schrieb:
>> Softwarebasierte Schnittstellenlösung (ist nur ein paar Millisekunden
>> pro Sekunde aktiv) zu realisieren und denke, dass die bisherig
>> verwendete Routine vor allem bei höheren Datenraten zu langsam ist
> Warum fährst du eine Schnittstelle erst mit Vollgas, und verbummelst
> danach den Rest der Zeit? Könntest du nicht einfach die Übertragung 100x
> langsamer machen und statt der blitzschnellen kürzen Bursts deine Daten
> langsam und ausdauernd übertragen?

Ich verbummle Zeit durch die langsame Datenrate (eigentlich sollte die 
Datenübertragung in 2-3ms abgeschlossen sein, ich benötige aber derzeit 
ca. 7ms), den Rest der Zeit ist die CPU mit Berechnungen voll 
ausgelastet - soviel Zeit habe ich nicht übrig.
Eigentlich war ich kurz davor, dafür ein kleines FPGA + R2R-DAC-Netzwerk 
verwenden, aber es ist ein Prototyp, daher habe ich das FPGA mal 
weggelassen.

von N. M. (mani)


Lesenswert?

Nebenbei noch die Fragen:
Was für ein Controller genau?

Und

Daniel R. schrieb:
> Ich verbummle Zeit durch die langsame Datenrate (eigentlich sollte die
> Datenübertragung in 2-3ms abgeschlossen sein, ich benötige aber derzeit
> ca. 7ms)

Für wieviel Werte?

von Daniel R. (sparker)


Lesenswert?

N. M. schrieb:
> Nebenbei noch die Fragen:
> Was für ein Controller genau?
STM32F405

>
> Und
>
> Daniel R. schrieb:
>> Ich verbummle Zeit durch die langsame Datenrate (eigentlich sollte die
>> Datenübertragung in 2-3ms abgeschlossen sein, ich benötige aber derzeit
>> ca. 7ms)
>
> Für wieviel Werte?

3 Datenpakete a 32 Bits (ca. 10 kbit/s, etwas höher),
schon wären 100 kbit/s - aber ich denke das ist ein Wunschtraum.

von N. M. (mani)


Lesenswert?

Daniel R. schrieb:
> STM32F405

Wenn ich das richtig sehe hat der 1MSPS.

Daniel R. schrieb:
> 3 Datenpakete a 32 Bits (ca. 10 kbit/s, etwas höher)

Die Angabe kapiere ich nicht. Der DAC hat 12 Bit. Also hat das Register 
vermutlich 16 Bit.
Was du da mit 32 Bit meinst ist mir nicht klar.
Dann 3 Datenpakete. Wie groß sind die Datenpakete? 1000 Werte? 10.000?

Mich interessiert eher wieviel Werte pro Sekunde du versuchst zu 
schreiben.
Wenn du 10kbit/s schreibst wären das 600-800SPS je nach dem ob ich mit 
12 oder 16 Bit rechne.
Bis du da an die 1.000.000SPS kommst musst du schon noch bisschen mehr 
machen.

Daniel R. schrieb:
> 100 kbit/s - aber ich denke das ist ein Wunschtraum

Der uC kann die 1MSPS.
Da muss was anderes nicht passen bei dir.
Hast du die Timer ISRs schon Mal gemessen ob die passen vom Zeitabstand?

von Daniel R. (sparker)


Lesenswert?

N. M. schrieb:
> Daniel R. schrieb:
>> STM32F405
>
> Wenn ich das richtig sehe hat der 1MSPS.
>
> Daniel R. schrieb:
>> 3 Datenpakete a 32 Bits (ca. 10 kbit/s, etwas höher)
>
> Die Angabe kapiere ich nicht. Der DAC hat 12 Bit. Also hat das Register
> vermutlich 16 Bit.
> Was du da mit 32 Bit meinst ist mir nicht klar.
> Dann 3 Datenpakete. Wie groß sind die Datenpakete? 1000 Werte? 10.000?
>
> Mich interessiert eher wieviel Werte pro Sekunde du versuchst zu
> schreiben.
> Wenn du 10kbit/s schreibst wären das 600-800SPS je nach dem ob ich mit
> 12 oder 16 Bit rechne.
> Bis du da an die 1.000.000SPS kommst musst du schon noch bisschen mehr
> machen.
>
> Daniel R. schrieb:
>> 100 kbit/s - aber ich denke das ist ein Wunschtraum
>
> Der uC kann die 1MSPS.
> Da muss was anderes nicht passen bei dir.
> Hast du die Timer ISRs schon Mal gemessen ob die passen vom Zeitabstand?

Moment, da habe ich zu wenig weit gedacht. Die Bits des DAC haben nichts 
mit den Bits auf der Schnittstelle zu tun.
Ich machs konkret:
1
case low: //12,5 kbit/s
2
TIM8->ARR=139; //DAC-Trigger / DMA) - Ramp Counter
3
TIM12->ARR=3579;  //half-bit-counter
Die Daten-Felder für den DAC (der über DMA mit den Daten versorgt wird) 
bestehen aus jeweils 16 Werten, die durch Timer 8 durchgesamplet werden.
Die Entscheidung, welches Feld gesamplet/verwendet wird, hängt von dem 
tatsächlich zu übertragenden Bit ab.
Eine halbe Bitzeit später (Timer 12) wird ein anderes Feld selektiert 
(das ist eben die ursprünglich angegebene HAL-C-Funktion) und dann läuft 
das wieder durch.
In einer gesamten Bitzeit werden 2 unterschiedliche Felder durchlaufen 
(und damit 2 Rampen generiert).

Und jetzt habe ich mir vorgestellt, die Werte für die Timer in etwa 
durch 6 zu teilen - damit dann ca. 6x so schnell.

BWT: Ich habe die max. ausgebbare Frequenz für den DAC gecheckt, die 
müsste noch im Rahmen sein.

: Bearbeitet durch User
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.