Forum: Mikrocontroller und Digitale Elektronik STM32F030xx > EXTI Interrupt


von Jan H. (janiiix3)


Lesenswert?

Guten Abend,

ich ein Evo. Board von STM (STM32F030xx DISCO).
Dort ist Taster an PA0 angeschlossen. Wird dieser Taster gedrückt, liegt 
an PA0 3V an.

Nun versuche ich diesen Pin mit hilfe des dazugehörigen Interrupts 
auszuwerten. Leider mache ich wahrscheinlich etwas falsch.

Komme hier leider nicht weiter.
Habe ich was vergessen im Code?.

Meine Debug Led lässt sich ein und ausschalten. Damit überprüfe ich die 
ISR.
1
/**
2
 ******************************************************************************
3
 * @file           : main.c
4
 * @author         : Auto-generated by STM32CubeIDE
5
 * @brief          : Main program body
6
 ******************************************************************************
7
 * @attention
8
 *
9
 * Copyright (c) 2021 STMicroelectronics.
10
 * All rights reserved.
11
 *
12
 * This software is licensed under terms that can be found in the LICENSE file
13
 * in the root directory of this software component.
14
 * If no LICENSE file comes with this software, it is provided AS-IS.
15
 *
16
 ******************************************************************************
17
 */
18
19
#include <stdint.h>
20
#include "stm32f030x8.h"
21
#include "mcal.h"
22
23
24
25
int main(void)
26
{
27
  __disable_irq();
28
29
  GPIOInitPort( GPIOA ); // Taster: PA0
30
  GPIOInitPort( GPIOC ); // LED: PC8
31
32
  RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // SYSCLK aktivieren
33
34
  GPIOSelectPinMode( GPIOA, PIN_0, INPUT );
35
  GPIOSelectPinMode( GPIOC, PIN_8, OUTPUT );
36
37
  GPIOA->OTYPER &= ~( GPIO_OTYPER_OT_0 ); // Output Type "Push/Pull"
38
  GPIOA->PUPDR &= ~( GPIO_PUPDR_PUPDR0 ); // Keine PullUp´s oder PullDown´s
39
40
  GPIOC->OTYPER &= ~( GPIO_OTYPER_OT_8 );
41
  GPIOC->PUPDR &= ~( GPIO_PUPDR_PUPDR8 );
42
43
  SYSCFG->EXTICR[0] &= ~( 0x000F ); // EXTI0 an (PORTxx [0..3])
44
  EXTI->IMR |= EXTI_IMR_IM0; // PA0: Enable IRQ
45
  EXTI->FTSR |= EXTI_FTSR_TR0; // PA0: Steigende Flanke
46
  NVIC_EnableIRQ(EXTI0_1_IRQn); // EXTI0: Aktivieren
47
48
  __enable_irq();
49
50
    /* Loop forever */
51
  for(;;)
52
  {
53
54
  }
55
}
56
57
void EXTI0_IRQHandler(void)
58
{
59
  GPIOTogglePin( GPIOC, PIN_8 );
60
  EXTI->PR |= EXTI_PR_PR0; // Lösche Pending Flag
61
}

von Jim M. (turboj)


Lesenswert?

Tausche mal die beiden Instuktionen in der ISR gegeneinander aus.
Du löschst das Interrupt Flag zu spät - Cortex-M hat Schreib Puffer.

Ansonsten sieht man das kurze Aufblitzen der LED vielleicht im Oszi.

von Jan H. (janiiix3)


Lesenswert?

Ich habe auch schon versucht die LED ein zu schlten.

von Jan H. (janiiix3)


Lesenswert?

Jim M. schrieb:
> Tausche mal die beiden Instuktionen in der ISR gegeneinander aus.
> Du löschst das Interrupt Flag zu spät - Cortex-M hat Schreib Puffer.
>
> Ansonsten sieht man das kurze Aufblitzen der LED vielleicht im Oszi.

Also egal wie ich es drehe das funktioniert nicht.

von pegel (Gast)


Lesenswert?

Gehört nicht vor NVIC_EnableIRQ noch ein NVIC_SetPriority ?

von Jan H. (janiiix3)


Lesenswert?

Ich arbeite gerade mit dem Buch von "Ralf Jesse" ->

https://www.amazon.de/gp/product/3747501915/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

Dort wird zwar der CortexM4 Kern beschrieben aber ich baue das für 
meinen CortexM0 um.

Es ist nichts von der Interrupt Priorität in dem aktuellen Kapitel 
beschrieben.

von Stefan F. (Gast)


Lesenswert?

pegel schrieb:
> Gehört nicht vor NVIC_EnableIRQ noch ein NVIC_SetPriority ?

Es muss auch ohne gehen. Bei meinem bescheidenen Basteleien habe immer 
nur die Standard Prio benutzt, die ab Reset gilt.

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Leider mache ich wahrscheinlich etwas falsch.
> Habe ich was vergessen im Code?

In meiner Datei startup_stm32f030r8tx.s ist der Interrupthandler 
anders benannt, nämlich EXTI0_1_IRQHandler. Der Name im Quelltext muss 
exakt damit überein stimmen.

Der Hinweis von Jim ist auch wichtig:
Beitrag "Re: STM32F030xx > EXTI Interrupt"

Ich habe mir ein paar Notizen zum Interrupt-System gemacht, die dir 
vielleicht auch bei weiteren Fragen helfen: 
http://stefanfrings.de/stm32/stm32l0.html#nvic

Schau dir da mal den Absatz ab "In diesem Zusammenhang ist das Register 
EXTI->PR wichtig...." an. Sowie im Beispiel-Quelltext der Kommentar "It 
is important that this is not the last command in the ISR".

Die Seite ist für die L0 Serie, die F0 ist ähnlich denke ich.

von Alex -. (alex796)


Lesenswert?

Frohes Neues,
Jan H. schrieb:
> Leider mache ich wahrscheinlich etwas falsch.
>
> Komme hier leider nicht weiter.
> Habe ich was vergessen im Code?.
>
> Meine Debug Led lässt sich ein und ausschalten. Damit überprüfe ich die
> ISR.

Dein Text ist ein wenig Wirrwarr für mich. Deine Debug LED verrät dir, 
dass du in die ISR kommst, richtig? Und was genau funktioniert nun nicht 
bzw. lässt sich nicht auswerten?

Ich bezweifle, dass ich das Problem verstanden habe.

Außerdem habe ich gerade nicht das RefMan, Datenblatt etc nicht zur 
Hand, daher meine Frage an dich:
Wo definierst du deine ganzen Funktionen, z.B.
1
  GPIOInitPort( GPIOA ); // Taster: PA0
2
  GPIOInitPort( GPIOC ); // LED: PC8

???

Gruß,

: Bearbeitet durch User
von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>> Leider mache ich wahrscheinlich etwas falsch.
>> Habe ich was vergessen im Code?
>
> In meiner Datei startup_stm32f030r8tx.s ist der Interrupthandler
> anders benannt, nämlich EXTI0_1_IRQHandler. Der Name im Quelltext muss
> exakt damit überein stimmen.

Moin Stefan,

du hast Recht. Bei dem CortexM0 scheint es tatsächlich dieser Handler zu 
sein. Jetzt funktioniert es so wie es soll.
Meine Frage jetzt.. Ich bin sehr neu was STM angeht. Woher weiß ich 
genau welche Routine ich jetzt für diesen Interrupt nehmen muss?. Diese 
Funktionen stehen ja nicht so im Datenblatt, wie kann ich darauf 
schließen bzw. diese am besten finden?!.

Danke für deine Hilfe.

von Jan H. (janiiix3)


Lesenswert?

Alex -. schrieb:
> Frohes Neues,
> Jan H. schrieb:

> Dein Text ist ein wenig Wirrwarr für mich. Deine Debug LED verrät dir,
> dass du in die ISR kommst, richtig? Und was genau funktioniert nun nicht
> bzw. lässt sich nicht auswerten?
>
Nein ich bin nicht in die ISR gekommen. Ich habe den falschen Handler 
verwendet. Anscheind ist mein Programm dadurch abgestürzt. Die Antwort 
von Stefan F. war sehr hilfreich.

Ich habe mich mal wieder zu kompliziert ausgedrückt.

> Wo definierst du deine ganzen Funktionen, z.B.
>
>
1
>   GPIOInitPort( GPIOA ); // Taster: PA0
2
>   GPIOInitPort( GPIOC ); // LED: PC8
3
>

Diese Funktionen sind ausgelagert und getestet.

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Woher weiß ich genau welche Routine ich jetzt für diesen
> Interrupt nehmen muss? ... Diese Funktionen stehen ja nicht
> so im Datenblatt, wie kann ich darauf schließen bzw. diese
> am besten finden?!.

Das habe ich dir bereits geschrieben:

Stefan ⛄ F. schrieb:
> In meiner Datei startup_stm32f030r8tx.s ist der Interrupthandler
> anders benannt, nämlich EXTI0_1_IRQHandler. Der Name im Quelltext muss
> exakt damit überein stimmen.

Die Startup Datei (in Assembler) legt die Funktions-Namen fest. Wenn du 
sie ändern willst, dann dort (an zwei Stellen!).

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Die Startup Datei (in Assembler) legt die Funktions-Namen fest. Wenn du
> sie ändern willst, dann dort (an zwei Stellen!).

Okay. Werde ich mir abspeichern. Vielen Dank.

von hard werker (Gast)


Angehängte Dateien:

Lesenswert?

Jan H. schrieb:
> Komme hier leider nicht weiter.
> Habe ich was vergessen im Code?.

Ich verstehe nicht wie man sich es als Anfänger so umständlich
machen kann. Dabei ist es eigentlich ganz einfach sich für
den ersten Start mal alles von CubeMX zusammenstellen zu lassen.

Ich habe mal schnell alles zusammengeklickt und für (mein)
Atollic Studio generieren lassen. Dabei habe ich noch keine
einzige Zeile Code geschrieben und komme sofort zu einem
"lauffähigen" Projekt. Siehe Anhang. Dieses Projekt lässt
sich (alleine durch Verwendung der Datei *.ioc) mit CubeMX
auf andere Entwicklungsplattformen generieren oder mit Hilfe
der eigenen Platform aus dem Atollic Studio Format importieren.

Im Übrigen sind die diskutierten Interrupt Handler schön brav
und sauber in <startup_stm32f030x8.s> gelistet so wie es sich
gehört und an ihre richtige Stelle gesetzt. Da braucht es nicht
mal ein Datenblatt des Controllers dazu.

von Jan H. (janiiix3)


Lesenswert?

hard werker schrieb:
> Jan H. schrieb:
>> Komme hier leider nicht weiter.
>> Habe ich was vergessen im Code?.
>
> Ich verstehe nicht wie man sich es als Anfänger so umständlich
> machen kann. Dabei ist es eigentlich ganz einfach sich für
> den ersten Start mal alles von CubeMX zusammenstellen zu lassen.

Ich kommentiere das mal jetzt nicht..

von Stefan F. (Gast)


Lesenswert?

hard werker schrieb:
> Ich verstehe nicht wie man sich es als Anfänger so umständlich
> machen kann. Dabei ist es eigentlich ganz einfach sich für
> den ersten Start mal alles von CubeMX zusammenstellen zu lassen.

Das problem ist, dass man als Anfänger völlig überfordert ist, wenn der 
generierte Code bzw. die HAL mal nicht wie erwartet funktionieren oder 
gar Fehlerhaft sind. Da ist dann nämlich der Moment, wo man die 
Grundlagen dahinter kennen muss.

Ist wie beim Auto-Fahren. Ich konfiguriere mein Auto und lasse es dann 
generieren. Aber wenn es mal nicht fährt, dann kann ich mir nicht selber 
helfen.

Beim Fahrrad sieht es ganz anders aus, da kenne ich fast jede Schraube.

von hard werker (Gast)


Lesenswert?

Jan H. schrieb:
> Meine Frage jetzt.. Ich bin sehr neu was STM angeht. Woher weiß ich
> genau welche Routine ich jetzt für diesen Interrupt nehmen muss?.

Jan H. schrieb:
> Ich kommentiere das mal jetzt nicht..

Warum? Weil du sprachlos bist?

von hard werker (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Das problem ist, dass man als Anfänger völlig überfordert ist, wenn der
> generierte Code bzw. die HAL mal nicht wie erwartet funktionieren oder
> gar Fehlerhaft sind.

Das ist eine billige Ausrede. Mag das ganze CubeMX Zeugs nicht
ganz fehlerfrei sein, so funktioniert es doch in 99% der Fälle
einwandfrei. Und für den Startup Code (Anwendungs-leeres Projekt-
Gerüst) ist der Prozentsatz sicher noch deutlich höher. Speziell
für den so "einfachen" F0.

von hard werker (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Das problem ist, dass man als Anfänger völlig überfordert ist, wenn der
> generierte Code bzw. die HAL mal nicht wie erwartet funktionieren oder
> gar Fehlerhaft sind.

Übrigens sind in meinem Beispiel-Projekt gar keine HAL Aufrufe
enthalten. Zwar gibt es einen Ordner STM32F0xx_HAL_Driver aber
darin sind nur die Low-Level Sourcen (statt der HAL Sourcen)
enthalten. Also "kein bisschen" HAL, für deine Meckerei bezüglich
HAL. Die Sourcen sind so wie früher unter Verwendung der SPL,
nur haben sie geringfügig andere Namen. Boooaaaaaah ......

von Erwin (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Das problem ist, dass man als Anfänger völlig überfordert ist, wenn der
> generierte Code bzw. die HAL mal nicht wie erwartet funktionieren oder
> gar Fehlerhaft sind. Da ist dann nämlich der Moment, wo man die
> Grundlagen dahinter kennen muss.

Dem kann ich nur zustimmen. Ich selber setzen die HAL gerne für Projekte 
ein, auch für sehr umfangreiche. Hierbei bietet sie schon den Vorteil 
der Portabilität eigener Libs z.B. für Hardware oder für Protokolle. 
Aber ich habe es auch schon so oft gesehen, dass die HAL völlig 
missverstanden wurde, sodass ich auch davon überzeugt bin, dass sie am 
Anfang eher hinderlich ist.

Kurzum: Besser ohne HAL anfangen, sie Schritt für Schritt kennenlernen 
und dann überlegen, ob und wie man damit Glücklich wird.

von hard werker (Gast)


Lesenswert?

Erwin schrieb:
> Aber ich habe es auch schon so oft gesehen, dass die HAL völlig
> missverstanden wurde, sodass ich auch davon überzeugt bin, dass sie am
> Anfang eher hinderlich ist.

Daher habe ich auch die Code-Generierung in meinem Beispiel mit
Low-Level-Treibern angestossen, nicht mit den HAL-Calls.

Erwin schrieb:
> Kurzum: Besser ohne HAL anfangen, sie Schritt für Schritt kennenlernen
> und dann überlegen, ob und wie man damit Glücklich wird.

Es herrscht scheinbar immer noch weit verbreitet die Meinung vor dass

CubeMX == HAL

was durch die Arbeitsweise für die Default-Einstellungen von STM
auch offensichtlich vorangetrieben bzw. unterstützt wird. Dennoch
kann man sich das Leben mit dem Codegenerator CubeMX einfach
machen und trotzdem mit normalen Low-Level-Calls arbeiten wie man
es früher mit der SPL gewohnt war.

von Erwin (Gast)


Lesenswert?

hard werker schrieb:
> Dennoch
> kann man sich das Leben mit dem Codegenerator CubeMX einfach
> machen und trotzdem mit normalen Low-Level-Calls arbeiten wie man
> es früher mit der SPL gewohnt war.

Klar, nur dass dann keinerlei Portabilität mehr gewährleistet ist und 
man eigentlich den ganzen Vorteil den eine oder "die HAL" liefert wieder 
losgeworden ist. Das schöne ist doch, mit wenig bis kaum Aufwand gesamte 
Projekte von einem F4 auf einen F3 zu bringen oder Teile aus einem F4 
Projekt sehr einfach in eines zu bringen, welches auf einem F1 läuft.

von hard werker (Gast)


Lesenswert?

Erwin schrieb:
> Klar, nur dass dann keinerlei Portabilität mehr gewährleistet ist

Ja, genau ..... genau das ist für den TO gerade wahnsinnig
wichtig wo er sich noch nicht mal klar ist wie und wo die
Interrupt-Tabelle angelegt ist. Was der vorangegange Verlauf
des Threads deutlich gemacht hat.

Immer schön in korinthenkackerhafter Weise das Thema vom
hundertsten ins tausendste ziehen. Weiter so!

von Erwin (Gast)


Lesenswert?

hard werker schrieb:
> Immer schön in korinthenkackerhafter Weise das Thema vom
> hundertsten ins tausendste ziehen. Weiter so!

Klar, daher empfehle ich ja auch OHNE HAL anzufangen WEIL es nicht 
notwendig ist oder habe ich mich da so missverständlich ausgedrückt?

von Johannes S. (Gast)


Lesenswert?

das LL Gedöns ist nur unleserlich und verpackt die 
Registerprogrammierung in eigene Namen. Die ganze Fehlerbehandlung wie 
im HAL muss man selber machen, und dann hat man auch nichts gewonnen.
Ich kenne Profis, und die kochen auch mit Wasser und CubeMX. Das 
Werkzeug hat sich sehr gut entwickelt und der generierte Code 
funktioniert, bei uns auch in vielen  24*7 Anwendungen. Die Kollegen 
haben gar keine Zeit und Lust sich mit der Registerfummelei abzugeben. 
Es ist eher professionell die Hardware richtig zu nutzen, z.B. ADC per 
FSMC oder DCMI anzubinden und per DMA auszulesen ohne die CPU zu 
belasten. Spätestens da macht die Registerfummelei keinen Spaß mehr. 
Schau mal was ein STM32H7 alles für Devices hat, da machst du garantiert 
mehr Fehler die zu Fuß zu benutzen als das du Fehler im HAL Code 
findest. Ja, der Stefan hat Anno dunnemals mal was gefunden was 
möglicherweise falsch war, aber der HAL Code wird immer noch gepflegt 
und auch Chip Revisionen werden da behandelt. Auch da kann man nämlich 
viel Zeit mit Fehlersuche verbringen weil einiges in Erratas beachtet 
werden muss.
Zum Einsteigen und µC kennenlernen kann man natürlich erstmal solche 
Übungen machen, aber CubeMX oder HAL als unprofessionell oder schlecht 
abzutun ist einfach nur überheblich.
Und normalerweise löst hier Taster per Interrupt lesen schon Shitstorms 
aus...

von hard werker (Gast)


Lesenswert?

Erwin schrieb:
> daher empfehle ich ja auch OHNE HAL anzufangen

Und warum empfiehlst du das?
Hat hier jemand empfohlen mit der Verwendung von HAL anzufangen?

von Jan H. (janiiix3)


Lesenswert?

Diese ganze Aufregung für eine "Anfängerfrage"
Leute...

von Stefan F. (Gast)


Lesenswert?

Johannes S. schrieb:
> Ja, der Stefan hat Anno dunnemals mal was gefunden was
> möglicherweise falsch war, aber der HAL Code wird immer noch gepflegt
> und auch Chip Revisionen werden da behandelt

Das eigentliche Problem war ja nicht der Bug, sondern meine Unfähigkeit, 
ihn zu beheben. Dafür braucht man Erfahrung auf den unteren Layer, den 
einen die HAL nicht so gut beibringen kann. So war das gemeint.

von Johannes S. (Gast)


Lesenswert?

diese WEAK Handling hat mich auch schon einige Stunden Fehlersuche 
gekostet. Noch fieser wird es bei C++, dann muss man auch auf das Name 
Mangling acht geben.

von Johannes S. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> So war das gemeint.

dafür lassen sich die Cortex-M schöner und billig debuggen. Das Problem 
ist einfach die grössere Komplexität, schon bei einem M0.

von Stefan F. (Gast)


Lesenswert?

Johannes S. schrieb:
> dafür lassen sich die Cortex-M schöner und billig debuggen. Das Problem
> ist einfach die grössere Komplexität, schon bei einem M0.

Ich sehe jetzt irgendwie nicht den Zusammenhang zur verwendeten 
Bibliothek.

von Lutz (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Das eigentliche Problem war ja nicht der Bug, sondern meine Unfähigkeit,
> ihn zu beheben. Dafür braucht man Erfahrung auf den unteren Layer, den
> einen die HAL nicht so gut beibringen kann. So war das gemeint.

Na ja, man kann in Eclipse (eigentlich) ja schön durch die Deklarationen 
und Definitionen hoppen, um nach x Rekursionen dann auf der 
Registerebene zu landen. Oder der Mouse-Tooltip reicht schon. Ab da kann 
man dann auch das Manual nutzen. Ist aber oft ein weiter Weg und nach 
3-4 Sprüngen weiß man schon fast gar nicht mehr, was man eigentlich 
genau wollte.

Und leider funktioniert das bei vielen Sachen dann auch nicht; die 
Quelle wird nicht gefunden. Manchmal hilft ein "Index Rebuild", oft aber 
auch nicht. Wobei das wohl eher an Eclipse liegt.
Und ein Wechsel des Chips ist ja auch kein Selbstgänger. Da muß man wohl 
schon selber handanlegen. Selbst wenn man z.B. aus einem STM32F103C8xx 
einen STM32F103CBxx machen will, der sich einzig in der Größe des Flash 
unterscheidet.

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.