This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

can I use the any pins of any ports to detect rising edge?

I am using TM4C129EXL launchpad, I am trying to using the regular GPIO as a edge detector, I checked the NVIC, the port P and Port Q has the specific ISR for specific pin, is there any other way? I knew we can check on the interrupt raw status register to detect which pin actually trig the interrupt?

the reason I ask the question is if I use the portJ it always give me it is the first pin trigger the interrupt even I actually click the second pin.  here is the code I use for the ISR

void GPIOjIntHandler(void)
{
    uint32_t status_int;
    status_int=GPIOIntStatus(GPIO_PORTJ_BASE,true);
    MAP_GPIOIntClear(GPIO_PORTJ_AHB_BASE,GPIO_INT_PIN_0);
    MAP_GPIOIntClear(GPIO_PORTJ_AHB_BASE,GPIO_INT_PIN_1);
    if(status_int&0x01)
    {
    		LEDWrite(CLP_D1, 1);
    }
    else if (status_int&0x02)
    {
    		LEDWrite(CLP_D1, 0);
    }
    else
    {

    }

}

  • Have you properly examined, "status_int" - prior to your cascade of "if" statements?

    This KISS method will indicate the success (or failure) of "status_int." If "status_int" properly reports - it is your "if" statements which fail.

    BTW - may I award "10 out of 10" for your post's title?   Simply great - especially "ANY" Pins on "ANY" Port - crystal clear and brief - BRAVO!

    [edit: somehow - after that title award ceremony - poster added a misplaced "the" wrecking his grammar.]  

  • #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/systick.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "drivers/pinout.h"
    #include "utils/uartstdio.h"
    
    uint32_t g_ui32SysClock;
    
    
    void  InitializeSensor(void)
        {
    
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); //PORT P
        ROM_SysCtlDelay(3);
        GPIOPinTypeGPIOInput(GPIO_PORTP_BASE,GPIO_PIN_3);  //PP3
    
        GPIOPadConfigSet(GPIO_PORTP_BASE, GPIO_PIN_3, GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD);
    
        ROM_GPIOIntTypeSet(GPIO_PORTP_BASE, GPIO_PIN_3, GPIO_HIGH_LEVEL);
    
        //ROM_IntMasterEnable();
    
        GPIOIntEnable(GPIO_PORTP_BASE, GPIO_PIN_3);
    
        ROM_IntEnable(INT_GPIOP3);
        }
    
    void InitalPortJ(void)
    {
    	    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); //PORT P
    	    ROM_SysCtlDelay(3);
    	    GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE,GPIO_PIN_0);  //PP3
    
    	    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD);
    
    	    ROM_GPIOIntTypeSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_RISING_EDGE);
    
    
    	    //ROM_IntMasterEnable();
    
    	    GPIOIntEnable(GPIO_PORTJ_BASE, GPIO_PIN_0);
    	    ROM_IntEnable(INT_GPIOJ);
    
    }
    
    void GPIOJ_IntHandler(void)
    {
    	uint32_t status_int;
    	status_int=GPIOIntStatus(GPIO_PORTJ_BASE,true);
    	MAP_GPIOIntClear(GPIO_PORTJ_BASE,GPIO_INT_PIN_0);
    	if(status_int&0x01)
    	    {
    	    		LEDWrite(CLP_D1, 0);
    	    }
    }
    void GPIOP_IntHandler(void)
    {
        uint32_t status_int;
        status_int=GPIOIntStatus(GPIO_PORTP_BASE,true);
        MAP_GPIOIntClear(GPIO_PORTP_BASE,GPIO_INT_PIN_3);
       // MAP_GPIOIntClear(GPIO_PORTP_AHB_BASE,GPIO_INT_PIN_1);
        if(status_int&0x08)
        {
        		LEDWrite(CLP_D1, 1);
        }
        else
        {
    
        }
    
    }
    
    int main(void) {
    
        //
        // Run from the PLL at 120 MHz.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
                    SYSCTL_CFG_VCO_480), 120000000);
    
    
        //
        // Configure the device pins.
        //
        PinoutSet(false, false);
        InitializeSensor();
        InitalPortJ();
        while (1)
        {
    
        }
        return 0;
    }
    

    Hi, CB1, Thanks for your reply,

    To verify my guess, I did a little experiment with a bread board, I use Port J which there is only one interrupt for entire 8 pins, and I use port P which there are 8 different interrupt for 8 different pin.

    I found that the GPIOIntStatus() return the specific pin address which trigger the interrupt, like I used in the code, the Port P pin 3 trigger the interrupt, so the status_int is 0x08 which is binary 00000100, so this stand for the third pin is the interrupt source,  but for the Port J, there is only one interrupt for the entire port, the out put of the status_int is always the 0x01, which stand for the first pin.

    I will post my code here:

  • I'm thinking (as I did initially) that those Ports featuring, "Specific/Single-Bit, Interrupt Response/Identification" are able to generate up to 8, "distinct" interrupts - each tied to their specific Port bit.  All (other) Ports generate a single, "Communal Port" interrupt.

    Thus - for those "enhanced" (specific bit, interrupt responding Ports) you simply, "Identify the interrupt source thru the simple (entry) into the unique (individual - 1 of n) interrupt handler."   (You may have to read this last sentence (several) times.   Required (several) re-writes - in my attempt to be clear...)

  • Hello Shan,

    You have enabled the Interrupt generation only Pin 0, yet wish to have interrupt status for Pin 1.

    GPIOIntEnable(GPIO_PORTJ_BASE, GPIO_PIN_0);

    You have to enable the pins on which interrupt is expected (when not using Port P or Q).

    Regards
    Amit
  • Hi,

    cb1- said:
    I'm thinking (as I did initially) that those Ports featuring, "Specific/Single-Bit, Interrupt Response/Identification" are able to generate up to 8, "distinct" interrupts - each tied to their specific Port bit

    You are right - this is only for ports P and Q, provided to use the function GPIOIntTypeSet(...) and is mandatory to specify GPIO_DISCRTE_INT or'ed with the required interrupt type. Otherwise the "communal port interrupt" is placed on pin 0 position.

    @Shan Cao: please check your micro, the port J may have only two pins on some micros (see the user manual)

    Regards.

  • Thank you, friend Petrei - always good to view your return here.

    We note Shan has "self-awarded" a Verify to a code-block which FAILS and is otherwise unconvincing. Such "self-awards" prove ALWAYS Suspect and should be viewed w/extreme caution...
  • Hi, Amit, Thanks for your reply, I notice that I have made a mistake, I repeat the experiment, and I can get the same output even though I enable different pin interrupt, but I found that as soon as I touch the button(without a push), the interrupt already trigged. This is related to static electricity.

    Then I noticed that I config the pin as float, so any static electric could charge the pin and trigger the interrupt in regardless of the trigger method(high level low level, edge detection). so I change the code from
    GPIOPadConfigSet(GPIO_PORTP_BASE, GPIO_PIN_3, GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD);
    to
    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_1, GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD_WPU);

    which enable the pull up resistor, in that way the interrupt could be trigged properly.

    My guess is, when I did not enable the pull up resistor, and set the interrupt be trigged by edge sensing, so every time I touch the button(without or with a pressing), the first pin was charged by the static electrics and trigger the interrupt, and that might be why the raw status return always is the first pin.

    Thanks for you good advice, I am sorry for my "self awarded" answer.
  • Hi, Cb1, Thanks for your reply, I am sorry for the "self awarded answer", I was confused by the question for a long time, so as soon as I can make a progress, I got so excited, and make this post, my apology, I will try to be patient in the future.

    Like I said in this post, I guess, static electrics might be the reason for I always get first pin trigged the interrupt as a return of status_int=GPIOIntStatus(GPIO_PORTP_BASE,true), cause I set the pin float without a pull-up resistor, so any environment electricity could make the input pin high and low, so the input is unpredictable.

    Thanks

    Shan
  • Hello Shan,

    Guess time to write the book on Static Charges....

    Regards
    Amit
  • Haha, but just to confirm with you, am I right about the static electric charges.?

    Shan
  • Hello Shan.

    It may be. If you put a Low Pass filter in front of the IO and perform the same experiment, that may help reduce the occurrence of the events.

    Regards
    Amit