2017-04-01 1 views
1

J'utilise le microprosseur stm32f103 sur notre carte de conception personnalisée. J'ai utilisé l'interruption de minuterie pour définir une variable de boolère à vrai toutes les 10ms. Je vérifie la valeur de la variable bool dans la boucle principale et si cette variable est vraie, je bascule une led à bord toutes les 500ms. Bien que le drapeau d'interruption de minuterie ait été effacé après avoir terminé le réglage du fonctionnement vrai, le code ne revient pas à la boucle principale et la led n'est pas activée. Minuterie initialiser, interrompre et boucle principale comme suit.C - Le code ne revient pas à l'interrup- teur principal après minuterie

static void MX_TIM2_Init(void) 
{ 
    TIM_ClockConfigTypeDef sClockSourceConfig; 
    TIM_MasterConfigTypeDef sMasterConfig; 

    htim2.Instance = TIM2; 
    htim2.Init.Prescaler = 7199; 
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP; 
    htim2.Init.Period = 99; 
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 
    if (HAL_TIM_Base_Init(&htim2) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 
    if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 
    if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

    if (HAL_TIM_Base_Init(&htim2) != HAL_OK) 
    { 
     /* Initialization Error */ 
     Error_Handler(); 
    } 

    /*##-2- Start the TIM Base generation in interrupt mode ####################*/ 
    /* Start Channel1 */ 
    if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK) 
    { 
     Error_Handler(); 
    } 
} 

void TIM2_IRQHandler(void) 
{ 
    HAL_TIM_IRQHandler(&htim2); 
} 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 
{ 
    task = true; 
} 

La boucle principale

while (1) 
{ 
    if(task == true) 
    { 
     task_timer++; 

     if(task_timer % 50 == 0) 
     { 
      HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_15); 
     } 
     task = false; 
    } 
} 

Lorsque j'utilise instruction else if dans la boucle principale, le code est traité comme prévu.

while (1) 
{ 
    if(task == true) 
    { 
     task_timer++; 

     if(task_timer % 50 == 0) 
     { 
      HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_15); 
     } 
     task = false; 
    } 
    else if(task == false) 
    { 
     ... 
    } 
} 

Il est intéressant de noter que si je n'ai utilisé que l'instruction else, le code fonctionne également de façon instable.

Y at-il quelqu'un peut expliquer la cause de cela.

Merci.

+0

Je ne vois aucun code où vous avez configuré le temporisateur et son interruption, je me demande comment l'interruption sera générée dans ce code. Avez-vous vérifié si votre ISR est réparé en y insérant un autre GPIO et en le vérifiant sur DSO? – Gaurav

+0

S'il vous plaît montrer un [mcve]. En particulier, montrez comment vous avez déclaré la variable 'task'. – kaylum

+0

La variable 'task' est-elle déclarée comme' volatile'? –

Répondre

0

1) Décalage de la tâche en tant que volatile.

2) Désactivez toutes les optimisations du compilateur dans les paramètres.

+0

La désactivation de l'optimisation du compilateur résout le problème. –

+0

@Adwait Patil Je pense que le compilateur traitera normalement les variables volatiles si l'optimisation est désactivée. Ainsi, si une variable est déclarée volatile, alors l'optimisation du compilateur doit être activée sinon elle traitera la variable normalement. – Gaurav