STM32F030xx > EXTI Interrupt

#6927057
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
}
Gast #6927439
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.
#6927463
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ß,
#6927497
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.
#6927499
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.
Gast #6927517
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!).
Gast #6927561
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.
Angehängte Dateien:
#6927563
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..
Gast #6927570
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.
Gast #6927578
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.
Gast #6927586
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 ......
Gast #6927595
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.
Gast #6927604
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.
Gast #6927613
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.
Gast #6927621
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!
Gast #6927630
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...
Gast #6927647
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.
Gast #6928460
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.

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