AnsweredAssumed Answered

Solved: STM32F4Discovery EXTI Multiple Interrupts

Question asked by honeycutt.matt on Jan 3, 2014
Latest reply on Jan 3, 2014 by honeycutt.matt
EDIT: Solved by clive1! See post below.



Hi (again),

I'm tinkering with Interrupts this week. I'n the example code I have provided below, The Green light flashes (as expected) in the loop. The EXTI0 fires when I bring the PA0 pin high. However, when I bring the PC5 pin high nothing happens :( Not sure, what i'm doing wrong, or is there a special way of handeling multiple interrupts? Google and the (soso) search here didn't show much.

As always any help is appreciated! 

#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_exti.h>
#include <stm32f4xx_syscfg.h>
#include <stm32f4xx.h>
#include <misc.h>
 
void InitGPIO(GPIO_TypeDef*, uint16_t, GPIOMode_TypeDef);
void Attach_GPIO_Interrupt(uint8_t, uint8_t, uint32_t, EXTITrigger_TypeDef, uint8_t);
void Delay();
 
 
int main()
{
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
    InitGPIO(GPIOA, GPIO_Pin_0, GPIO_Mode_IN); //initialise PA0 is input
    InitGPIO(GPIOC, GPIO_Pin_5, GPIO_Mode_IN);// PC5 as input
 
    //Green
    InitGPIO(GPIOD, GPIO_Pin_12, GPIO_Mode_OUT);
    //Blue
    InitGPIO(GPIOD, GPIO_Pin_15, GPIO_Mode_OUT);
    //Orange
    InitGPIO(GPIOD, GPIO_Pin_13, GPIO_Mode_OUT);
         
    //attach interrupt to GPIO PA0
    Attach_GPIO_Interrupt(EXTI_PortSourceGPIOA, EXTI_PinSource0, EXTI_Line0, EXTI_Trigger_Rising, 1);
     
    //interrupt to PC5
    Attach_GPIO_Interrupt(EXTI_PortSourceGPIOC, EXTI_PinSource5, EXTI_Line2, EXTI_Trigger_Rising_Falling, 1);
 
    for (;;)
    {
        GPIO_WriteBit(GPIOD, GPIO_Pin_12, Bit_SET);
        Delay();
        GPIO_WriteBit(GPIOD, GPIO_Pin_12, Bit_RESET);
        Delay();
    }
   
}
 
extern "C" void EXTI0_IRQHandler(void) //EXTI0 ISR
{
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) //check if EXTI line is asserted
    {
        EXTI_ClearFlag(EXTI_Line0); //clear interrupt
        //Enter your code here
 
        GPIO_WriteBit(GPIOD, GPIO_Pin_15, Bit_SET);
        Delay();
        GPIO_WriteBit(GPIOD, GPIO_Pin_15, Bit_RESET);
    }
}
 
extern "C" void EXTI2_IRQHandler(void) //EXTI2 ISR
{
    if (EXTI_GetITStatus(EXTI_Line2) != RESET) //check if EXTI line is asserted
    {
        EXTI_ClearFlag(EXTI_Line2); //clear interrupt
        //Enter your code here
 
        GPIO_WriteBit(GPIOD, GPIO_Pin_13, Bit_SET);
        Delay();
        GPIO_WriteBit(GPIOD, GPIO_Pin_13, Bit_RESET);
    }
}
 
void Delay()
{
    int i;
    for (i = 0; i < 1000000; i++)
        asm("nop");
}
 
void InitGPIO(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIOMode_TypeDef GPIO_Mode)
{
    GPIOPuPd_TypeDef PuPdMode = GPIO_PuPd_NOPULL;
    GPIO_InitTypeDef  GPIO_InitStructure;
 
    switch (GPIO_Mode)
    {
        case GPIO_Mode_OUT:
            PuPdMode = GPIO_PuPd_NOPULL; //digital output. Not using open drain mode as I do not know how that operates
            break;
        case GPIO_Mode_IN:
            PuPdMode = GPIO_PuPd_NOPULL; //digital read have Pin as input floating
            break;
        case GPIO_Mode_AN:
            PuPdMode = GPIO_PuPd_NOPULL; //for analogue read have Pin as input floating
            break;
        case GPIO_Mode_AF: //need to do a remapping if using alternate functions
            PuPdMode = GPIO_PuPd_UP; //for PWM have not looked at accounting for the various other alternate functions
            break;
    }
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
    //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //used for digital output and PWM output
    //this setting does not matter for ADC and digital read
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
    GPIO_InitStructure.GPIO_PuPd = PuPdMode;
    GPIO_Init(GPIOx, &GPIO_InitStructure);
}
 
void Attach_GPIO_Interrupt(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex, uint32_t EXTI_Line,
    EXTITrigger_TypeDef EXTI_Trigger, uint8_t Priority)
{
    uint8_t EXTI_IRQn = 0;
    switch (EXTI_Line)
    {
    case 0x1:
        EXTI_IRQn = EXTI0_IRQn;
        break;
    case 0x2:
        EXTI_IRQn = EXTI1_IRQn;
        break;
    case 0x4:
        EXTI_IRQn = EXTI2_IRQn;
        break;
    case 0x8:
        EXTI_IRQn = EXTI3_IRQn;
        break;
    case 0x10:
        EXTI_IRQn = EXTI4_IRQn;
        break;
    case 0x20: case 0x40: case 0x80: case 0x100: case 0x200:
        EXTI_IRQn = EXTI9_5_IRQn;
        break;
    case 0x400: case 0x800: case 0x1000: case 0x2000: case 0x4000: case 0x8000:
        EXTI_IRQn = EXTI15_10_IRQn;
        break;
    }
 
    /* Connect EXTI Line to appropriate GPIO Pin */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx, EXTI_PinSourcex);
 
    NVIC_InitTypeDef   NVIC_InitStructure;
    EXTI_InitTypeDef   EXTI_InitStructure;
 
    /* Configure EXTI Line */
    EXTI_InitStructure.EXTI_Line = EXTI_Line;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
 
    /* Enable and set EXTI Line Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = Priority;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

Outcomes