Forum: Mikrocontroller und Digitale Elektronik STM32 Timer mehrere Compare Values mit DMA


von energetic (Gast)


Lesenswert?

Hallo zusammen,

folgendes Problem: Für einen Timer auf einem STM32H7 habe ich ein Array 
mit mehreren compare values (die keinerlei Schema aufweisen), z.B. so
1
uint16_t compare_vals = { 100, 160, 200, 320, ... };

Beim erreichen eines Wertes möchte ich einen GPIO Pin toggeln. Ich 
könnte natürlich in der ISR vom ersten Compare value den nächsten setzen 
usw., aber wäre es auch möglich soetwas per DMA und ohne jegliches zutun 
des Cores zu lösen?
D.h. dass der DMA quasi immer den nächsten Wert aus dem Array als neuen 
Compare value setzt?

Viele Grüße,
energetic

von Christopher J. (christopher_j23)


Lesenswert?

Ja, das geht. Schau mal in AN4776 "General-purpose Timer Cookbook".

von energetic (Gast)


Lesenswert?

Vielen Dank für die Antwort :)
Das Timer-Cookbook kenne ich schon. Wo genau soll ich denn da fündig 
werden? :P Die einzige Section, bei der es um DMA geht ist am Ende der 
DMA-Burst-Transfer und das sah beim ersten Lesen nicht nach dem aus, was 
ich suche.

Vielleicht muss ich es mir aber auch einfach nochmal genauer ansehen...

von Hans-Georg L. (h-g-l)


Lesenswert?

energetic schrieb:
> Vielen Dank für die Antwort :)
> Das Timer-Cookbook kenne ich schon. Wo genau soll ich denn da fündig
> werden? :P Die einzige Section, bei der es um DMA geht ist am Ende der
> DMA-Burst-Transfer und das sah beim ersten Lesen nicht nach dem aus, was
> ich suche.
>
> Vielleicht muss ich es mir aber auch einfach nochmal genauer ansehen...

Lesen bildet ;-)
Beim nächsten Abschnitt "arbitrary waveform generation" ist es doch 
ausführlich beschrieben wie man die Register des Timers mit dem 
DMA-burst setzen kann. Vielleicht reicht es bei dir ja nur das Compare 
Register neu zu beschreiben ...

von Robert (bertl100)


Lesenswert?

Ich habe mich jetzt auch mit diesem feature befasst.

Ich kann mit "HAL_TIM_PWM_START_DMA" das array mit den comparevalues
verwenden.
Für meinen Fall müsste ich allerdings, so wir im applicationnote 
beschrieben,
alle 3 Werte, also ARR, RCR und CCR gemiensam setzten um meinen 
Anforderungen zu entsprechen.

Ein Call auf "HAL_TIM_DMABurst_MultiwriteStart" funktioniert aber nicht. 
Hat da jemand zwischenzeitlich damit Erfahrung?
Möglicherweise fehlt mir da einfach nur was.

LG

Robert

von Andreas B. (abm)


Lesenswert?

TIMx_DMAR ist das Zauberwort. Man stellt DBA im TIMx_DCR so ein, dass 
auf das/die gewünschte(n) TIMx_CCRx gezeigt wird, und je nach Anzahl der 
Kanäle, die bedient werden sollen stellt man DBL entsprechend ein.

von Robert (bertl100)


Lesenswert?

Vielen Dank für den Hinweis!

LG

Robert

von Robert (bertl100)



Lesenswert?

Habe da noch meine Probleme damit.

Was momentan funktioniert:
1
const uint32_t wave_buffer[9] = {58, 0, 58, 0, 116, 0, 116, 0, 116};
2
3
status = HAL_DMA_Start_IT(PWM1->hdma[TIM_DMA_ID_UPDATE], wave_buffer, (uint32_t)PWM1->Instance->DMAR, 9);
4
5
status = HAL_TIM_PWM_Start_DMA(PWM1, TIM_CHANNEL_1, wave_buffer, 9);

So bekomme ich ein PWM-Signal, welches leider nur den CCR1, also die 
Pulsbreite entsprechend ändert.

Mir wäre sehr geholfen, wenn mir dankenswerterweise jemand ein 
funktionierendes Beispiel geben könnte, wo alle 3 Register gesetzt 
werden.

LG

Robert

: Bearbeitet durch User
von Robert (bertl100)


Lesenswert?

Hab's hingekommen!!!!

Danke!

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.