0
\$\begingroup\$

I'm trying to connect the NVIC interrupt to handle a keyboard, nonetheless I'm having troubles becuase two keys are connected to the line0, which use the EXTI0_IRQHandler, I saw in the stm official pages that there is not possible the read two pins separately from the same interrupt line. I would like to know if there is a way to configure this feature. Below Im attaching the code used to initialize the pins is:

GPIOC_KEY_Struct.Pin = GPIO_PIN_0;
GPIOC_KEY_Struct.Mode = GPIO_MODE_IT_RISING;
GPIOC_KEY_Struct.Pull = GPIO_PULLUP;
GPIOC_KEY_Struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOI, &GPIOC_KEY_Struct);

GPIO_InitTypeDef GPIOI_KEY_Struct;
GPIOC_KEY_Struct.Pin = GPIO_PIN_0;
GPIOC_KEY_Struct.Mode = GPIO_MODE_IT_RISING;
GPIOC_KEY_Struct.Pull = GPIO_PULLUP;
GPIOC_KEY_Struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIOI_KEY_Struct);
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);

After the configuration I'm using the IRQ handler function, shown below:

void EXTI0_IRQHandler(void)
  {
    char test[]="0x9B";
    char test1[] = "0x3D";
    int i,a = 0,b = 0;
    //Rutina a seguir en la interrupcion
    a = HAL_GPIO_ReadPin(GPIOA,BOTON_3);
    b = HAL_GPIO_ReadPin(GPIOI,BOTON_3);
    if(a==1)
      {
        HAL_UART_Init(&s_UARTHandle);
        HAL_UART_Transmit(&s_UARTHandle,test1, sizeof(test1), HAL_KEY_DELAY);
        HAL_UART_DeInit(&s_UARTHandle);
        HAL_GPIO_EXTI_IRQHandler(BOTON_3);
      }
    if (b==1)
      {
        HAL_UART_Init(&s_UARTHandle);
        HAL_UART_Transmit(&s_UARTHandle,test, sizeof(test), HAL_KEY_DELAY);
        HAL_UART_DeInit(&s_UARTHandle);
        HAL_GPIO_EXTI_IRQHandler(BOTON_3);
      }
    else
      {
        HAL_GPIO_EXTI_IRQHandler(BOTON_3);
      }
  }

Nonetheless I'm having troubles in the interrupt because when I touch one button it send the two strings, and also only one button is working (the first button that is been configured in the code). Is there a problem in the set up of the pins?

PS.- The same code is used without interrupts and it works perfectly.

\$\endgroup\$
  • \$\begingroup\$ Internal pullups enabled, and active high inputs? How is the thing connected, can you attach schematics? \$\endgroup\$ – berendi Jun 28 at 7:36
0
\$\begingroup\$

I see a problem with your set up:

GPIOC_KEY_Struct.Pin = GPIO_PIN_0;
GPIOC_KEY_Struct.Mode = GPIO_MODE_IT_RISING;
GPIOC_KEY_Struct.Pull = GPIO_PULLUP;
GPIOC_KEY_Struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOI, &GPIOC_KEY_Struct);

GPIO_InitTypeDef GPIOI_KEY_Struct;
GPIOC_KEY_Struct.Pin = GPIO_PIN_0;
GPIOC_KEY_Struct.Mode = GPIO_MODE_IT_RISING;
GPIOC_KEY_Struct.Pull = GPIO_PULLUP;
GPIOC_KEY_Struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIOI_KEY_Struct);

It looks like you copy/pasted the code and changed the name in the declaration of the GPIO_InitTypeDef in the second set, but not the rest of the variable names, it should be:

GPIO_InitTypeDef GPIOI_KEY_Struct;
GPIOI_KEY_Struct.Pin = GPIO_PIN_0;
GPIOI_KEY_Struct.Mode = GPIO_MODE_IT_RISING;
GPIOI_KEY_Struct.Pull = GPIO_PULLUP;
GPIOI_KEY_Struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIOI_KEY_Struct);

Notice I changed GPIOC_KEY_Struct to GPIOI_KEY_Struct?

\$\endgroup\$
  • \$\begingroup\$ Thanks Ron, I've updated the code, nonetheless the problem persist, when I press the GPIOA button it does not send anything and when I press the GPIOI button it sends the information for the two buttons. \$\endgroup\$ – Alejandro Enrique Garcia Navar Jun 27 at 21:33
  • \$\begingroup\$ Where is GPIOA and GPIOI defined? As well as BOTON_3? \$\endgroup\$ – Ron Beyer Jun 27 at 22:17
  • \$\begingroup\$ BOTON_3 is defined as follows and GPIOI is the other argument needed for the function HAL_GPIO_Init #define BOTON_3 GPIO_PIN_0 The code works perfectly when I don't use interrupts vectors, my question is what am I doing wrong with the NVIC interrupt function that makes me not be able to handle the two buttons, or is it not possible to handle two pins at the same time if they are in the same interrupt line? \$\endgroup\$ – Alejandro Enrique Garcia Navar Jun 28 at 0:16
  • \$\begingroup\$ I think I have to see the actual wiring diagram for how you have the two buttons hooked up to GPIO. Do you mean that they share the same GPIO, or do they just share the IRQ and have individual GPIO pins that they also connect to? \$\endgroup\$ – Ron Beyer Jun 28 at 0:34
  • \$\begingroup\$ The share the same interupt line, which is line 0 for all the GPIO_PIN_0 \$\endgroup\$ – Alejandro Enrique Garcia Navar Jun 28 at 1:17
0
\$\begingroup\$

It's not possible to configure both PA0 and PI0 as an interrupt source. Exactly one of them can be active at a given time. There is a configuration register that controls which one, and it can obviously have only a single value.

enter image description here

There are however 32 timer input channels capable of generating interrupts when the state of some pin changes. Check the alternate function mapping tables in the datasheet to see which pins can be connected to timer inputs.

Both PA0 and PI0 can be mapped to timer channels, pick one of them. I'd recommend PA0 for starters, because it can be mapped to TIM2 or TIM5 channel 1, and it'd be in line with the example given in the reference manual.

enter image description here

If contact bounce becomes a problem, you can use the value captured in CCR1, compared with the value acquired the last time the hander was executed, to check the elapsed time since the last rising edge. You might have to set a prescaler if the required debouncing interval is longer.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your help mate, I have updated the code using the function LL_SYSCFG_GetEXTISource (uint32_t Line) it solved the problem with the two detected pressed buttons when I press only one of them, nonetheless I'm having the problem in the pins, because only the last one configured is being use for the interrupt handling. \$\endgroup\$ – Alejandro Enrique Garcia Navar Jun 28 at 16:12
  • \$\begingroup\$ I've changed the MCU for a stm32f407 due to pin availability. the new pin set up is: GPIO_InitTypeDef GPIOC_KEY_Struct; GPIOC_KEY_Struct.Pin = GPIO_PIN_5; GPIOC_KEY_Struct.Mode = GPIO_MODE_IT_RISING; GPIOC_KEY_Struct.Pull = GPIO_PULLUP; GPIOC_KEY_Struct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIOC_KEY_Struct); HAL_NVIC_SetPriority(EXTI9_5_IRQn, 3, 1); HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); GPIOC_KEY_Struct.Pin = GPIO_PIN_5; HAL_GPIO_Init(GPIOB, &GPIOC_KEY_Struct); HAL_NVIC_SetPriority(EXTI9_5_IRQn, 3, 0); HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); \$\endgroup\$ – Alejandro Enrique Garcia Navar Jun 28 at 16:18
0
\$\begingroup\$

The probelm is been solved, what i did was a "port swept" inside the same interrupt line, configuring all the ports at the same time in the interrupt vector but asking only for the one initialized at the time, change the code to this:

  GPIO_PORB_Struct.Pin = KEY_PIN;
  HAL_GPIO_Init(TECLA_PORT_B, &GPIO_PORB_Struct);
  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

  GPIO_PORB_Struct.Pin = KEY_PIN_2;
  HAL_GPIO_Init(TECLA_PORT_B, &GPIO_PORB_Struct);
  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

  HAL_GPIO_Init(TECLA_PORT_A, &GPIO_PORA_Struct);
  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

 HAL_GPIO_Init(TECLA_PORT_C, &GPIO_PORC_Struct);
 HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

The interruption is disable every time it is called and then enabled again with the next port set up

\$\endgroup\$
  • \$\begingroup\$ Simply reading the ports would be a lot easier \$\endgroup\$ – berendi Jul 2 at 18:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.