Sandeerius
Sandeerius

Reputation: 377

STM32 Interrupt Handeling if condition

How I could have 2 interrupts with one handler by this code below:

SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PB | SYSCFG_EXTICR1_EXTI1_PC;
EXTI->IMR = EXTI_IMR_MR0 | EXTI_IMR_MR1;
EXTI->RTSR = EXTI_RTSR_TR0| EXTI_RTSR_TR1;
/* Configure NVIC for External Interrupt */
/* (6) Enable Interrupt on EXTI0_1 */
/* (7) Set priority for EXTI0_1 */
NVIC_EnableIRQ(EXTI0_1_IRQn); /* (6) */
NVIC_SetPriority(EXTI0_1_IRQn,0); /* (7) */

This is the code that the handler excecute:

void EXTI0_1_IRQHandler(void)
{
    if ((EXTI->PR & EXTI_PR_PR1) == EXTI_PR_PR1)  /* Check line 1 has triggered the IT */
  {
    EXTI->PR = EXTI_PR_PR1; /* Clear the pending bit */
    GPIOC->ODR |= 1<<0;
  }
  if ((EXTI->PR & EXTI_PR_PR0) == EXTI_PR_PR0)  /* Check line 0 has triggered the IT */
  {
    EXTI->PR = EXTI_PR_PR0; /* Clear the pending bit */
    GPIOC->ODR &= ~(1<<0);
 }
} 

The code works fine when I click on the button that is connected to PC1, the LED turns on and when I click on the button that is connected to PB0 the LED turns off. In my if structures I check which line is active but I also want the LED only turns on by clicking on PC1 and not with a click on another pin on line 1, the same for line 0 but I don't know how I can change the conditions for the if structures.

The micro-controller is a STM32F091.

Upvotes: 3

Views: 2141

Answers (1)

imbearr
imbearr

Reputation: 1019

  1. First: you can't connect more than one pin (A..Fx) per EXTIx line (see RM0091 page 177). So EXTI line 0 IRQ is strictly correspond to one pin: C0 in your code.
  2. Second: don't use IRQs for serve buttons. You must implement bounce filter and best idea for this is check button's pin state by timer. Human reaction is about 200ms, really pushed button will produce pulse with duration 100-200ms. So you need timer with 12-24ms and two bytes in RAM for each button... See code example bellow:

    uint8_t btn_state = (uint8_t)0x0, btn_mask = (uint8_t)0x1;
    void some_tim_irq_handler(void)
    {
        if (GPIOC->IDR & (uint16_t)0x1) { // PC0 up
            btn_state |= btn_mask;
        } else {                          // PC0 down
            btn_state &= (uint8_t)~btn_mask;
        }
        btn_mask <<= (uint8_t)0x1;        // mask cycle
        if (btn_state == (uint8_t)0x0) {
            // One state
            return;
        }
        if (btn_state == (uint8_t)0xFF) {
            // Second state
        }
    }
    

Upvotes: 0

Related Questions