Reputation: 377
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
Reputation: 1019
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