mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32F07VG Discovery - EXTI15_10_IRQHandler mit mehreren Interrupts


Autor: Robin H. (robin_h319)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich mache mich gerade mit dem STM32F407VG vertraut. Ich habe vorher viel 
mit dem MSP430G2553 und Arduino programmiert.

Ich habe zwei buttons an den STM32 angeschlossen und möchte diese über 
Interrupts abfragen. Wie ich das mache, wenn ich für jeden eine einzelne 
EXTI_Line nutze, weiß ich bereits. Zum Beispiel PD0 und PB12. Dafür habe 
ich ein Programm gefunden. Mir ist auch bewusst, dass ich für eine EXTI 
Line nicht zwei Interrupts nutzen kann.

Wie verhält sich das, wenn ich z.B. EXTI Line 12 und 13 nehmen möchte? 
Zum Beispiel: PB12 und PB13

Dafür habe ich ein Programm geschrieben und beim Debuggen fliege ich bei 
beiden Buttons in die ISR. Mein Problem ist das löschen der Flags. Im 
IRQ Handler sieht das wie folgt aus:
/* Handle PB12 interrupt */
void EXTI15_10_IRQHandler(void) {
    /* Make sure that interrupt flag is set */

    if ((EXTI_GetITStatus(EXTI_Line12) != RESET) && (EXTI_GetFlagStatus(EXTI_Line12) != RESET)){
        /* Do your stuff when PB12 is changed */
        EXTI_ClearITPendingBit(EXTI_Line12);
    }
    if ((EXTI_GetITStatus(EXTI_Line13) != RESET) && (EXTI_GetFlagStatus(EXTI_Line13) != RESET)) {
        /* Do your stuff when PB12 is changed */
        EXTI_ClearITPendingBit(EXTI_Line13);
    }
}

Ich hatte angenommen, dass ich über EXTI_GetFlagStatus(EXTI_LineX) das 
enstprechende Flag abarbeiten kann. Aber unabhängig davon, welchen 
Button ich drücke, es werden immer BEIDE Flags gelöscht - also 
ClearITPendingBit() für EXTI_Line12 und 13 ausgeführt.

Ist es möglich, dass nur das enstprechende Flag gelöscht wird, dass auch 
aufgetreten wird? Oder kann ich das im EXTI15_10_IRQHandler nicht 
unterscheiden?

Vielen Dank und Grüße,
Robin

Ich hatte ein BSP gefunden und das dann um PB13 erweitert
Hier der gesamte Code:
#include "stm32f4xx.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_syscfg.h"
#include "misc.h"


/* Configure pins to be interrupts */
void Configure_PD0(void) {
    /* Set variables used */
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    /* Enable clock for GPIOD */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    /* Enable clock for SYSCFG */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Set pin as input */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD, &GPIO_InitStruct);

    /* Tell system that you will use PD0 for EXTI_Line0 */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);

    /* PD0 is connected to EXTI_Line0 */
    EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    /* Enable interrupt */
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    /* Interrupt mode */
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    /* Triggers on rising and falling edge */
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    /* Add to EXTI */
    EXTI_Init(&EXTI_InitStruct);

    /* Add IRQ vector to NVIC */
    /* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
    /* Set priority */
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    /* Set sub priority */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
    /* Enable interrupt */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* Add to NVIC */
    NVIC_Init(&NVIC_InitStruct);
}

void Configure_PB12(void) {
    /* Set variables used */
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    /* Enable clock for GPIOB */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    /* Enable clock for SYSCFG */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Set pin as input */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Tell system that you will use PB12 for EXTI_Line12 */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);

    /* PB12 is connected to EXTI_Line12 */
    EXTI_InitStruct.EXTI_Line = EXTI_Line12;
    /* Enable interrupt */
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    /* Interrupt mode */
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    /* Triggers on rising and falling edge */
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    /* Add to EXTI */
    EXTI_Init(&EXTI_InitStruct);

    /* Add IRQ vector to NVIC */
    /* PB12 is connected to EXTI_Line12, which has EXTI15_10_IRQn vector */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
    /* Set priority */
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    /* Set sub priority */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
    /* Enable interrupt */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* Add to NVIC */
    NVIC_Init(&NVIC_InitStruct);
}

void Configure_PB13(void) {
    /* Set variables used */
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    /* Enable clock for GPIOB */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    /* Enable clock for SYSCFG */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Set pin as input */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Tell system that you will use PB12 for EXTI_Line12 */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource13);

    /* PB12 is connected to EXTI_Line12 */
    EXTI_InitStruct.EXTI_Line = EXTI_Line13;
    /* Enable interrupt */
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    /* Interrupt mode */
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    /* Triggers on rising and falling edge */
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    /* Add to EXTI */
    EXTI_Init(&EXTI_InitStruct);

    /* Add IRQ vector to NVIC */
    /* PB12 is connected to EXTI_Line12, which has EXTI15_10_IRQn vector */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
    /* Set priority */
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    /* Set sub priority */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x02;
    /* Enable interrupt */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* Add to NVIC */
    NVIC_Init(&NVIC_InitStruct);
}


/* Set interrupt handlers */
/* Handle PD0 interrupt */
void EXTI0_IRQHandler(void) {
    /* Make sure that interrupt flag is set */
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
        /* Do your stuff when PD0 is changed */


        /* Clear interrupt flag */
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

/* Handle PB12 interrupt */
void EXTI15_10_IRQHandler(void) {
    /* Make sure that interrupt flag is set */

    if ((EXTI_GetITStatus(EXTI_Line12) != RESET) && (EXTI_GetFlagStatus(EXTI_Line12) != RESET)){
        /* Do your stuff when PB12 is changed */
        EXTI_ClearITPendingBit(EXTI_Line12);
    }
    if ((EXTI_GetITStatus(EXTI_Line13) != RESET) && (EXTI_GetFlagStatus(EXTI_Line13) != RESET)) {
        /* Do your stuff when PB12 is changed */
        EXTI_ClearITPendingBit(EXTI_Line13);
    }
}

int main(void) {
    /* System init */
    SystemInit();
    /* Configure PD0 as interrupt */
    Configure_PD0();
    /* Configure PB12 and PB13 as interrupt */
    Configure_PB12();
    Configure_PB13();


    while (1) {

    }
}

Autor: Giovanni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich würde die
&& (EXTI_GetFlagStatus(EXTI_Line12) != RESET)
 weglassen.

Vor
EXTI_ClearITPendingBit(EXTI_Line12);
 kannste die Pins abfragen

Autor: Robin H. (robin_h319)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Giovanni schrieb:
> VorEXTI_ClearITPendingBit(EXTI_Line12); kannste die Pins abfragen

wie kann ich den Pin abfragen? Gibt es dafür von ARM auch irgend ne 
fertige Funktion für?

Autor: STM Apprentice (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin H. schrieb:
> wie kann ich den Pin abfragen? Gibt es dafür von ARM auch irgend ne
> fertige Funktion für?

Kann man alles in der

stm32f4xx_gpio.c

spicken und in der

stm32f4xx.h

die Strukturdefinitionen nachlesen.

Autor: Markus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
>ich mache mich gerade mit dem STM32F407VG vertraut. Ich habe vorher viel
>mit dem MSP430G2553 und Arduino programmiert.

Vielleicht wäre Dich auch das STM32GENERIC interessant. Ist zwar grad 
noch in der Entwicklung, aber das Discovery wird rudimentär unterstützt.

Autor: Robin H. (robin_h319)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STM Apprentice schrieb:
> Kann man alles in der
>
> stm32f4xx_gpio.c

Danke, da habe ich es gefunden.

Sieht jetzt so aus und scheint auch zu funktionieren:
void EXTI15_10_IRQHandler(void) {
    /* Make sure that interrupt flag is set */
  if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == Bit_SET){
    if ((EXTI_GetITStatus(EXTI_Line12) != RESET)){
      /* Do your stuff when PB12 is changed */
      EXTI_ClearITPendingBit(EXTI_Line12);
    }
  }

  if ((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13) == Bit_SET)){
    if ((EXTI_GetITStatus(EXTI_Line13) != RESET)){
      /* Do your stuff when PB12 is changed */
      EXTI_ClearITPendingBit(EXTI_Line13);
    }
  }
}

danke.

Markus schrieb:
> Vielleicht wäre Dich auch das STM32GENERIC interessant. Ist zwar grad
> noch in der Entwicklung, aber das Discovery wird rudimentär unterstützt.

Die werde ich mir auch mal anschauen!

Autor: STM Apprentice (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin H. schrieb:
> Die werde ich mir auch mal anschauen!

Vorsicht, das ist Arduino!

Ja ja, die C&P Fehlerteufelchen

Robin H. schrieb:
/* Do your stuff when PB12 is changed */
   EXTI_ClearITPendingBit(EXTI_Line13);

Autor: Felix F. (wiesel8)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sind deine Taster angeschlossen? Low/High Active? Schaltplan? Ohne 
das kann man deinen falschen Code nicht korrigieren.

mfg

Autor: STM Apprentice (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Felix F. schrieb:
> Ohne das kann man deinen falschen Code nicht korrigieren.

Robin H. schrieb:
> Sieht jetzt so aus und scheint auch zu funktionieren:

Autor: Felix F. (wiesel8)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STM Apprentice schrieb:
> Felix F. schrieb:
>> Ohne das kann man deinen falschen Code nicht korrigieren.
>
> Robin H. schrieb:
>> Sieht jetzt so aus und scheint auch zu funktionieren:

/* Triggers on rising and falling edge */
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
Steigend + fallend bei einem Taster? Glaub ich kaum...

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
Default High, er will also anscheinend bei fallender Flanke in den 
Int...

if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == Bit_SET){
    if ((EXTI_GetITStatus(EXTI_Line12) != RESET)){
      /* Do your stuff when PB12 is changed */
      EXTI_ClearITPendingBit(EXTI_Line12);
    }
  }
Er prüft aber, ob der Pin immer noch High ist?????????????
Bit wird also nicht gelöscht.

(Code) Lesen bildet!!!

Bzgl. entprellen will ich hier gar nicht anfangen.

mfg

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.