STM32 Interrupt

#3973076
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
#3973095
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.
Moderator Persönliche Seite #3973102
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.
#3976943
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"
#3977068
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;
#3977125
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)"
Gast #3977131
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)
#3977138
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)
#3977165
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"

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren