Dies ist der Code für den Timer in meinem Projekt auf STM32F429:
//timer initialization
void timerInit()
{
uwPrescalerValue2 = (uint32_t) ((SystemCoreClock / 2) / 100000) - 1;
RS485Timer.Instance = TIM5;
RS485Timer.Init.Period = 67400000; // high value to notice interrupt even without debugging
RS485Timer.Init.Prescaler = 400000;
RS485Timer.Init.ClockDivision = 0;
RS485Timer.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&RS485Timer);
}
void timerReset()
{
HAL_TIM_Base_Stop_IT(&RS485Timer);
HAL_TIM_Base_DeInit(&RS485Timer);
HAL_TIM_Base_Init(&RS485Timer);
HAL_TIM_Base_Start_IT(&RS485Timer);
printf("%d timer reset\n", countereset);
countereset++;
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* TIMx Peripheral clock enable */
__TIM5_CLK_ENABLE();
/*##-2- Configure the NVIC for TIMx #########################################*/
/* Set the TIMx priority */
HAL_NVIC_SetPriority(TIM5_IRQn, 7, 1);
/* Enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(TIM5_IRQn);
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim)
{
__TIM5_FORCE_RESET();
__TIM5_RELEASE_RESET();
HAL_NVIC_DisableIRQ(TIM5_IRQn);
}
void TIM5_IRQHandler(void)
{
if (__HAL_TIM_GET_FLAG(&RS485Timer, TIM_FLAG_UPDATE) != RESET) //In case other interrupts are also running
{
if (__HAL_TIM_GET_ITSTATUS(&RS485Timer, TIM_IT_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_FLAG(&RS485Timer, TIM_FLAG_UPDATE);
HAL_TIM_IRQHandler(&RS485Timer);
printf("timer interrupt\n");
}
}
}
Und nachdem timerReset()
ich die Funktion mitten in meinem Programm ausgeführt habe, startet der Interrupt nicht wenige Sekunden später, sondern fast sofort. Ich habe einige andere Timer ausprobiert, um zu überprüfen, ob es kein Hardwareproblem gibt, aber nein, das ist es nicht.
microcontroller
c
stm32
interrupts
timer
m0drzew
quelle
quelle
Antworten:
Ich bin mit einem STM32F105 darauf gestoßen. Die Funktionen der STM32F1xx Standard Peripheral Library unterscheiden sich ein wenig von denen, die Sie verwenden, aber die Idee sollte dieselbe sein.
Durch die Ausgabe der
TIM_TimeBaseInit()
Funktion wurde das Flag TIM_SR_UIF gesetzt. Ich bin noch nicht zurückgegangen, um herauszufinden, warum. Sobald dieses Bit gesetzt ist, wird der Interrupt ausgelöst, sobald er aktiviert ist.Um das Problem zu beheben
TIM_TimeBaseInit()
, habe ich nach dem Anruf sofort angerufenTIM_ClearITPendingBit()
. Dann würde ich den Interrupt mit aktivierenTIM_ITConfig()
. Dies hat das Problem behoben.Meine vollständige Initialisierungsroutine sieht folgendermaßen aus:
quelle
__HAL_TIM_CLEAR_FLAG(&htim6, TIM_SR_UIF);
Da ich ein ähnliches Problem hatte und keine Antworten gefunden hatte, teile ich meine Erfahrungen in der Hoffnung, anderen Menschen zu helfen.
Ich glaube, dass in Ihrem Fall das Einstellen der URS (Update Request Source) vor dem Initialisieren des Timers auch das Problem löst.
In meinem Fall verwende ich die Low-Layer-Treiber. Ein Beispielcode wäre also:
Das Problem ist, dass ich die Funktionen
LL_TIM_SetPrescaler(TIM16, 7999)
undLL_TIM_SetAutoReload(TIM16, 2999)
verwendet habe, um die Zeitbasis zu konfigurieren, und festgestellt habe, dass bei Verwendung dieser Funktionen die Werte nicht aktualisiert wurden. Daher musste ich ein Ereignis generieren, um die Werte mithilfe zu aktualisierenLL_TIM_GenerateEvent_UPDATE(TIM16)
.Sie können dann entweder das Ereignisflag mit löschen,
LL_TIM_ClearFlag_UPDATE(TIM16)
bevor Sie den Interrupt aktivieren, oder es verwenden,LL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER)
bevor Sie das Ereignis generieren.quelle
Gleiches Problem mit TIM_TimeBaseInit () und STM32F0xx. Die letzte Zeichenfolge dieser Funktion:
Es setzt das Aktualisierungsereignis im Ereignisgenerierungsregister. Deshalb habe ich den IRQ-Handler überprüft:
quelle