stm32 interrupción externa siempre pendiente

0

En mi proyecto basado en stm32F107, uso cuatro pines (PINE 12-15) para alcanzar un nivel creciente en ellos.

Mi problema: dos pines siempre producen interrupciones externas pero no hay un nivel ascendente en ellas y otros dos pines nunca responden a un nivel creciente.

Mi pregunta: estoy buscando algunas formas de depuración y pueden ser consejos. Puede que leer algunos registros en la rutina de interrupción ayude a resolver mi problema.

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

      GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;

      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
      GPIO_Init(GPIOE, &GPIO_InitStruct);

      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
      GPIO_Init(GPIOE, &GPIO_InitStruct);

      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
      GPIO_Init(GPIOE, &GPIO_InitStruct);

      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
      GPIO_Init(GPIOE, &GPIO_InitStruct);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

      EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt; 
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    // KeyI_0
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_Pin_12);
        EXTI_InitStructure.EXTI_Line    = EXTI_Line12;
        EXTI_Init(&EXTI_InitStructure); 

    // KeyI_1
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_Pin_13);
        EXTI_InitStructure.EXTI_Line    = EXTI_Line13;
        EXTI_Init(&EXTI_InitStructure);

    // KeyI_2
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_Pin_14);
        EXTI_InitStructure.EXTI_Line    = EXTI_Line14;
        EXTI_Init(&EXTI_InitStructure);

    // KeyI_3
            GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_Pin_15);
            EXTI_InitStructure.EXTI_Line    = EXTI_Line15;
            EXTI_Init(&EXTI_InitStructure);  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           
      NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
      NVIC_Init(&NVIC_InitStructure);

 void EXTI15_10_IRQHandler(void)
{
  printf("exti\n");
  if (EXTI_GetFlagStatus(EXTI_Line12) != RESET) {
    EXTI_ClearITPendingBit(EXTI_Line12); 
    printf("key1\n");
    //keyboard_StringStart(0);
  } else if (EXTI_GetFlagStatus(EXTI_Line13) != RESET) {
      EXTI_ClearITPendingBit(EXTI_Line13);
      printf("key2\n");
      //keyboard_StringStart(2);
  } else if (EXTI_GetFlagStatus(EXTI_Line14) != RESET) {
      EXTI_ClearITPendingBit(EXTI_Line14);
      printf("key3\n");
      //keyboard_StringStart(3);
  } else if (EXTI_GetFlagStatus(EXTI_Line15) != RESET) {
      EXTI_ClearITPendingBit(EXTI_Line15);
      printf("key4\n");
      //keyboard_StringStart(1);
  }
}
    
pregunta r_spb

2 respuestas

0

Así que fue un error en la sintaxis del código.

Eso es incorrecto:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_Pin_12);

Eso es correcto:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource12);

Lo siento por perder el tiempo.

    
respondido por el r_spb
1

Ya que pregunta por métodos de depuración para problemas como este, lo primero que haría (después de asegurarme de que el microcontrolador esté correctamente anulado y de que el poder sea bueno) es hacer que funcione sin problemas con UNA interrupción configurada y habilitada, y entonces y solo luego pasar a más de uno. Agréguelas una a la vez y vea dónde van las cosas mal.

No sé qué está haciendo tu printf particular. Supongo que va a algún tipo de semihosting en tu entorno de desarrollo. En cualquier caso, lo perdería hasta que haya resuelto este problema. Utilice alguna salida GPIO como indicadores de que se recibió la interrupción, probablemente activando cada uno. Como regla general, las cosas largas y complicadas deben evitarse en las interrupciones. Puede intentar deshabilitar la interrupción mientras está en ella y volver a activarla en el camino de regreso. Ese printf toma una gran cantidad de tics del reloj, y el rebote (ver más abajo) puede volver a activarse.

Otro problema sería el cambio de rebote. Es posible que esté provocando una interrupción cada vez que accione el interruptor. Incluso cuando apagas el interruptor, es probable que tengas bordes ascendentes. Puede hacer rebotar en el hardware o software, pero nuevamente, hasta que tenga un control sobre él, le recomiendo que active las interrupciones desde una salida digital en otro puerto.

Además, usar un multímetro aquí realmente no es la herramienta correcta. Si el problema radica en las señales que van a los pines PORTE, no hay forma de que lo encuentre sin un alcance. Si todo lo demás no funciona, debería tratar de manejar estas entradas mejor , pero sin saber qué son ahora, no podemos aconsejarle sobre esto. Si tuviera un alcance, podría usar la interrupción para establecer un poco alto, activar el alcance en eso y ver la señal del puerto que lo causó.

Si superar su problema de esta manera no le ayuda a descubrir el problema subyacente (o alguien con un ojo mejor que yo puede ver el error en su código), actualice para informarnos el paso en el que las cosas van mal y Podemos tomar otra grieta en ello.

    
respondido por el Scott Seidman

Lea otras preguntas en las etiquetas