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.

多组GPIO共用同一个中断函数问题。

1将GPIOA PIN0-7跟GPIOB PIN0-7 这16根IO设定为input 

2:将这两组的IO中断函数都注册到同一个函数IntGPIOHandler();

问题:

问题1:在IntGPIOHandler如何知道是哪个Port(A或者B)产生的中断

问题2:在中断函数中通过GPIOIntStatus(SLAVE_INT_BASE[u8i],0)可以判断哪个PIN被举起来,代表0-7的那根PIN产生中断

问题3:问题2中如果这里有一些PIN的中断是同时来的,eg PIN0跟PIN1,这样GPIOIntStatus(SLAVE_INT_BASE[u8i],0) 读出来的是0x03;这时候通过GPIOIntClear(SLAVE_INT_BASE[u8i],PIN0);将PIN0清掉,退出ISR,因PIN1的还没有清除,原本希望能够因为PIN1再进一次ISR,但实际发现退出后PIN1的ISR也没有来。

以上如何规避?

  • //多组GPIO 设定同一个中断函数IntGPIOHandler
    void Sys_InitialGPIOINT(uint32_t *u32MaskCH )
    {
    uint8_t i;
    for (i=0; i<40; i++)
    {
    //if(u16MaskCH & ( 1 << i ))
    if((u32MaskCH[i%32] & ( 1 << i )))
    {
    SysCtlPeripheralEnable(SLAVE_INT_PERIPH[i]);
    GPIOPinTypeGPIOInput(SLAVE_INT_BASE[i], SLAVE_INT_PIN[i]);
    GPIOPadConfigSet(SLAVE_INT_BASE[i], SLAVE_INT_PIN[i],GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
    //ROM_IntEnable(INT_GPIOD);
    ROM_GPIOIntTypeSet(SLAVE_INT_BASE[i],SLAVE_INT_PIN[i],GPIO_RISING_EDGE);
    //GPIOIntEnable(SLAVE_INT_BASE[i],SLAVE_INT_PIN[i]);
    Sys_GpioIntEnable(u32MaskCH);
    GPIOIntRegister(SLAVE_INT_BASE[i], IntGPIOHandler);
    GPIOIntClear(SLAVE_INT_BASE[i],SLAVE_INT_PIN[i]);
    }
    }
    }

    main
    {
    Sys_InitialCLK(SYSCTL_XTAL_25MHZ,120000000);//TI_Board Input Clk 25MHZ,Bridge use 12MHZ
    Sys_PortFunctionInit();
    Sys_InitialUart(3,115200);
    Sys_InitialGPIOINT(uint32_t *u32MaskCH );
    }

    void IntGPIOHandler(void)
    {
    // unsigned int Status;
    // uint32_t ui32Temp=0;
    // UARTprintf("GPIOInt\n");
    // ROM_GPIOIntClear(GPIO_PORTD_BASE,GPIO_INT_PIN_1);
    uint8_t u8i;
    unsigned int Status;
    static uint8_t u8ShotCnt=0;
    for(u8i=0;u8i<40;u8i++)
    {
    Status=0;
    Status=GPIOIntStatus(SLAVE_INT_BASE[u8i],0);
    UARTprintf("0_S%d=0x%x,Pin=0x%x\n",u8i,Status,SLAVE_INT_PIN[u8i]);
    Status=GPIOIntStatus(SLAVE_INT_BASE[u8i],1);
    UARTprintf("1_S%d=0x%x,Pin=0x%x\n",u8i,Status,SLAVE_INT_PIN[u8i]);
    if(Status&SLAVE_INT_PIN[u8i])
    {
    // UARTprintf("INT Map\n");
    GPIOIntClear(SLAVE_INT_BASE[u8i],SLAVE_INT_PIN[u8i]);
    Status=GPIOIntStatus(SLAVE_INT_BASE[u8i],0);
    UARTprintf("u8i=%d,Pin=0x%x\n",u8i,Status);
    // INTBitMap[u8i/32]=INTBitMap[u8i/32]|(1<<u8i);
    u8i>=32 ? (INTBitMap[u8i/32]=(INTBitMap[u8i/32]|(1<<(u8i-32)))):(INTBitMap[u8i/32]=(INTBitMap[u8i/32]|(1<<u8i)));
    break;
    }
    }
    }
  • 我觉得芯片也不是万能的,既然有这样的缺陷,就应该避免这样的情况,外部中断就是这样,个人觉得无解,最好不要共用一个中断或者避免同时按下。
  • 1:不同个Port的中断函数不要一样,通过port 中断的优先权,可以解决不同port上不同pin同时发生的中断,这个合理。

    2:但同一组port的IO中断,只能注册一个Port的中断函数;通过Status=GPIOIntStatus(Port,0)可以得到那个Pin产生了中断,然后GPIOIntClear(Port pin)清其中一个pin 的中断,退出中断后,还会再进一次中断吗?

    一个实例 GPIOA的Pin0跟Pin1同时产生中断(或者说它俩中断的时间上非常近)

    在GPIOAISR里面Status=GPIOIntStatus(Port,0);看到了Pin0跟Pin1;

    故意只清GPIOIntClear(PortA,Pin0);然后退出GPIOAISR;

    退出后会因为PortA Pin1的INT status没有清,再进来一次吗?

  • 我认为不会,如果还会再次进入的话,中断的实时性不就没有了吗?