Forum: Mikrocontroller und Digitale Elektronik STM32 HAL, n-Anzahl an PWM Pulsen?


von Robert (Gast)


Lesenswert?

Guten Abend,
für einen TLC5940 muss ich exakt 4095 PWM Pulse für einen GSCLK 
generieren.

Dazu starte ich einen Timer im PWM-Modus(alles mit CubeMX konfiguriert) 
und zähle dann manuell die Pulse im Interrupt.

PWM Start:
1
HAL_TIM_PWM_Start_IT(&htim2, 0);

Interrupt IRQ:
1
void TIM2_IRQHandler(void) {
2
  /* USER CODE BEGIN TIM2_IRQn 0 */
3
4
    clkCnt++;
5
    //if we have 4096 pulses we need to Blank and start over.
6
    if (clkCnt == 4095)
7
    {
8
      //code...
9
    }
10
    
11
  /* USER CODE END TIM2_IRQn 0 */
12
  HAL_TIM_IRQHandler(&htim2);
13
  /* USER CODE BEGIN TIM2_IRQn 1 */
14
  /* USER CODE END TIM2_IRQn 1 */
15
}

Funktioniert auch aber kommt mir "dirty" vor weil ich den uC gerne nur 
einmal kurz belasten würde bei einem bestimmten Puls und nicht bei 
jedem...

Nochmal kurz:
Ich suche nach einer sauberen Lösung mit der HAL-Lib ein Event bei einer 
bestimmten Anzahl an PWM-Pulsen auszulösen die weitestgehend im 
Hintergrund läuft.

Jemand eine Idee?
MfG Robert

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Robert schrieb:
> Funktioniert auch aber kommt mir "dirty" vor weil ich den uC gerne nur
> einmal kurz belasten würde bei einem bestimmten Puls und nicht bei
> jedem...
>
> Nochmal kurz:
> Ich suche nach einer sauberen Lösung mit der HAL-Lib ein Event bei einer
> bestimmten Anzahl an PWM-Pulsen auszulösen die weitestgehend im
> Hintergrund läuft.
>
> Jemand eine Idee?

Klar :-)

Das, was Du suchst, nennt sich "repetition counter". Du schreibst 
einfach die Anzahl der gewünschten Auto-Reload-Vorgänge rein und dann 
stoppt der Zähler automatisch nach dieser Anzahl.

Ganz ohne Interrupt und Prozessorbelastung :-)

Edit: Das kann mWn allerdings nicht jeder Timer. Eventuell musst Du also 
einen anderen verwenden.

Eine andere Möglichkeit wäre, durch einen zweiten Timer die 
Ausgangsimpulse als Eingangsimpulse zu zählen und beim gewünschten Wert 
einen (einzelnen) Interrupt auszulösen.

: Bearbeitet durch Moderator
von Robert (Gast)


Lesenswert?

Hallo,
hört sich gut an. Allerdings finde ich leider weder in der HAL 
Dokumentation noch in CubeMX einen Hinweis darauf wie ich den Timer wie 
von dir beschrieben einstelle :(

Bitte höflichst um mehr Erläuterung.
MfG.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Ich hab gerade nochmal nachgeschaut - der Rep-Counter hat leider nur 8 
Bit Breite, das reicht also leider nicht :-/

Dann würde ich es so lösen, dass ich einen zweiten Timer auf den Ausgang 
des ersten schalte und den von 4095 runterzählen lasse. Bei 0 generiert 
der Dir dann ein Counter Underflow Event, das den Interrupt aufruft und 
Deinen ersten Timer stoppen kann.

von Robert (Gast)


Lesenswert?

Hallo,
ja ich bin gestern auch noch bisschen weiter gekommen. Bei dem M4 Cortex 
ist der 8bit bei M7 wären es 16bit.

Also benötige ich die Methode mit dem Timer der die Pulse zählt.

1. Der Timer der meine Pulse zählt arbeitet dann im Input Capture Direct 
Mode richtig?
2. Damit das ganze funktioniert, benötige ich eine physikalische 
Verbindung zwischen meinem PWM-Ausgang und meinem Zähl-Timer Eingang?

Ausgehend davon das der oben genannte Mode richtig ist, wie stelle ich 
den Timer dann ein?

Counter Mode -> Down
Counter Period -> 4095

Welche Auswirkungen hat der Prescaler für den TIM-CLK? Muss ich den auf 
meine PWM Frequenz anpassen?

MfG.

von Christopher J. (christopher_j23)



Lesenswert?

Robert schrieb:
> Also benötige ich die Methode mit dem Timer der die Pulse zählt.
>
> 1. Der Timer der meine Pulse zählt arbeitet dann im Input Capture Direct
> Mode richtig?
> 2. Damit das ganze funktioniert, benötige ich eine physikalische
> Verbindung zwischen meinem PWM-Ausgang und meinem Zähl-Timer Eingang?

Eine physikalische Verbindung wäre ein bisschen "von hinten durch die 
Brust ins Auge". Einige Timer (z.B. Timer 2-5 bei STM32F4) besitzen 
einen Triggerausgang der dann von einem anderen Timer als Triggereingang 
(auf unterschiedlichste Weise) verwurstet werden kann. Bedingung dafür 
ist lediglich, dass der zweite Timer einen "slave mode controller" 
besitzt (was für TIM2-TIM5 ebenso der Fall ist). Siehe beispielsweise 
Seite 336 im F411RE Reference Manual oder den von mir angehängten 
Ausschnitt.

Kurze Zusammenfassung:
1. Man setzt im TIMx_CR2 des ersten Timers (Master) die gewünschten Bits 
für "Master Mode Selection".
2. Man konfiguriert die entsprechenden Bits für TS (Trigger Selection) 
und SMS (Slave Mode Selection) im TIMx_SMCR (Slave Mode Control 
Register) des zweiten Timers (Slave).

Wenn man nun den Master-Timer so konfiguriert, dass er die gewünschte 
Puls-Form ausgibt kann man durch die Interrupt-Routine des Slave-Timers 
den Master-Timer nach einer gewünschten Anzahl an Pulsen stoppen.

Robert schrieb:
> Hallo,
> hört sich gut an. Allerdings finde ich leider weder in der HAL
> Dokumentation noch in CubeMX einen Hinweis darauf wie ich den Timer wie
> von dir beschrieben einstelle :(

Das ist auch kein Wunder, denn dafür gibts das Reference Manual. Die 
Timer bei den STM32 sind schon komplizierte Biester aber dafür kann man 
eben auch (fast) alles mit denen anstellen. Es lohnt sich daher meiner 
Meinung nach unbedingt, einfach mal das Refman durchzuschauen.

Ich wünsche viel Erfolg und RT(F)RM ;)

: 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.