简体   繁体   中英

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.

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.

I solved my problem, it was an electrical issue due to the RC 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.

  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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM