Это код для таймера в моем проекте на 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");
}
}
}
И после запуска timerReset()
функции в середине моей программы прерывание начинается не спустя несколько секунд, а почти сразу. Я попробовал несколько других таймеров, чтобы проверить, нет ли проблем с оборудованием, но нет, это не так.
microcontroller
c
stm32
interrupts
timer
m0drzew
источник
источник
Ответы:
Я столкнулся с этим с STM32F105. Функции стандартной периферийной библиотеки STM32F1xx немного отличаются от того, что вы используете, но идея должна быть такой же.
При
TIM_TimeBaseInit()
вызове функции флаг TIM_SR_UIF стал установленным. Я еще не вернулся, чтобы выяснить, почему. Как только этот бит установлен, прерывание сработает, как только оно будет включено.Чтобы это исправить, после звонка
TIM_TimeBaseInit()
я сразу позвонилTIM_ClearITPendingBit()
. Тогда я бы включил прерывание сTIM_ITConfig()
. Это решило проблему.Моя полная процедура инициализации выглядит следующим образом:
источник
__HAL_TIM_CLEAR_FLAG(&htim6, TIM_SR_UIF);
Поскольку у меня была похожая проблема, и я не нашел ответов, я делюсь своим опытом в надежде помочь другим людям.
Я полагаю, что в вашем случае установка URS (источника запроса на обновление) перед инициализацией таймера также решает проблему.
В моем случае я использую драйверы нижнего уровня, поэтому пример кода:
Проблема заключается в том, что я использовал
LL_TIM_SetPrescaler(TIM16, 7999)
иLL_TIM_SetAutoReload(TIM16, 2999)
функцию для настройки базы времени, и я обнаружил , что при использовании этих функций, значения были не обновляется, так что я должен был генерировать событие для обновления значений с помощьюLL_TIM_GenerateEvent_UPDATE(TIM16)
.Затем вы можете либо очистить флаг события, используя
LL_TIM_ClearFlag_UPDATE(TIM16)
перед включением прерывания, либо использоватьLL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER)
перед генерацией события.источник
У меня была похожая проблема в моде One Pulse, и я нашел решение для библиотеки HAL. Когда я управлял флагами таймера в функции «TIM2_IRQHandler», я увидел, что установлен «флаг сравнения захвата 1». Поэтому я очистил «захватить флаг сравнения 1». Но на этот раз я увидел, что «захват сравнить флаг 2» установлен. Поэтому я очистил все флаги сравнения (от 1 до 4) в моей функции «TIM2_IRQHandler», используя следующие коды.
источник
Та же проблема с TIM_TimeBaseInit () и STM32F0xx. Последняя строка этой функции:
Он устанавливает событие обновления в регистре генерации событий. Вот почему я поставил проверку обработчику IRQ:
источник