Forum: Mikrocontroller und Digitale Elektronik STM32 Interrupt


von Michael M. (mabuo)


Lesenswert?

Hallo zusammen.
Das ist mein erster Beitrag in diesem Forum.

Ich habe eine Frage zum Thema Interrupts bei meinem STM32 Board.
Und zwar will ich folgendes programmieren:
Im Hauptprogramm stelle ich einen Wert über den ADC ein.(funktioniert)
Wird der "User"-Button gedrückt soll in den Interrupt-Handler gesprungen 
werden. Dort wird auf ein bestimmtes Ereignis am GPIO gewartet, der dann 
einen Timer auslöst.

Mein Problem ist ich weiß nicht so recht wie ich über den "User"-Button 
einen Interrupt auslösen kann. Funktioniert das überhaupt? Muss ich auf 
etwas besonderes achten?
Bin über jede Hilfe dankbar.

Ich nutze den STM32F103ZE

Viele Grüße

von Michael M. (eos400dman)


Lesenswert?

Hallo,

ich würde dir raten den Taster nicht per Interrupt abzufragen. Das macht 
bei prellenden Tastern nur Problemen. Frag lieber mit einem Timer alle 
10ms, oder so, den Taster ab und schau ob der Wert sich geändert hat. 
Dann kannst du entsprechende darauf reagieren.

Viele Grüße Michael

von (prx) A. K. (prx)


Lesenswert?

Mario Burner schrieb:
> Wird der "User"-Button gedrückt soll in den Interrupt-Handler gesprungen
> werden. Dort wird auf ein bestimmtes Ereignis am GPIO gewartet, der dann
> einen Timer auslöst.

Per Taster einen Interrupt auslösen setzt einen entprellten Taster 
voraus. Taster zyklisch per Timer abfragen erspart das.

In einem Interrupt-Handler auf ein Ereignis warten ist selten eine gute 
Idee. Besser: Ein Ereignis löst einen Interrupt aus und ruft damit einen 
Handler auf. Wenn das nur auf Tastendruck erfolgen soll, dann kann als 
Folge der Tasterabfrage der Interrupt vom Ereignis einschaltet werden.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Michael Mayer schrieb:
> ich würde dir raten den Taster nicht per Interrupt abzufragen. Das macht
> bei prellenden Tastern nur Problemen.

Erstens das, zweitens will er dann im ausgelösten Interrupt noch auf ein 
weiteres "Ereignis warten", wie er schreibt. Warten in einem 
Interrupt-Handler ist ein No-Go.

Für die vom TO vorgestellte Aufgabe braucht man keinen Interrupt, 
sondern höchstens eine kleine Statemachine:
1
volatile int button_pressed;        // volatile, global, wird von Timer-IRQ-Handler gesetzt, welcher Taste abfragt
2
volatile int gpio_event;            // dito, hier wird GPIO abgefragt
3
4
int main ()
5
{
6
    int state = WAIT_FOR_BUTTON;
7
8
    init_something();
9
10
    button_pressed = 0;
11
    gpio_event = 0;
12
13
    while (1)
14
    {
15
        if (state == WAIT_FOR_BUTTON)
16
        {
17
            if (button_pressed)
18
            {
19
                button_pressed = 0;
20
                gpio_event = 0;
21
                state = WAIT_FOR_EVENT;
22
            }
23
        }
24
        else if (state == WAIT_FOR_EVENT)
25
        {
26
            if (gpio_event)
27
            {
28
                gpio_event = 0;
29
                state = WAIT_FOR_BUTTON;
30
                read_adc();              // ADC einlesen
31
            }
32
        }
33
34
    }
35
}

Tastatur-Entprellung habe ich jetzt mal aussen vor gelassen, das ist ja 
im Artikel Entprellung bestens beschrieben. Der obige Code ist 
lediglich ein Gerüst.

von Michael M. (mabuo)


Lesenswert?

Danke für die schnellen Antworten.
Habe mein Programm ähnlich nach dem Gerüst aufgebaut und das 
funktioniert soweit.

Nun will ich noch folgendes machen.
Wenn das GPIO-Event eintritt soll nach einer bestimmten Zeit 
(eingestellt durch ADC) ein Impuls ausgegeben werden.

Lösen will ich das mit einem Timer Interrupt, der initialisiert und 
aktiviert wird wenn das Event Eintritt.
Im IRQHandler wird dann der Impuls gegeben und der Timer wieder 
deaktiviert.

1.Frage: Funktioniert das wenn ich den Timer erst im Programm 
initialisiere?
2.Frage:
Immer wenn ich meinen NVIC initialisieren will bekomme ich in folgender 
Zeite eine Fehlermeldung:

 NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;

Bei "TIM7_IRQn" sagt mir der compiler "use of undeclared identifier"

von Michael M. (mabuo)


Lesenswert?

In der Vector-tabelle gibt es keinen TIM7 also habe ich es mit TIM4 
versucht.
Gleiche Fehlermeldung. Weiß jemand woran das liegt?

void SetupTimer (void) {


  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);

  TIM_TimeBaseInitTypeDef timInitStruct;
  timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
  timInitStruct.TIM_Prescaler = 1000;
  timInitStruct.TIM_Period = timer_aktiv;
  TIM_TimeBaseInit(TIM4, &timInitStruct);
  TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);

  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x05;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x05;

  NVIC_Init(&NVIC_InitStructure);

}


Compiler:

Setup.c(240): error:  #268: declaration may not appear after executable 
statement in block
        TIM_TimeBaseInitTypeDef timInitStruct;
Setup.c(248): error:  #268: declaration may not appear after executable 
statement in block
        NVIC_InitTypeDef NVIC_InitStructure;
Setup.c(249): error:  #20: identifier "TIM7_IRQn" is undefined
        NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;

von holger (Gast)


Lesenswert?

>In der Vector-tabelle gibt es keinen TIM7 also habe ich es mit TIM4
>versucht.
>Gleiche Fehlermeldung. Weiß jemand woran das liegt?

Dann nimm versuchsweise mal TIM1.
Wenn der Compiler immer noch meckert fehlt
ein #include "stm32f10x.h".

von Michael M. (mabuo)


Lesenswert?

Hilf leider auch nicht.

von holger (Gast)


Lesenswert?

>Hilf leider auch nicht.

Verdammt, TIM1_IRQn gibt es ja gar nicht;)
Dann halt noch mal mit TIM2.

von Michael M. (mabuo)


Lesenswert?

Ok eine Fehlermeldung weg. Jetzt meckert er aber an was anderem:

NVIC_InitStructure.NVIC_IRQChannel = TIM2;

Fehler: incompatible pointer to integer conversion assigning to 'u8' 
(aka 'unsigned char') from 'TIM_TypeDef *'

und der Compiler gibt folgende Meldung:

C:\Keil_v5\ARM\Inc\ST\STM32F10x\stm32f10x.h(96): error:  #35: #error 
directive: "Please select first the target STM32F10x device used in your 
application (in stm32f10x.h file)"
   #error "Please select first the target STM32F10x device used in your 
application (in stm32f10x.h file)"

von holger (Gast)


Lesenswert?

>Ok eine Fehlermeldung weg. Jetzt meckert er aber an was anderem:
>
>NVIC_InitStructure.NVIC_IRQChannel = TIM2;

Das muss ja auch TIM2_IRQn lauten. Aber schön das das jetzt
die wahre Ursache für deine Probleme ausgräbt.

>C:\Keil_v5\ARM\Inc\ST\STM32F10x\stm32f10x.h(96): error:  #35: #error
>directive: "Please select first the target STM32F10x device used in your
>application (in stm32f10x.h file)"

Dir fehlt ein define für deinen STM32 in den Compiler Optionen.

Es muss irgendwas von denen hier sein:

#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined 
(STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) 
&& !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined 
(STM32F10X_CL)

von Patrick B. (p51d)


Lesenswert?

Das ist aber auch logisch:
TIM2 ist ein Pointer der dir normalerweise die Basisadresse des Timer2 
Moduls im Memory-Map entspricht.

Was du willst ist etwas komplett anderes:
1
NVIC_InitTypeDef NVIC_InitStructure;
2
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
5
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
sollte eigentlich gehen (hab mal rasch die Vektortabelle von keil 
angeschaut: http://www.keil.com/dd/docs/arm/st/stm32f10x/stm32f10x.h)

von Michael M. (mabuo)


Lesenswert?

Das ist mir neu...
Was macht so ein define und wo mus ich das einfügen?

von Michael M. (mabuo)


Lesenswert?

holger schrieb:
> Dir fehlt ein define für deinen STM32 in den Compiler Optionen.
>
> Es muss irgendwas von denen hier sein:
>
> #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined
> (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD)
> && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined
> (STM32F10X_CL)

Habe nachgeschaut sind alle defines vorhanden.

Patrick B. schrieb:
> Was du willst ist etwas komplett anderes:NVIC_InitTypeDef
> NVIC_InitStructure;
> NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
> NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
> NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
> NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

genau das hab ich ja schon eingegeben mit der Meldung bei TIM7_IRQn:

"use of undeclared identifier"

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.