cancel
Showing results for 
Search instead for 
Did you mean: 

trying to understand EXTI example code

arro239
Associate III
Posted on September 20, 2012 at 03:51

I have EXTI example running on my stm32f4 board but I am having trouble changing the PIN which causes the interrupt.

Here is the initialization method:

void EXTILine0_Config(void)

 

{

 

 

 

  GPIO_InitTypeDef   GPIO_InitStructure;

 

  NVIC_InitTypeDef   NVIC_InitStructure;

 

 

  /* Enable GPIOA clock */

 

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

 

  /* Enable SYSCFG clock */

 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 

 

 

  /* Configure PA0 pin as input floating */

 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

 

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

 

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 

  /* Connect EXTI Line0 to PA0 pin */

 

  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

 

 

  /* Configure EXTI Line0 */

 

  EXTI_InitStructure.EXTI_Line = EXTI_Line0;

 

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

 

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  

 

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

 

  EXTI_Init(&EXTI_InitStructure);

 

 

  /* Enable and set EXTI Line0 Interrupt to the lowest priority */

 

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;

 

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;

 

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;

 

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 

  NVIC_Init(&NVIC_InitStructure);

 

}

I am trying to change the replace GPIO_Pin_0 in ''GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;'' but still - my led is controlled via the same user button, and via applying +3 to PA0, not any other PA pin. I have even tried changing EXTI_PinSource0 - same thing, only PA0 causes the interrupt. I have double checked that I am in fact rebuilding and reflashing a couple of times - I can easily change which LED I control with the EXTI, this confirm that I am in fact do execute the new binary.

What am I missing here?

#pa0 #falling-edge #interrupts
16 REPLIES 16
Posted on September 20, 2012 at 16:07

Hard to say, most pins will default as inputs.

Different pin numbers will cause different EXTI interrupts, you'll need to provide an example of the code that's NOT working, rather than one that IS.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
arro239
Associate III
Posted on September 20, 2012 at 17:11

Sure, here is the code which does not work the way I expect it to work. While I have specified pin_3, I still get the interrupt only if I apply current to PA0 - not PA3 as I would expect

void EXTILine0_Config(void)

 

{

 

 

 

  GPIO_InitTypeDef   GPIO_InitStructure;

 

  NVIC_InitTypeDef   NVIC_InitStructure;

 

 

  /* Enable GPIOA clock */

 

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

 

  /* Enable SYSCFG clock */

 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 

 

 

  /* Configure PA0 pin as input floating */

 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

 

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

 

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 

  /* Connect EXTI Line0 to PA0 pin */

 

  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

 

 

  /* Configure EXTI Line0 */

 

  EXTI_InitStructure.EXTI_Line = EXTI_Line0;

 

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

 

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  

 

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

 

  EXTI_Init(&EXTI_InitStructure);

 

 

  /* Enable and set EXTI Line0 Interrupt to the lowest priority */

 

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;

 

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;

 

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;

 

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 

  NVIC_Init(&NVIC_InitStructure);

 

}
arro239
Associate III
Posted on September 20, 2012 at 20:16

I guess I need EXTI_PinSource3 with GPIO_Pin_3, but do I still use line0 and exti0? Does not work with pin_3, source3, line 0 and exti0. Have also tried line3 and exti3 - same nothing.

Posted on September 20, 2012 at 20:29

For PA3
void EXTILine3_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable GPIOA clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Enable SYSCFG clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Configure PA3 pin as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect EXTI Line3 to PA3 pin */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource3);
/* Configure EXTI Line3 */
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; 
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI Line3 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
// ...
/* Clear the EXTI line pending bit */
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
For PA6
void EXTILine6_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable GPIOA clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Enable SYSCFG clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Configure PA6 pin as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect EXTI Line6 to PA6 pin */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource6);
/* Configure EXTI Line6 */
EXTI_InitStructure.EXTI_Line = EXTI_Line6;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; 
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI Line9-5 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI9_5_IRQHandler(void) // EXTI 5 thru 9 interrupt to here
{
if(EXTI_GetITStatus(EXTI_Line6) != RESET)
{
// ...
/* Clear the EXTI line pending bit */
EXTI_ClearITPendingBit(EXTI_Line6);
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
arro239
Associate III
Posted on September 21, 2012 at 01:48

Thank you

clive1! So, bottom line - all four constants have to be in sync. Kinda a strange solution in terms of four constants with the same index to configure one thing, but I guess it is what low level programming is. And I have totally forgotten about

the Handler part - thanks for saving me there 🙂

void EXTILine_Config(uint32_t GPIO_Pin, uint8_t EXTI_PinSourcex,

 

        uint32_t EXTI_Line, uint8_t NVIC_IRQChannel) {

 

 

    GPIO_InitTypeDef GPIO_InitStructure;

 

    NVIC_InitTypeDef NVIC_InitStructure;

 

 

    /* Enable GPIOA clock */

 

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

 

    /* Enable SYSCFG clock */

 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 

 

    /* Configure pin as input floating */

 

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

 

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin;

 

    GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 

    /* Connect EXTI Line to pin */

 

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSourcex);

 

 

    /* Configure EXTI Line */

 

    EXTI_InitStructure.EXTI_Line = EXTI_Line;

 

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

 

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

 

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

 

    EXTI_Init(&EXTI_InitStructure);

 

 

    /* Enable and set EXTI Line Interrupt to the lowest priority */

 

    NVIC_InitStructure.NVIC_IRQChannel = NVIC_IRQChannel;

 

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;

 

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;

 

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 

    NVIC_Init(&NVIC_InitStructure);

 

}

 

 

void EXTILine0_Config() {

 

    EXTILine_Config(GPIO_Pin_3, EXTI_PinSource3, EXTI_Line3, EXTI3_IRQn);

 

}

 

 

Posted on September 21, 2012 at 02:39

Kinda a strange solution in terms of four constants with the same index to configure one thing, but I guess it is what low level programming is.

Yes, it's a bit inelegant you'd have thought ST could have come up with a more orthogonal scheme. I haven't looked at the constants, sometimes they use indices, others bit vectors, and often more complex encodings.

You also aren't forced to use GPIO bank A, you could pull bit positions from other banks.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
edgarmedina20
Associate II
Posted on May 22, 2014 at 09:11

Hello everybody,

I have a problem with the EXTI in PA0, I'm using the development board stm32f4 Discovery and I'm using the EXTI example, but I need that the interrupt work when the button PA0 is pushed. this is the modificated code:

int main(void)

{

  /* Initialize LED1,2,3,4 mounted on STM32F4-Discovery board */

  LEDInit();

  /* Configure EXTI Line0/1 (connected to PA0 and PA1 pin) in interrupt mode */

  EXTILine_Config();

  /* Generate software interrupt: simulate a rising edge applied on EXTI0 and EXTI1 line */

  EXTI_GenerateSWInterrupt(EXTI_Line0 | EXTI_Line1);

  while (1){  }

}

void LEDInit()

{

  GPIO_InitTypeDef  GPIO_InitStructure;

 

  /* Enable the GPIO_LED Clock */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

  /* Configure the GPIO_LED pin */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

}

void EXTILine_Config(void)

{

  GPIO_InitTypeDef   GPIO_InitStructure;

  NVIC_InitTypeDef   NVIC_InitStructure;

  /* Enable GPIOA clock */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  /* Enable SYSCFG clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  /* Configure PA0 pin as input floating */

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Connect EXTI Line0 to PA0 pin */

  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

  /* Configure EXTI Line0 */

  EXTI_InitStructure.EXTI_Line = EXTI_Line0;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;         //ERROR?

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI Line0 Interrupt to the lowest priority */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

/* Connect EXTI Line0 to PA1 pin */

  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource1);

/* Configure EXTI Line0 */

  EXTI_InitStructure.EXTI_Line = EXTI_Line1;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  //ERROR?

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_ClearITPendingBit(EXTI_Line1);

  EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI Line1 Interrupt to the lowest priority */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

void EXTI0_IRQHandler(void)

{

Delay_ms(1000);//debounce. FOR TEST. but I changed for 1,2,10.

   if(EXTI_GetITStatus(EXTI_Line0) != RESET)

   {

     /* SET LED */

     GPIO_SetBits(GPIOD, GPIO_Pin_13);

   }

   if(EXTI_GetITStatus(EXTI_Line0) == RESET)

   {

/*

RE

SET LED */

GPIO_ResetBits(GPIOD, GPIO_Pin_13);

   }

/* Clear the EXTI line 0 pending bit */

EXTI_ClearITPendingBit(EXTI_Line0);

}

void EXTI1_IRQHandler(void)

{

Delay_ms(1000);//debounce. FOR TEST. but I changed for 1,2,10.

  if(EXTI_GetITStatus(EXTI_Line1) != RESET)

  {

    /* SETLED */

    GPIO_SetBits(GPIOD, GPIO_Pin_12);

  }

  else if(EXTI_GetITStatus(EXTI_Line1) == RESET)

  {

  GPIO_ResetBits(GPIOD, GPIO_Pin_12);

  }

/* Clear the EXTI line 0 pending bit */

EXTI_ClearITPendingBit(EXTI_Line1);

}

The problem is, the interrupt is activated in both conditions when I push the button. but this is terrible error, and I tested only the Falling edge interrupt and not work!,  in others words When I pushed the button, the two ''IF'' worked, but I thought ''THE BOUNCE'', so I inserted a delay for a debounce but doesn't have any effect. maybe did I configurate bad the interrupt?.

tranvanduy
Associate II
Posted on March 10, 2015 at 10:36

Hi all, I am using STM32F030F4P6 (20 pins), I use PA0, PA1,... as EXTI_Line are OK, but I can't use PB1 pin for EXTI.

When I config PB1 as EXTI_Line1, it works on PA1, I can't understand, how to use PB1 ax EXTI1.

I use Keil uVision v5.12.

Thanks all!
Posted on March 10, 2015 at 13:10

When I config PB1 as EXTI_Line1, it works on PA1, I can't understand, how to use PB1 as EXTI1.

You can only use one source per index. So you could use either PA1 or PB1, but not both.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..