es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Habilitar la interrupción de GPIO desde cero.

Intenté implementar código para la interrupción GPIO desde cero, pero no funciona.
Intenté depurar y ver el contenido de cada registro que uso, parecen estar bien.
Publico la parte relacionada del código que creé, ¿alguien puede ayudarme a encontrar el error?

La siguiente parte del código se utiliza para inicializar el puerto GPIO, en este caso muestro la parte relacionada con la configuración del modo de interrupción.

void GPIOInit (GPIOhandle_t *pGPIOHandle){
      ….
     
      // Otro código no relacionado con interrupciones
        
      ….

      // Modo de interrupción

      if (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RT) {

         // Configure EXTI para generar una interrupción si ocurre el flanco de subida y la eliminación del flanco de bajada
         EXTI->RTSR1 |= (1 << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
         EXTI->FTSR1 &= ~(1 << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));

      } else if (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_FT){

         // Configure EXTI para generar una interrupción si ocurre el flanco de bajada y la eliminación del flanco de subida
         EXTI->FTSR1 |= (1 << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
         EXTI->RTSR1 &= ~(1 << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));

      } else if (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RFT){

         // Configure EXTI para generar una interrupción si ocurre el flanco de subida y el conjunto del flanco de bajada
         EXTI->RTSR1 |= (1 << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
         EXTI->FTSR1 |= (1 << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));

      }

      // Configure el registro SYSCFG para el selector de multiplexor
      uint8_t EXTICRx_Index; // índice EXTICRx; 0, 1, 2, 3
      uint8_t EXTICRx_Position; // Posición dentro del EXTICRx

      __RCC_SYSCFG_ENABLE_CLK(); // Habilitar el reloj para SYSCFGs

      EXTICRx_Index = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 4;
      EXTICRx_Position = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 4;

      if (pGPIOHandle->pGPIOx == GPIOA){
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x0 << (4 * EXTICRx_Position));
      } else if (pGPIOHandle->pGPIOx == GPIOB) {
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x1 << (4 * EXTICRx_Position));
      } else if (pGPIOHandle->pGPIOx == GPIOC) {
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x2 << (4 * EXTICRx_Position));
      } else if (pGPIOHandle->pGPIOx == GPIOD) {
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x3 << (4 * EXTICRx_Position));
      } else if (pGPIOHandle->pGPIOx == GPIOE) {
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x4 << (4 * EXTICRx_Position));
      } else if (pGPIOHandle->pGPIOx == GPIOF) {
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x5 << (4 * EXTICRx_Position));
      } else if (pGPIOHandle->pGPIOx == GPIOG) {
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x6 << (4 * EXTICRx_Position));
      } else if (pGPIOHandle->pGPIOx == GPIOH) {
         // Clear y set
         SYSFG->EXTICR[EXTICRx_Index] &= ~(0xf << (4 * EXTICRx_Position));
         SYSFG->EXTICR[EXTICRx_Index] |= (0x7 << (4 * EXTICRx_Position));
      }

      // Habilitar la interrupción para ese pin
      EXTI->IMR1 |= (1 << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));

}

….

// Otro código no relacionado con interrupciones

….

Esta función configura NVIC para habilitar la interrupción para ese IRQNumber.

void GPIOITConfig (uint8_t IRQNumber, uint8_t EnOrDi){

    if(EnOrDi == ENABLE){

        if(IRQNumber <= 31){

            *(NVIC_ISER0) |= (1 << IRQNumber);

        }else if(IRQNumber > 31 && IRQNumber < 64){

            *(NVIC_ISER1) |= (1 << (IRQNumber % 32));

        }else if(IRQNumber > 63 && IRQNumber < 96){

            *(NVIC_ISER2) |= (1 << (IRQNumber % 64));
        }

    }else if(EnOrDi == DISABLE){

        if(IRQNumber <= 31){

            *(NVIC_ICER0) |= (1 << IRQNumber);

        }else if(IRQNumber > 31 && IRQNumber < 64){

            *(NVIC_ICER1) |= (1 << (IRQNumber % 32));

        }else if(IRQNumber > 63 && IRQNumber < 96){

            *(NVIC_ICER2) |= (1 << (IRQNumber % 64));

        }
    }
}

Esta función establece la prioridad de interrupción.

void GPIOITPriority(uint8_t IRQNumber, uint32_t IRQPriority){

    // 1. primero averigüemos el registro ipr
    uint8_t iprx = IRQNumber / 4;
    uint8_t iprx_section = IRQNumber % 4;

    uint8_t shift_amount = (8 * iprx_section) + (8 – 4);

    *(NVIC_PR_BASE_ADDR + iprx) |= (IRQPriority << shift_amount);
}

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Basándonos en el código proporcionado, no parece contener errores obvios relacionados con la configuración de interrupción GPIO. Sin embargo, podría haber varias razones por las que no funcione, como una configuración de pin incorrecta, una configuración de interrupción incorrecta o un manejo de interrupción incorrecto.

    Para depurar aún más el problema, se recomienda verificar primero si se está activando la interrupción agregando algunas declaraciones de depuración o utilizando un depurador. Si la interrupción no se está activando, verifique si se ha configurado correctamente el pin para el modo de interrupción y si el registro EXTI está configurado correctamente.

    Si la interrupción se está activando pero no se está manejando correctamente, verifique si la función del controlador de interrupción se ha implementado correctamente y si el registro NVIC está configurado correctamente.

    Además, es recomendable verificar la hoja de datos del MCU STM32 específico que se está utilizando para verificar cualquier requisito o limitación específicos relacionados con la configuración de interrupción GPIO.

Comments are closed.