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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.