2017-05-11 4 views
0

J'ai le problème suivant: J'ai 2 entrées sur mon carte électronique:STM32 HAL GPIO interrompez compte trop Mutch

#define TOR1_IN_uC_Port   GPIOC 
#define TOR1_IN_uC_Pin   GPIO_PIN_5 
#define TOR2_IN_uC_Port   GPIOE 
#define TOR2_IN_uC_Pin   GPIO_PIN_6 

J'ai cette initialisation:

GPIO_InitStruct.Pull = GPIO_NOPULL; 
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; 
GPIO_InitStruct.Pin = TOR1_IN_uC_Pin; 
HAL_GPIO_Init(TOR1_IN_uC_Port, &GPIO_InitStruct); 
GPIO_InitStruct.Pin = TOR2_IN_uC_Pin; 
HAL_GPIO_Init(TOR2_IN_uC_Port, &GPIO_InitStruct); 

HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2, 1); 
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); 

J'ai deux thèses fonctions d'interruption:

void EXTI9_5_IRQHandler(void) 
{ 
    if(__HAL_GPIO_EXTI_GET_IT(TOR1_IN_uC_Pin) != RESET) 
    { 
     HAL_GPIO_EXTI_IRQHandler(TOR1_IN_uC_Pin); 
     __HAL_GPIO_EXTI_CLEAR_IT(TOR1_IN_uC_Pin); 
    } 
    if(__HAL_GPIO_EXTI_GET_IT(TOR2_IN_uC_Pin) != RESET) 
    { 
     HAL_GPIO_EXTI_IRQHandler(TOR2_IN_uC_Pin); 
     __HAL_GPIO_EXTI_CLEAR_IT(TOR2_IN_uC_Pin); 
    } 
} 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 
{ 
    if (GPIO_Pin == TOR1_IN_uC_Pin) 
     Input1.Count++; 
    else if (GPIO_Pin == TOR2_IN_uC_Pin) 
     Input2.Count++; 
} 

J'ai pluged sur les entrées d'un GBF à 10Hz, mais le les compteurs comptent trop mutch. Lorsque j'imprime les compteurs sur le port série, il affiche environ 5kHz

Lorsque je lis manuellement l'état des entrées, je ne peux pas demander si le nombre d'entrées est trop élevé.

Voyez-vous quelque chose qui ne va pas dans mon code? Quelqu'un a une idée?

+0

Qu'est-ce que TOR4_IN_uC_Pin? Je ne vois que les définitions pour 1 et 2. – Yunnosch

+0

C'est un décalage, j'ai corrigé mon poste, merci – Grokiff

+0

Faites un peu de caoutchouc et expliquez comment votre code fonctionne en détail. Peut-être que vous voulez ajouter plus de code, il me semble qu'il doit y avoir plus de code que vous avez montré. Je pense au lien entre HAL_GPIO_EXTI_IRQHandler et HAL_GPIO_EXTI_Callback. Avez-vous besoin de reconnaître/consommer des interruptions? Un facteur de 5kHz/10Hz ressemble moins à une erreur d'algorithme (par exemple, un par un), plus à la fréquence maximale qu'un ISR en boucle peut imprimer en série ... Y at-il quelque chose comme un choix entre déclenchement sur front et niveau? déclenchement? – Yunnosch

Répondre

0

J'ai aussi eu ce problème, il a fallu du temps avant que je le remarque. C'est parce que vous effacez le drapeau IRQ très proche du retour d'interruption. Création d'une interruption tail-chain avec elle-même.

void EXTI9_5_IRQHandler(void) 
{ 
    if(__HAL_GPIO_EXTI_GET_IT(TOR2_IN_uC_Pin) != RESET) 
    { 
     HAL_GPIO_EXTI_IRQHandler(TOR2_IN_uC_Pin); 
     __HAL_GPIO_EXTI_CLEAR_IT(TOR2_IN_uC_Pin); 
    } 
    __DMB(); // add this 
} 

Vous devez attendre que le bus termine l'action d'effacement. Le DMB instruction aide avec ceci. La barrette de mémoire de données agit comme une barrière de mémoire.

Il garantit que tous les accès mémoire explicites qui apparaissent dans l'ordre du programme avant l'instruction DMB sont observés avant tout accès mémoire explicite qui apparaît dans l'ordre du programme après l'instruction DMB. Cela n'affecte pas l'ordre des autres instructions exécutées sur le processeur.

+0

C'est une réponse ridicule. Aucune barrière n'est nécessaire pour effacer le drapeau d'interruption. Merci de ne pas donner de mauvais conseils. –

+0

@PeterJ, pas besoin de non. Vous pouvez également ajouter un tas de nops, ou effacer le drapeau en premier. – Jeroen3

+0

Le drapeau doit être effacé en premier. C'est la règle du pouce. Toutes les barries doivent être considérées comme un mal nécessaire dans des circonstances très spécifiques (et certainement pas dans la routine d'interruption simple). –

0
  1. ExtJ - toujours effacer le drapeau d'abord (autres interruptions), ainsi
  2. commutateur sera toujours générer plus d'un implulse.
  3. HAL & ExtJ - J'ai eu un bon nombre de problèmes avec elle (peut-être que je suis trop paresseux pour apprendre cette bibliothèque monstrueuse) et a commencé à utiliser des registres nus - tous les problèmes était allé instantanément :)
0

Je résolu mon problème , c'était un problème électrique dû au RC circuit entre l'entrée et le micro GPIO.

Le signal prend trop de temps pour s'élever (signal dans la dent de scie). J'ai changé mon compte électronique et le nombre de mirco très bien maintenant.

+1

C'est votre solution. Vous pouvez l'accepter. Peut-être que [cette] page (https://stackoverflow.com/help/self-answer) vous aide. Vous ne pouvez pas le fermer comme dans un forum simple. – kaliczp