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


von Robin H. (robin_h319)


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:
1
/* Handle PB12 interrupt */
2
void EXTI15_10_IRQHandler(void) {
3
    /* Make sure that interrupt flag is set */
4
5
    if ((EXTI_GetITStatus(EXTI_Line12) != RESET) && (EXTI_GetFlagStatus(EXTI_Line12) != RESET)){
6
        /* Do your stuff when PB12 is changed */
7
        EXTI_ClearITPendingBit(EXTI_Line12);
8
    }
9
    if ((EXTI_GetITStatus(EXTI_Line13) != RESET) && (EXTI_GetFlagStatus(EXTI_Line13) != RESET)) {
10
        /* Do your stuff when PB12 is changed */
11
        EXTI_ClearITPendingBit(EXTI_Line13);
12
    }
13
}

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:
1
#include "stm32f4xx.h"
2
#include "stm32f4xx_exti.h"
3
#include "stm32f4xx_syscfg.h"
4
#include "misc.h"
5
6
7
/* Configure pins to be interrupts */
8
void Configure_PD0(void) {
9
    /* Set variables used */
10
    GPIO_InitTypeDef GPIO_InitStruct;
11
    EXTI_InitTypeDef EXTI_InitStruct;
12
    NVIC_InitTypeDef NVIC_InitStruct;
13
14
    /* Enable clock for GPIOD */
15
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
16
    /* Enable clock for SYSCFG */
17
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
18
19
    /* Set pin as input */
20
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
21
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
22
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
23
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
24
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
25
    GPIO_Init(GPIOD, &GPIO_InitStruct);
26
27
    /* Tell system that you will use PD0 for EXTI_Line0 */
28
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);
29
30
    /* PD0 is connected to EXTI_Line0 */
31
    EXTI_InitStruct.EXTI_Line = EXTI_Line0;
32
    /* Enable interrupt */
33
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
34
    /* Interrupt mode */
35
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
36
    /* Triggers on rising and falling edge */
37
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
38
    /* Add to EXTI */
39
    EXTI_Init(&EXTI_InitStruct);
40
41
    /* Add IRQ vector to NVIC */
42
    /* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
43
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
44
    /* Set priority */
45
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
46
    /* Set sub priority */
47
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
48
    /* Enable interrupt */
49
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
50
    /* Add to NVIC */
51
    NVIC_Init(&NVIC_InitStruct);
52
}
53
54
void Configure_PB12(void) {
55
    /* Set variables used */
56
    GPIO_InitTypeDef GPIO_InitStruct;
57
    EXTI_InitTypeDef EXTI_InitStruct;
58
    NVIC_InitTypeDef NVIC_InitStruct;
59
60
    /* Enable clock for GPIOB */
61
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
62
    /* Enable clock for SYSCFG */
63
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
64
65
    /* Set pin as input */
66
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
67
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
68
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
69
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
70
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
71
    GPIO_Init(GPIOB, &GPIO_InitStruct);
72
73
    /* Tell system that you will use PB12 for EXTI_Line12 */
74
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);
75
76
    /* PB12 is connected to EXTI_Line12 */
77
    EXTI_InitStruct.EXTI_Line = EXTI_Line12;
78
    /* Enable interrupt */
79
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
80
    /* Interrupt mode */
81
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
82
    /* Triggers on rising and falling edge */
83
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
84
    /* Add to EXTI */
85
    EXTI_Init(&EXTI_InitStruct);
86
87
    /* Add IRQ vector to NVIC */
88
    /* PB12 is connected to EXTI_Line12, which has EXTI15_10_IRQn vector */
89
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
90
    /* Set priority */
91
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
92
    /* Set sub priority */
93
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
94
    /* Enable interrupt */
95
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
96
    /* Add to NVIC */
97
    NVIC_Init(&NVIC_InitStruct);
98
}
99
100
void Configure_PB13(void) {
101
    /* Set variables used */
102
    GPIO_InitTypeDef GPIO_InitStruct;
103
    EXTI_InitTypeDef EXTI_InitStruct;
104
    NVIC_InitTypeDef NVIC_InitStruct;
105
106
    /* Enable clock for GPIOB */
107
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
108
    /* Enable clock for SYSCFG */
109
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
110
111
    /* Set pin as input */
112
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
113
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
114
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
115
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
116
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
117
    GPIO_Init(GPIOB, &GPIO_InitStruct);
118
119
    /* Tell system that you will use PB12 for EXTI_Line12 */
120
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource13);
121
122
    /* PB12 is connected to EXTI_Line12 */
123
    EXTI_InitStruct.EXTI_Line = EXTI_Line13;
124
    /* Enable interrupt */
125
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
126
    /* Interrupt mode */
127
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
128
    /* Triggers on rising and falling edge */
129
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
130
    /* Add to EXTI */
131
    EXTI_Init(&EXTI_InitStruct);
132
133
    /* Add IRQ vector to NVIC */
134
    /* PB12 is connected to EXTI_Line12, which has EXTI15_10_IRQn vector */
135
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
136
    /* Set priority */
137
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
138
    /* Set sub priority */
139
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x02;
140
    /* Enable interrupt */
141
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
142
    /* Add to NVIC */
143
    NVIC_Init(&NVIC_InitStruct);
144
}
145
146
147
/* Set interrupt handlers */
148
/* Handle PD0 interrupt */
149
void EXTI0_IRQHandler(void) {
150
    /* Make sure that interrupt flag is set */
151
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
152
        /* Do your stuff when PD0 is changed */
153
154
155
        /* Clear interrupt flag */
156
        EXTI_ClearITPendingBit(EXTI_Line0);
157
    }
158
}
159
160
/* Handle PB12 interrupt */
161
void EXTI15_10_IRQHandler(void) {
162
    /* Make sure that interrupt flag is set */
163
164
    if ((EXTI_GetITStatus(EXTI_Line12) != RESET) && (EXTI_GetFlagStatus(EXTI_Line12) != RESET)){
165
        /* Do your stuff when PB12 is changed */
166
        EXTI_ClearITPendingBit(EXTI_Line12);
167
    }
168
    if ((EXTI_GetITStatus(EXTI_Line13) != RESET) && (EXTI_GetFlagStatus(EXTI_Line13) != RESET)) {
169
        /* Do your stuff when PB12 is changed */
170
        EXTI_ClearITPendingBit(EXTI_Line13);
171
    }
172
}
173
174
int main(void) {
175
    /* System init */
176
    SystemInit();
177
    /* Configure PD0 as interrupt */
178
    Configure_PD0();
179
    /* Configure PB12 and PB13 as interrupt */
180
    Configure_PB12();
181
    Configure_PB13();
182
183
184
    while (1) {
185
186
    }
187
}

von Giovanni (Gast)


Lesenswert?

ich würde die
1
&& (EXTI_GetFlagStatus(EXTI_Line12) != RESET)
 weglassen.

Vor
1
EXTI_ClearITPendingBit(EXTI_Line12);
 kannste die Pins abfragen

von Robin H. (robin_h319)


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?

von STM Apprentice (Gast)


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.

von Markus (Gast)


Angehängte Dateien:

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.

von Robin H. (robin_h319)


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:
1
void EXTI15_10_IRQHandler(void) {
2
    /* Make sure that interrupt flag is set */
3
  if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == Bit_SET){
4
    if ((EXTI_GetITStatus(EXTI_Line12) != RESET)){
5
      /* Do your stuff when PB12 is changed */
6
      EXTI_ClearITPendingBit(EXTI_Line12);
7
    }
8
  }
9
10
  if ((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13) == Bit_SET)){
11
    if ((EXTI_GetITStatus(EXTI_Line13) != RESET)){
12
      /* Do your stuff when PB12 is changed */
13
      EXTI_ClearITPendingBit(EXTI_Line13);
14
    }
15
  }
16
}

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!

von STM Apprentice (Gast)


Lesenswert?

Robin H. schrieb:
> Die werde ich mir auch mal anschauen!

Vorsicht, das ist Arduino!

Ja ja, die C&P Fehlerteufelchen

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

von Felix F. (wiesel8)


Lesenswert?

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

mfg

von STM Apprentice (Gast)


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:

von Felix F. (wiesel8)


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:

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

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

1
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == Bit_SET){
2
    if ((EXTI_GetITStatus(EXTI_Line12) != RESET)){
3
      /* Do your stuff when PB12 is changed */
4
      EXTI_ClearITPendingBit(EXTI_Line12);
5
    }
6
  }
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.