Jump to content
lawrence_jeff

GPIO Interrupt Question

Recommended Posts

I have went through all the getting started info and while it goes over timed interrupts it is somewhat lacking on the GPIO pin information, can someone help me figure out what's going on.

I am trying to trigger an interrupt routine on a pin change (for use in software quadrature decoding)

 

In Main I have this (The intention is to set C6 as an input with pull ups enable and trigger a routine called IntGPIOc)

//Setup Port C (6) for interrupts
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_6);
GPIOPadConfigSet(GPIO_PORTC_BASE,GPIO_PIN_6,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_6, GPIO_RISING_EDGE);
GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_6);
ROM_IntMasterEnable();

I have this routine in the code

 

void
IntGPIOc(void)
{
	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 8);

}

 

And I have modified Startup_css to declare and configure the interrupt routine

 

    IntGPIOc,                    			// GPIO Port C

 

When I run - the code compiles and executes correctly and I see the pin go high due to the pull ups, but I can pull it low temporarily and let it go back high and the routine is never called (I have validated through a breakpoint as well as visibly not seeing the LED come on)

 

Any ideas? I have struggled to find even basic documentation on this, the peripheral library guide got me this far but their examples aren't very good.

 

 

 

 

Share this post


Link to post
Share on other sites

Jeff,

 

Here is part of a project I wrote that uses both edges of the interupt  on PB2. Not that I don't modify the startup_css.c as I use GPIOPortIntRegister() to register the interrupt. Regardless of what TI says, I feel it is bad to mod startup_css.c.

.

 

 

#define IR_IN_PERIPHERAL     SYSCTL_PERIPH_GPIOB
#define IR_IN_PORT          GPIO_PORTB_BASE
#define IR_IN_PIN            GPIO_PIN_2
#define IR_OUT_PERIPHERAL     SYSCTL_PERIPH_GPIOB
#define IR_OUT_PORT          GPIO_PORTB_BASE
#define IR_OUT_PIN            GPIO_PIN_0


// this is to look like arduino for testing
void setup(void)
{
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    //FPULazyStackingEnable();

    //
    // Set the clocking to run directly from the crystal.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
                   SYSCTL_OSC_MAIN);
    //
    // Enable processor interrupts.
    //
    IntMasterEnable();

    //
    // Initialize the UART and write status.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);
    UARTprintf("\033c                                                                            ");

    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Enable the GPIO pins for the LED (PF1 & PF2).
    //
    GPIOPinTypeGPIOOutput(LED_PORT, GREEN_LED | RED_LED| BLUE_LED);
    GPIOPinWrite(LED_PORT, GREEN_LED | RED_LED| BLUE_LED, 0);

    //
    // Enable the peripherals used by IR recv
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);

    IntDisable(INT_WTIMER0A);
    //
    // Enable processor interrupts.
    //
    IntMasterEnable();

    //
    // Enable the peripherals used by this example.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);


    //
    // Enable processor interrupts.
    //
    IntMasterEnable();



    // setup for IR - must enable peripheral!
    SysCtlPeripheralEnable(IR_IN_PERIPHERAL);
    IRrecv_Setup(IR_IN_PORT,IR_IN_PIN,WTIMER0_BASE,LED_PORT,GREEN_LED);
    IRrecv_blink13(1);
    IRrecv_enableIRIn();
    UARTprintf("\033[H\033[2J\nIR Decode Dump Example\n");
      UARTprintf("System Clock=%d  %d Mhz\n",SysCtlClockGet(),SysCtlClockGet()/1000000L);
    UARTprintf("Ready...\n");
}


// interrupt code to collect raw data.
// ion edge of inpit in recvpin
// Widths of alternating SPACE, MARK are recorded in rawbuf..
// rawlen counts the number of entries recorded so far.
// First entry is the SPACE between transmissions.
// As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues.
// As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging starts
    interrupt void irRecvISR(void)
    {

        // read the ir input pin
        uint8 irdata = GPIOPinRead(irparams.recvport,irparams.recvpin)!=0;

        // clear pin interrupt here
        GPIOPinIntClear(irparams.recvport,irparams.recvpin);



        switch (irparams.rcvstate)
        {
        case STATE_WAIT :               // In the middle of a gap
            {
                // if we see a mark start timing
                if (irdata == MARK)
                {
                    // store gap time
                    irparams.timer=(LONG_GAP_TICKS)-HWREG(irparams.timerport + TIMER_O_TAV);    // get the timer
                    irparams.rawbuf[irparams.rawlen] = irparams.timer;
                    irparams.rawbits[irparams.rawlen]=irdata;
                    irparams.rawlen++;
                    TimerLoadSet(irparams.timerport,TIMER_A, GAP_TICKS);    // gap time
                    irparams.rcvstate=STATE_RECV;
                }
                else
                {
                    // still no data - just wait again
                    TimerLoadSet(irparams.timerport,TIMER_A, LONG_GAP_TICKS);    // gap time
                }
                break;
            }

        case STATE_RECV:
            {

                if (irparams.rawlen >= RAWBUF-1)
                {
                    // Buffer overflow
                    irparams.rcvstate = STATE_STOP;
                    break;
                }
                irparams.timer=(GAP_TICKS)-HWREG(irparams.timerport + TIMER_O_TAV);    // get the timer
                irparams.rawbuf[irparams.rawlen] = irparams.timer;
                irparams.rawbits[irparams.rawlen]=irdata;
                irparams.rawlen++;
                HWREG(irparams.timerport + TIMER_O_TAV) = GAP_TICKS;    // reset the gap timer

                break;
            }

        case STATE_STOP:                // waiting, measuring gap
            {
                TimerLoadSet(irparams.timerport,TIMER_A, LONG_GAP_TICKS);    // gap time
                HWREG(irparams.timerport + TIMER_O_TAV) = LONG_GAP_TICKS;
            }
        }

        if (irparams.blinkflag)
        {
            if (irdata == MARK)
            {
                GPIOPinWrite(irparams.blinkport,irparams.blinkpin,irparams.blinkpin);    // turn pin 13 LED on
            }
            else
            {
                GPIOPinWrite(irparams.blinkport,irparams.blinkpin,0);    // turn pin 13 LED off
            }
        }

//    UARTprintf("\nGP %08x %d  %x\n",irparams.timer,irparams.timer,irparams.rcvstate,irdata);

    }

//*****************************************************************************
//
// The interrupt handler gap timer interrupt
//
//*****************************************************************************
    interrupt void IRTimerAISR(void)
    {
        // read the ir input pin
        uint8 irdata = GPIOPinRead(irparams.recvport,irparams.recvpin)!=0;
        // store the last count
        // note GAP_TICKS may not be the right thing if not in recv
        // expand to look at the recv_state
        if (irparams.rcvstate == STATE_RECV)
        {
            irparams.timer=GAP_TICKS;   // max time
            irparams.rawbuf[irparams.rawlen] = irparams.timer;
            irparams.rawbits[irparams.rawlen]=0;
            irparams.rawlen++;
        }

        // Clear the timer interrupt.
        //
        TimerIntClear(irparams.timerport, TIMER_TIMA_TIMEOUT);

        // tell recv to stop
        irparams.rcvstate = STATE_STOP;

        // set the timer for a long time
        TimerLoadSet(irparams.timerport,TIMER_A, LONG_GAP_TICKS);    //  long gap time

        if (irparams.blinkflag)
        {
            GPIOPinWrite(irparams.blinkport,irparams.blinkpin,0);    // turn pin 13 LED off        }
        }

    }



    void IRrecv_Setup(uint32 recvport,uint32 recvpin,uint32 timerport,uint32 blinkport,uint32 blinkpin)
    {
        irparams.recvpin = recvpin;
        irparams.recvport =recvport;
        irparams.timerport=timerport;
        irparams.blinkport=blinkport;
        irparams.blinkpin=blinkpin;
        irparams.blinkflag = 0;
        GPIOPinTypeGPIOInput(recvport, recvpin);
        if (blinkport)
        {
            GPIOPinTypeGPIOOutput(blinkport,blinkpin);
        }

    }

// initialization
    void IRrecv_enableIRIn(void)
    {
        uint32 freq;

        freq=SysCtlClockGet();

        // Configure the 64-bit periodic timer spit in half
        // this is to use the prescalers
        //
        //IMER_A set to count main timer 1mhz.  each count
        // is 1 usec  This is to even it out
        TimerEnable(irparams.timerport, TIMER_A);


        // TIMER A
        TimerConfigure(irparams.timerport, TIMER_CFG_SPLIT_PAIR |  TIMER_CFG_A_ONE_SHOT);

        // TIMER_A down
        TimerIntRegister(irparams.timerport,TIMER_A,IRTimerAISR);
        TimerPrescaleSet(irparams.timerport,TIMER_A, freq/1000000ul);    // get number of mHz as pre scale so time base to 1MHz
        TimerLoadSet(irparams.timerport,TIMER_A, GAP_TICKS*2);    // gap time
        HWREG(irparams.timerport + TIMER_O_TAV) = GAP_TICKS*2;    // reset the timer

        TimerEnable(irparams.timerport, TIMER_A);

        IntEnable(INT_WTIMER0A);
        //
        // Setup the interrupts for the timer timeouts.
        //

        TimerIntClear(irparams.timerport, TIMER_TIMA_TIMEOUT);
        TimerIntEnable(irparams.timerport, TIMER_TIMA_TIMEOUT);
        TimerIntClear(irparams.timerport, TIMER_TIMA_TIMEOUT);
        TimerIntEnable(irparams.timerport, TIMER_TIMA_TIMEOUT);

        // initialize state machine variables
        irparams.rawlen = 0;
        irparams.rcvstate = STATE_WAIT;


        // set pin modes
        // now set to interrupt on ir pin transition
        GPIOPortIntRegister(irparams.recvport,irRecvISR);
        GPIOIntTypeSet(irparams.recvport,irparams.recvpin,GPIO_BOTH_EDGES);
        // clear pin interrupt here
        GPIOPinIntClear(irparams.recvport,irparams.recvpin);

        GPIOPinIntEnable(irparams.recvport,irparams.recvpin);
        // clear pin interrupt here
        GPIOPinIntClear(irparams.recvport,irparams.recvpin);


        IntMasterEnable();
    }

Share this post


Link to post
Share on other sites

Here is part of a project I wrote that uses both edges of the interupt  on PB2. Not that I don't modify the startup_css.c as I use GPIOPortIntRegister() to register the interrupt. Regardless of what TI says, I feel it is bad to mod startup_css.c.

.

 

 

It is standard practice to modify the startup file. There are hooks in there to place your interrupts.

 

I have went through all the getting started info and while it goes over timed interrupts it is somewhat lacking on the GPIO pin information, can someone help me figure out what's going on.

I am trying to trigger an interrupt routine on a pin change (for use in software quadrature decoding)

 

In Main I have this (The intention is to set C6 as an input with pull ups enable and trigger a routine called IntGPIOc)

//Setup Port C (6) for interrupts
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_6);
GPIOPadConfigSet(GPIO_PORTC_BASE,GPIO_PIN_6,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_6, GPIO_RISING_EDGE);
GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_6);
ROM_IntMasterEnable();

I have this routine in the code

 

void
IntGPIOc(void)
{
	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 8);

}

 

And I have modified Startup_css to declare and configure the interrupt routine

 

    IntGPIOc,                    			// GPIO Port C

 

When I run - the code compiles and executes correctly and I see the pin go high due to the pull ups, but I can pull it low temporarily and let it go back high and the routine is never called (I have validated through a breakpoint as well as visibly not seeing the LED come on)

 

Any ideas? I have struggled to find even basic documentation on this, the peripheral library guide got me this far but their examples aren't very good.

Jeff, you need to clear your port C interrupt in your interrupt routine.

Share this post


Link to post
Share on other sites

Thank you both for your responses, I added the clear to my interrupt routine and tried some things I saw in that example code, but still no luck. I boiled everything down to a simple sample and still can't get it to trigger the interrupt -I think I must be missing some enable somewhere

 

Here is the simplified project (Based on the lab 2 example from the getting started)

 

#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_ints.h"


void
IntGPIOc(void)
{
	GPIOPinIntClear(GPIO_PORTC_BASE, GPIO_PIN_6);
	//Change LED Color so we can tell it worked
	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 8);

}

int main(void)
{

	SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
	//Init Status Light
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

	//Setup Port C (6) for interrupts
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
	GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_6);
	GPIOPadConfigSet(GPIO_PORTC_BASE,GPIO_PIN_6,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
	GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_6, GPIO_BOTH_EDGES);
	GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_6);
	IntMasterEnable();


	while(1)
	{
		// Turn on the LED
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 2);

	}
}

The only other difference is the 2 lines in the startup where I declare and set the routine.

 

extern void IntGPIOc(void);

 

IntGPIOc, // GPIO Port C

 

I attached the whole project in a zip if that helps, I'm fairly sure its something simple I am missing I just can't figure it out.

Lab2.zip

Share this post


Link to post
Share on other sites

Jeff,

 

You may need to clear the interrupt before enableing it. I got into this habit as some hardware will not interrupt unless it is cleared. It gets into some funcky stqate.  Maybe that is your problem.

 

Clear

enable

clear again

 

 

Johnk

Share this post


Link to post
Share on other sites

Unfortunately no luck - my trimmed down bit of your code did the same thing, I even added a GPIO read to the while loop in my earlier example to validate that the value is changing - so I can see in debug mode that the pin value toggles but the interrupt handler attached to that pin never executes.

 

I'm out of ideas, anyone have any other thoughts?

Share this post


Link to post
Share on other sites

Jeff,

 

I know this sounds dumb, but, dit you hook he correct vector in your startup_ccs???  Try my way and see if that works. if one vertor is missing that could cause a problem.

Also your ISR will turn on the led 8 for just extremley short time as the next instruction in in the shile loop which will turn it off.  Try a toggle inside the ISR and modify the while loop to not touch that particular LED. (remove GPIO_PIN_3 from

 while(1) { // Turn on the LED GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 2); }

 

JohnK

Share this post


Link to post
Share on other sites

John, You are correct, declaring it in code works correctly. If I take my otherwise non working code and add

 

GPIOPortIntRegister(GPIO_PORTC_BASE,IntGPIOc);

 

The interrupt handler fires when I toggle the pin. If I comment that line out and have it in the statup_css_c file it does not. Am I perhaps modifying it incorrectly? I added an external reference using

 

 

 

extern void IntGPIOc(void);


And then in the vector table modified the GPIO Port C line (bolded below). I would guess that even if I had modified the incorrect line it should still have fired the default handler and been stuck in its loop (which I never saw in the debugger).


So I'm glad it works using this other method but confused as to why the startup method doesn't work?


#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (* const g_pfnVectors[])(void) =
{
(void (*)(void))((unsigned long)&__STACK_TOP),
// The initial stack pointer
ResetISR, // The reset handler
NmiSR, // The NMI handler
FaultISR, // The hard fault handler
IntDefaultHandler, // The MPU fault handler
IntDefaultHandler, // The bus fault handler
IntDefaultHandler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
IntDefaultHandler, // SVCall handler
IntDefaultHandler, // Debug monitor handler
0, // Reserved
IntDefaultHandler, // The PendSV handler
IntDefaultHandler, // The SysTick handler
IntDefaultHandler, // GPIO Port A
IntDefaultHandler, // GPIO Port B
IntGPIOc, // GPIO Port C
IntDefaultHandler, // GPIO Port D
IntDefaultHandler, // GPIO Port E
IntDefaultHandler, // UART0 Rx and Tx

 

 

I have simplified the project down to the basics and changed the interrupt handler to change the LED color each time it fires (to make it very obvious when it works and doesn't) and have uploaded the project demonstrating this behavior.

 

John - thanks again for getting me going! I swear I had tried in one of my iterations through your code but must not have.

Lab2.zip

Share this post


Link to post
Share on other sites

Jeff,

 

Problems like this are why I do it the way I do. It also allows me to change ISRs to preform a different function if needed.

 

I am glad I was able to help you.  Maybe we can get TI to do it the right way.

 

 

Regards

JohnK

ps - I have been a professional sortware engineer specializing in BIOS on x86 since 1965. - jek

Share this post


Link to post
Share on other sites

Though the post is a bit old, I am sharing my code that might be useful for someone googling for something similar.

 

/*
This program uses an interrupt routin to toggle the LEDs when SW1 (connected to PF4 pin) is pressed. The program 
remains in forground thread till it receive the interrupt request by pressing SW1, it jumps to the backgrouind thread i.e. IntGPIOF ISR and performs the task
and comes back to the forground thread
*/
 
#define TARGET_IS_BLIZZARD_RA1 //This is required for Keil IDE in order to compile the code with ROM_ functions
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "lm4f120h5qr.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
 
 
 
 
#define LED_RED    0x02 //PF1(Red)
#define LED_BLUE   0x04 //PF2(Blue)
#define LED_GREEN  0x08 //PF3(Green)
 
extern void IntGPIOF(void);
 
int main(void)
{
volatile int ulLoop;
ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
 
ulLoop = SYSCTL_RCGC2_R; //Some delay to stabilize the clock on the GPIO module
 
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 |GPIO_PIN_3);
 
GPIOPortIntRegister(GPIO_PORTF_BASE,IntGPIOF);
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);
GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE);
GPIOPinIntEnable(GPIO_PORTF_BASE, GPIO_PIN_4);
ROM_IntMasterEnable();
 
while(1)
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0xE);
 
}
 
 
}
 
void IntGPIOF(void)
{
volatile int ulLoop;
GPIOPinIntClear(GPIO_PORTF_BASE, GPIO_PIN_4);
GPIO_PORTF_DATA_R |= LED_RED;
for(ulLoop = 0; ulLoop < 900000; ulLoop++){ } // Delay for a bit.
GPIO_PORTF_DATA_R = 0x00;
 
GPIO_PORTF_DATA_R |= LED_GREEN;
for(ulLoop = 0; ulLoop < 900000; ulLoop++){ }
GPIO_PORTF_DATA_R = 0x00;
 
GPIO_PORTF_DATA_R |= LED_BLUE;
for(ulLoop = 0; ulLoop < 900000; ulLoop++){ }
GPIO_PORTF_DATA_R = 0x00;
 
}

Share this post


Link to post
Share on other sites

@@Sahil @@lawrence_jeff,

 

Recently I saw this post.

 

Interrupt enabling was never hard for me. So I decided to give some time to figure out what the actual issue in your first code. I think you need to refer the User Guide of the API after going through the introductory lab sessions to get somewhat clearer view on these APIs.

 

Under NVIC it is specifically mentioned,

 

 

 When statically configured, the interrupts must be explicitly enabled in the NVIC via IntEnable() before the processor can respond to the interrupt(in addition to any interrupt enabling required within the peripheral itself).  

 

But in your code you have not done that. You have not enabled interrupts for PORTC.

 

The workaround proposed works because within the "GPIOPortIntRegister" function internally it calls IntEnable() function. 

 

My working code looks like below,

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_6);
GPIOPadConfigSet(GPIO_PORTC_BASE,GPIO_PIN_6,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_6,GPIO_FALLING_EDGE);
GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_6);
GPIOPinIntClear(GPIO_PORTC_BASE, GPIO_PIN_6);
IntMasterEnable();
IntEnable(INT_GPIOC);

In addition to this code, I included the interrupt handler in the NVIC under 'GPIO port C' and referred to the handler as an 'extern function'. I think you know about that process.

 

The difference between the 'workaround' and this method is that when you use "GPIOPortIntRegister" it will dynamically register the Interrupt handler. So the interrupt handler address will be stored in the SRAM. When the processor is actually catering to the interrupt it will have to fetch this address from the SRAM, which will add some latency to the code. 

 

But if you statically register the interrupt handler through the NVIC, then your flash will contain the required address and the processor do not need to fetch the address from the SRAM. Which will be fast.

 

If we can save some more clock cycles, it is always better to use that method  if the requirement permits you to do so. It will improve performance and save some power.

 

Thank you.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×