To jest kod timera w moim projekcie na 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");
}
}
}
I po uruchomieniu timerReset()
funkcji w środku mojego programu, przerwanie zaczyna się nie kilka sekund później, ale prawie natychmiast. Próbowałem kilka innych timerów, aby sprawdzić, czy nie ma problemu ze sprzętem, ale nie, nie jest.
microcontroller
c
stm32
interrupts
timer
m0drzew
źródło
źródło
Odpowiedzi:
Wpadłem na to z STM32F105. Standardowe funkcje biblioteki peryferyjnej STM32F1xx różnią się nieco od używanych, ale pomysł powinien być taki sam.
TIM_TimeBaseInit()
Uruchomienie tej funkcji spowodowało ustawienie flagi TIM_SR_UIF. Jeszcze nie wróciłem, żeby dowiedzieć się, dlaczego. Po ustawieniu tego bitu przerwanie zostanie uruchomione, gdy tylko zostanie włączone.Aby to naprawić, po zadzwonieniu
TIM_TimeBaseInit()
natychmiast zadzwoniłemTIM_ClearITPendingBit()
. Potem pozwoliłbym przerwać za pomocąTIM_ITConfig()
. To rozwiązało problem.Moja pełna procedura inicjalizacji wygląda następująco:
źródło
__HAL_TIM_CLEAR_FLAG(&htim6, TIM_SR_UIF);
Ponieważ miałem podobny problem i nie znalazłem odpowiedzi, dzielę się swoim doświadczeniem w nadziei na pomoc innym ludziom.
Uważam, że w twoim przypadku ustawienie URS (Źródło żądania aktualizacji) przed zainicjowaniem timera również rozwiązuje problem.
W moim przypadku używam sterowników warstwy niższej, więc przykładowy kod to:
Problem polega na tym, że użyłem funkcji
LL_TIM_SetPrescaler(TIM16, 7999)
iLL_TIM_SetAutoReload(TIM16, 2999)
do skonfigurowania podstawy czasu i odkryłem, że podczas korzystania z tych funkcji wartości nie były aktualizowane, więc musiałem wygenerować zdarzenie, aby zaktualizować wartości za pomocąLL_TIM_GenerateEvent_UPDATE(TIM16)
.Następnie możesz wyczyścić flagę zdarzenia za pomocą
LL_TIM_ClearFlag_UPDATE(TIM16)
przed włączeniem przerwania lub użyćLL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER)
przed wygenerowaniem zdarzenia.źródło
Miałem podobny problem w modzie One Pulse i znalazłem rozwiązanie dla biblioteki HAL. Kiedy kontrolowałem flagi timera w funkcji „TIM2_IRQHandler”, zobaczyłem, że „przechwytywanie flagi porównania 1” jest ustawione. Więc wyczyściłem „przechwyć porównaj flagę 1”. Ale tym razem widziałem, że ustawiona jest opcja „przechwyć flagę porównania 2”. Więc wyczyściłem wszystkie flagi porównania (od 1 do 4) w mojej funkcji „TIM2_IRQHandler” za pomocą następujących kodów.
źródło
Ten sam problem z TIM_TimeBaseInit () i STM32F0xx. Ostatni ciąg tej funkcji:
Ustawia aktualizację zdarzenia w rejestrze generowania zdarzeń. Dlatego sprawdzam moduł obsługi IRQ:
źródło