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
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
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.
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.
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"
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;
>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".
>Hilf leider auch nicht.
Verdammt, TIM1_IRQn gibt es ja gar nicht;)
Dann halt noch mal mit TIM2.
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)"
>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)
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)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.