Forum: Mikrocontroller und Digitale Elektronik STM PWM-Erzeugung


von Andy (Gast)


Lesenswert?

Hey, ich habe ein kleines Problem und hoffe das mir jemand weiterhelfen 
kann.
Zur Zeit versuche ich mit einem STM32F2 ein PWM-Signal mit Hilfe des 
Timer2 zu erzeugen. Das ist auch gar kein Problem.

Jetzt wollte ich eine Verzögerungszeit nach Starten des Timers einbauen, 
in der am Ausgang des GPIO_Pin ein High oder Low Signal (einstellbar) 
anliegen soll.

Ablauf nach Starten des Timers:

1.Verzögerungszeit
2.eigentliches PWM-Signal

(1)------(2)__--__--__--__...

oder invertiert

______--__--__--__--...

Ich hab überlegt das zuerst die Werte für die Verzögerungszeit in die 
Register des Timers geschrieben werden und bei Erreichen des 
CompareWertes einen einmaligen Interrupt auslös. Dieser schreibt die 
neuen Werte für die PWM in das Register.

------(I)__--__--__--... --> in der Art

Jetzt habe ich allerdings das Problem, das der Wechsel mit Hilfe des 
Interrupts nicht wie erwünscht funktioniert.

------|------|____--__--__--__--


Hier meine Timer2 Config

void TIM2_Configuration(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_Period = 3000;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  TIM_ARRPreloadConfig(TIM2, ENABLE);

  /* TIM PWM1 Mode configuration */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 2000;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC3Init(TIM2, &TIM_OCInitStructure);
  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);


  TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);

  TIM_ClearFlag(TIM2, TIM_FLAG_Update);


  TIM_UpdateRequestConfig(TIM2, TIM_UpdateSource_Regular);

  // Clear update pending flag
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);

  /* TIM2 enable counter */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_Init(&NVIC_InitStructure);

  NVIC_EnableIRQ(TIM2_IRQn);

  TIM_Cmd(TIM2, ENABLE);

}

und hier der Interrupt Handler:

void TIM2_IRQHandler(void)
{
  TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);

  if(Verzoegerungszeit == 0)
  {
    Verzoegerungszeit = 1;

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2);

    TIM_PrescalerConfig(TIM2, 0, TIM_PSCReloadMode_Immediate);

    TIM_SetAutoreload(TIM2, 500);

    TIM_ARRPreloadConfig(TIM2, ENABLE);

    TIM_SetCompare3(TIM2, 250);

    TIM_SetCompare1(TIM1, 20);

  }
}

über Hilfe wäre ich sehr dankbar.

von Christoph (Gast)


Lesenswert?

Hallo,

nimm doch einen zweiten Timer, der STM hat ja genügend davon ;-) Den 
lässt du loslaufen und setzt deinen gewünschten Pegel. In dessen ISR 
hältst du ihn an und startest deinen PWM-Timer. Dann musst du den 
Wartetimer am Anfang nur noch so konfigurieren, dass du ein Interrupt 
nach der gewünschten Wartezeit hast. Hab so mal eine Wartezeit für eine 
Ultraschall-Messung realisiert, klappt prima. Was du am Ende der 
Wartezeit machst ist ja egal.

Viele Grüße,
Christoph

von james (Gast)


Lesenswert?

Challo da,

ich hab zwei Vorschläge:

1.) Ist "Verzoegerungszeit" als volatile deklariert?

2.) Vielleicht lassen sich einige Dinge die du in der ISR am Timer 
veränderst nur machen, wenn der Timer disabled ist.

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.