Voici le code de la minuterie dans mon projet sur 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");
}
}
}
Et après avoir exécuté la timerReset()
fonction au milieu de mon programme, l'interruption démarre quelques secondes plus tard, mais presque immédiatement. J'ai essayé quelques autres minuteries pour vérifier s'il n'y a pas de problème matériel, mais non, ce n'est pas le cas.
microcontroller
c
stm32
interrupts
timer
m0drzew
la source
la source
Réponses:
J'ai rencontré ça avec un STM32F105. Les fonctions de la bibliothèque périphérique standard STM32F1xx sont un peu différentes de celles que vous utilisez, mais l'idée devrait être la même.
L'émission de la
TIM_TimeBaseInit()
fonction a entraîné la définition de l'indicateur TIM_SR_UIF. Je ne suis pas encore retourné pour comprendre pourquoi. Une fois ce bit défini, l'interruption se déclenchera dès qu'il sera activé.Pour y remédier, après avoir appelé
TIM_TimeBaseInit()
, j'ai immédiatement appeléTIM_ClearITPendingBit()
. Ensuite, je voudrais activer l'interruption avecTIM_ITConfig()
. Cela a résolu le problème.Ma routine d'initialisation complète ressemble à ceci:
la source
__HAL_TIM_CLEAR_FLAG(&htim6, TIM_SR_UIF);
Comme j'avais un problème similaire et que je n'avais pas trouvé de réponses, je partage mon expérience dans l'espoir d'aider d'autres personnes.
Je crois que dans votre cas, la définition de l'URS (Update Request Source) avant d'initialiser le minuteur résout également le problème.
Dans mon cas, j'utilise les pilotes de couche inférieure, donc un exemple de code serait:
Le problème est que j'utilisais les fonctions
LL_TIM_SetPrescaler(TIM16, 7999)
etLL_TIM_SetAutoReload(TIM16, 2999)
pour configurer la base de temps, et j'ai découvert qu'en utilisant ces fonctions, les valeurs n'étaient pas mises à jour, j'ai donc dû générer un événement pour mettre à jour les valeurs à l'aideLL_TIM_GenerateEvent_UPDATE(TIM16)
.Vous pouvez ensuite soit effacer l'indicateur d'événement en utilisant
LL_TIM_ClearFlag_UPDATE(TIM16)
avant d'activer l'interruption, soit utiliserLL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER)
avant de générer l'événement.la source
J'ai eu un problème similaire dans le mod One Pulse et j'ai trouvé une solution pour la bibliothèque HAL. Lorsque j'ai contrôlé les drapeaux de la minuterie dans la fonction "TIM2_IRQHandler", j'ai vu que "capturer le drapeau de comparaison 1" était réglé. J'ai donc effacé "capture compare flag 1". Mais cette fois, j'ai vu que "capture compare flag 2" est réglé. J'ai donc effacé tous les indicateurs de comparaison (de 1 à 4) dans ma fonction "TIM2_IRQHandler" en utilisant les codes suivants.
la source
Même problème avec TIM_TimeBaseInit () et STM32F0xx. La dernière chaîne de cette fonction:
Il définit l'événement de mise à jour dans le registre de génération d'événements. C'est pourquoi j'ai mis un chèque au gestionnaire IRQ:
la source