Grokiff
Grokiff

Reputation: 29

STM32 HAL GPIO interrupt count too much

I've got the following problem: I've got 2 inputs on my electronic board:

#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

I've got this 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);

I've got theses two functions for 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++;
}

I've pluged on the inputs a GBF at 10Hz, but the counters counts too much. When I print the counters on the serial port, it shows about 5kHz

When I read manually the state of the inputs, I can't verify if the input count too much.

Upvotes: 1

Views: 1816

Answers (3)

Grokiff
Grokiff

Reputation: 29

I solved my problem, it was an electrical issue due to the R.C. circuit between the input and the micro GPIO.

The signal takes too much time to rise (signal in saw tooth). I changed my electronic and the mirco count very well now.

Upvotes: 1

0___________
0___________

Reputation: 67835

  1. EXTI - always clear the IT flag first (other interrupts as well)
  2. Switch will always generate more than one implulse.
  3. HAL & EXTI - I had a lots of issues with it (maybe I am too lazy to learn this monstrous library) and started using bare registers - all problems had gone instantly :)

Upvotes: 0

Jeroen3
Jeroen3

Reputation: 935

I've had this problem too, it took a while before I noticed it. It is because you clear the IRQ flag very close the interrupt return. Creating a tail-chain interrupt with itself.

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
}

You have to wait for the bus to finish the clear action. The DMB instruction helps with this.

Data Memory Barrier acts as a memory barrier. It ensures that all explicit memory accesses that appear in program order before the DMB instruction are observed before any explicit memory accesses that appear in program order after the DMB instruction. It does not affect the ordering of any other instructions executing on the processor.

Upvotes: 2

Related Questions