cancel
Showing results for 
Search instead for 
Did you mean: 

Does one IRQx handler can be binding with multiple port?

Carter Lee
Associate III
Posted on October 17, 2017 at 10:31

Hi.

I'm not sure whether one IRQ handler can handle multiple ports.

For example, If I made one EXTI3_IRQHandler(), then I want to connect external interrupts PA0, PA1, PA2, PA3 to 

EXTI3_IRQHandler().

Is this possible way? if yes what am I supposed to do?

void EXTI0_Config(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

EXTI_InitStructure.EXTI_Line = EXTI_Line0;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

/* Enable and set EXTI0 Interrupt to the lowest priority */

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void EXTI1_Config(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);

EXTI_InitStructure.EXTI_Line = EXTI_Line1;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void EXTI2_Config(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);

EXTI_InitStructure.EXTI_Line = EXTI_Line2;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void EXTI3_Config(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);

EXTI_InitStructure.EXTI_Line = EXTI_Line3;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

Does one IRQx handler can be binding with multiple port?

1 REPLY 1
Danish1
Lead II
Posted on October 17, 2017 at 11:01

At the hardware level, each interrupt position has its own vector.

There are separate positions for EXTI0, EXTI, EXTI2, EXTI3, EXTI4

But EXTIs 5 to 9 all share the same position

And EXTIs 10 to 15 share another position.

So an interrupt on EXTI0 calls the routine pointed to by the vector entry for EXTI0

Similarly an interrupt on EXTI1 calls a routine pointed to by the vector entry for EXTI1.

At the hardware level, there's nothing stopping you putting the same routine address for the vector entries for each of EXTI0, EXTI1, EXTI2, EXTI3's positions.

But your development environment does not expect this. It wants to have routines of different names e.g. 

EXTI2_IRQHandler() for the EXTI2 position.

What can you do if you want common code for all of those interrupts?

  1. You could duplicate the code for each EXTIn_IRQHandler. Bad points for this are that it uses extra program memory, and risks errors if you need to make a change in the code and don't update all copies of the code.

  2. You could have each EXTIn_IRQHandler call the same subroutine, and put the processing in this common subroutine. This makes execution time marginally longer.

  3. You could edit the vector table that you use for this particular project, so that the positions for EXTI0, EXTI1, EXTI2, EXTI3 each point to the same routine, which (for argument's sake you could call) EXTI0to3_IRQHandler. This also risks errors because it's not a change people normally make.

Hope this helps,

Danish