Autor Tema: [Solucionado] ¿Como saber que pin causó determinada interrupción (EXTI0)?  (Leído 1997 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Carl47D

  • PIC16
  • ***
  • Mensajes: 160
Que tal,
Me puse a estudiar un poco las HAL de ST, estoy trabajando con la STM32F4Discovery, con el OpenSTM32 como IDE, todo actualizado al día.
Después de leer el manual que describe las HAL para los F4xx (UM1725) pude entender el ejemplo que trae el CubeMX sobre los GPIO y EXTI (Interrupciones externas), y entonces me puse a escribir el mio desde cero sin usar el Cube, lo que hace hasta es disparar una interrupción cuando detecta un flanco de bajada en el botón de usuario de la tarjeta (PA0).
Código: C
  1. #include <stdint.h>
  2.  
  3. #include "stm32f4xx.h"
  4. #include "stm32f4xx_hal.h"
  5. #include "stm32f4xx_hal_rcc.h"
  6. #include "stm32f4xx_hal_gpio.h"
  7.  
  8. #define ONBOARD_PUSH_BTN        GPIO_PIN_0
  9. #define ONBOARD_GREEN_LED       GPIO_PIN_12
  10. #define ONBOARD_ORANGE_LED      GPIO_PIN_13
  11. #define ONBOARD_RED_LED         GPIO_PIN_14
  12. #define ONBOARD_BLUE_LED        GPIO_PIN_15
  13.  
  14. void EXTI0_IRQHandler(void);
  15. static void EXTILine0_Config(void);
  16. static void configLEDS(void);
  17.  
  18. int main(void)
  19. {
  20.         configLEDS();
  21.         EXTILine0_Config();
  22.  
  23.         HAL_GPIO_WritePin(GPIOD, ONBOARD_GREEN_LED, GPIO_PIN_SET);
  24.         HAL_GPIO_WritePin(GPIOD, ONBOARD_ORANGE_LED, GPIO_PIN_RESET);
  25.         HAL_GPIO_WritePin(GPIOD, ONBOARD_RED_LED, GPIO_PIN_SET);
  26.         HAL_GPIO_WritePin(GPIOD, ONBOARD_BLUE_LED, GPIO_PIN_RESET);
  27.  
  28.         while(1){
  29.         }
  30. }
  31.  
  32. static void configLEDS(void){
  33.  
  34.         __HAL_RCC_GPIOD_CLK_ENABLE();
  35.  
  36.         GPIO_InitTypeDef   LEDs_InitStructure;
  37.  
  38.         LEDs_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  39.         LEDs_InitStructure.Pull = GPIO_NOPULL;
  40.         LEDs_InitStructure.Pin = ONBOARD_GREEN_LED
  41.                                                         | ONBOARD_ORANGE_LED
  42.                                                         | ONBOARD_RED_LED
  43.                                                         | ONBOARD_BLUE_LED;
  44.         HAL_GPIO_Init(GPIOD, &LEDs_InitStructure);
  45. }
  46.  
  47. static void EXTILine0_Config(void)
  48. {
  49.   GPIO_InitTypeDef   GPIO_InitStructure;
  50.  
  51.   __HAL_RCC_GPIOA_CLK_ENABLE();
  52.  
  53.   /* Configure PA0 pin as input floating */
  54.   GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
  55.   GPIO_InitStructure.Pull = GPIO_NOPULL;
  56.   GPIO_InitStructure.Pin = ONBOARD_PUSH_BTN;
  57.   HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
  58.  
  59.   /* Enable and set EXTI Line0 Interrupt to the lowest priority */
  60.   HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
  61.   HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  62. }
  63.  
  64. void EXTI0_IRQHandler(void)
  65. {
  66.         HAL_GPIO_EXTI_IRQHandler(0x01);
  67. }
  68.  
  69. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  70. {
  71.         HAL_GPIO_TogglePin(GPIOD, ONBOARD_GREEN_LED);
  72.         HAL_GPIO_TogglePin(GPIOD, ONBOARD_ORANGE_LED);
  73.         HAL_GPIO_TogglePin(GPIOD, ONBOARD_RED_LED);
  74.         HAL_GPIO_TogglePin(GPIOD, ONBOARD_BLUE_LED);
  75. }

Uso EXTI0 porque todos los pines 0 de los puertos del microcontrolador están "conectados" a esa señal:


El problema que tengo ahora es que si añado un botón en PB0 y configuro ese pin para generar una interrupción en un flanco de bajada,
¿Como saber que señal del lado izquierdo (pin 0 de algún puerto) del mux generó el trigger en EXTI0?
¿Existe algún registro que contenga el valor de los pines 0 de todos los puertos (lo dudo xD)?
¿Alguna propuesta más elegante que dentro de EXTI0_IRQHandler leer los pines 0 de todos los puertos en y pasarlo como parámetro al IRQHandler?

Saludos y como habrán notado explicar no es mi fuerte xD
Carlos
« Última modificación: 22 de Octubre de 2016, 15:44:42 por Carl47D »

Desconectado Carl47D

  • PIC16
  • ***
  • Mensajes: 160
Re:[ST HAL] ¿Como saber que pin causó determinada interrupción (EXTI0)?
« Respuesta #1 en: 22 de Octubre de 2016, 05:59:23 »
Me acabo de dar cuenta que es imposible, solo una de las las señales de los pines Px0 entran al mux, nunca podrán pasar dos señales hacia EXTIx al mismo tiempo, eso me pasa por darle muchas vueltas a algo sin observar los detalles, aparte de pensar que todos los micros funcionan igual :S.

Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:[Solucionado] ¿Como saber que pin causó determinada interrupción (EXTI0)?
« Respuesta #2 en: 22 de Octubre de 2016, 09:52:12 »
Ahora que lo decis, pense que era algo base ya esto. Iba a respodner que se puede, pero luego me di cuenta que no.

Me mal acostumbre al integrado de TI. Que es un ARM tambien, pero sus registros de GPIO funcionan distinto.

En el de TI tenes registros para configurar los flancos/niveles etc y ademas tenes registro para habilitar, enmascarar y ver si se disparo alguna interrupcion, SIN llegar al NVIC. Es decir que si vos habilitas y la mascara es correcta, luego lo que te faltaria es habilitar el NVIC para que realmente tengas una interrupcion. En resumen son como 2 modulos completamente distintos cada uno con su habilitacion/flag de estados y en el caso del GPIO flag por pin.

En el caso de ST, acabo de mirar y no... sigue teniendo los registros mas basicos como los de un F0 y se termino. Solo deberias habilitarlo desde el NVIC y nada mas. Por lo cual no podes leer el estado de algun registro de flags, sino que la unica que te queda es leer pin a pin, y encontrar cual es el que hizo ocurrir la interrupcion. Siempre y cuando se mantenga una cantidad de tiempo suficiente para que esto ocurra.

Desconectado Carl47D

  • PIC16
  • ***
  • Mensajes: 160
Re:[Solucionado] ¿Como saber que pin causó determinada interrupción (EXTI0)?
« Respuesta #3 en: 22 de Octubre de 2016, 14:27:21 »
Que tal,
Creo que el F4 que trae el kit es de los más viejos xD y también estoy acostumbrado a los PSoC que también trae un ARM pero mas lentejo xD, ahí las señales que generan interrupciones pasan por una OR y no por un MUX, se puede tener el pin Pa.0 y Pb.0 (donde a y b son diferentes puertos) generando interrupciones independientes, y puedo tener una interrupción para un puerto entero (Pa.0 ... Pa.7), cosa que acá por lo que veo tampoco es posible.

Toca acostumbrarme  :oops:

Saludos
Carlos