Forum: Mikrocontroller und Digitale Elektronik STM32 Beispielcode zerstört F446RE ST-Link Verbindung


von T. S. (signalprocessingbeta)


Lesenswert?

Hi zusammen.
Erstmal möchte ich mich für den (vielleicht unlogischen) Threadtitel 
entschuldigen, ich bin ein Anfänger in Mikrocontrollern und wusste nicht 
wie ich das Problem hätte besser formulieren können.

Das Problem:
Ein Beispielquelltext aus dem Buch: "STM32 ARM Programming for Embedded 
Systems" führt zu einer Art Absturz meines Nucleo F446REs. (Nucleo 
F446RE ist ein Launchpad für einen STM32 ARM Cortex M4 Mikrocontroller)
Die anderen Beispielquelltexte führten nicht zu diesem Problem. Hier ist 
der Quelltext:
1
#include "stm32f4xx.h"
2
3
int main(void) {
4
  RCC->AHB1ENR |=  4;   /* enable GPIOC clock */
5
  RCC->AHB1ENR |=  1;   /* enable GPIOA clock */
6
  
7
  GPIOA->MODER &= ~0x00000C00;    /* clear pin mode */
8
9
  GPIOA->MODER |=  0x00000400;    /* set pin PA5 to output mode */
10
  
11
  GPIOA->MODER &= ~0x0C000000;    /* clear pin mode to input mode */
12
  
13
  while(1) {
14
    if (GPIOC->IDR & 0x2000)      /* if PC13 is high */
15
      GPIOA->BSRR = 0x00200000;    /* turn off green LED */
16
    else
17
      GPIOA->BSRR = 0x00000020;    /* turn on green LED */
18
  }
19
}

Der Quelltext soll dazu dienen, dass bei einem gedrückten Button eine 
LED leuchtet. Wenn man den Quelltext zum ersten mal draulädt, 
funktioniert das auch, nur leider kann man den Mikrocontroller danach 
nicht mehr ansprechen. Der Mikrocontroller wird danach in Keil -> 
Options for Target -> Debug -> ST-Link Debugger -> Settings mit Debug 
Adapter "ST-LINK/V2-1" und Port: "SW" auch nicht mehr erkannt "no target 
connected".
Ich bekomme den Mikrocontroller erst wieder ansprechbar wenn ich das 
Programm "STM32 ST-LINK Utility" öffne, unter Settings -> Mode -> 
Connect under Reset setze und danach auf Target -> Erase Chip klicke. 
Danach finde ich den Controller wieder in Keil und kann Programme drauf 
flashen und debuggen.

So viel zur Vorgeschichte, kann mir jemand sagen woran das liegt?

: Bearbeitet durch User
von Meggl (Gast)


Lesenswert?

Sind dir die Funktionen von BOOT0 und BOOT1 (meist Jumper) bekannt?

von Stefan F. (Gast)


Lesenswert?

Gemäß dem Datenblatt sind die Leitungen SWDIO und SWCLK alternative 
Funktionen von PA13 und PA14.

Nach einem Reset hat das Register gemäß dem Referenzhandbuch intial den 
Wert 0xA8000000, damit sind PA13, PA14 und PA15 im "alternate function 
mode".

Deswegen funktioniert die Schnittstelle nach einem Reset zunächst.

Dann kommt dein Programm:
1
GPIOA->MODER &= ~0x00000C00;    /* clear pin mode */ 
2
GPIOA->MODER &= ~0x0C000000;    /* clear pin mode to input mode */
3
[c/]
4
5
Mit diesen beiden Zeilen setzt du effektiv alle Bits auf Low, also alle Pin Modes auf 00 "input". PA13 und PA15 sind jetzt nicht mehr im alternativen Modus.
6
7
Die eine Zeile dazwischen:
8
[c]
9
GPIOA->MODER |=  0x00000400;    /* set pin PA5 to output mode */

Konfiguriert PA5 als Ausgang. Du hast also den ganzen Port A als Input 
konfiguriert, mit Aussnahme von PA5.

von T. S. (signalprocessingbeta)


Lesenswert?

Meggl schrieb:
> Sind dir die Funktionen von BOOT0 und BOOT1 (meist Jumper) bekannt?

Ehrlich gesagt nicht, ich arbeite das Buch chronologisch durch und bis 
jetzt wurden diese Funktionen nicht erwähnt.
Eine Googlesuche hat mich gerade aber auf diesen Thread gebracht: 
Beitrag "STM32 Boot0 / 1"
Dadurch lassen sich wohl verschiedene Bootmodi einstellen, wenn ich das 
richtig verstehe.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Fang bitte nicht mit soner Magicnumber Programmierung an, da blickt dann 
keiner mehr durch.

Es gilt:
#define YELLOW_LED (1 << 27)
YELLOW_LED sagt mehr als 1<<27 sagt mehr als 0x08000000 sagt mehr als 
134217728.

Du kannst ja mal gucken pb du dir ausversehen PA13 und/oder PA14 
umkonfigurierst, denn das sind die SWD Pins zum debuggen.

von Stefan F. (Gast)


Lesenswert?

Wenn du Boot0 auf High legst, aktivierst du den internen seriellen 
Bootloader. Als angenehmen Seiteneffekt lässt dieser auch die SWD 
Schnittstelle aktiv.

Eventuell verzettelst du dich weniger, wenn du bei Zugriffen auf 
Register die Makros benutzt, die ST freundlicherweise in die CMSIS-Core 
Library eingefügt hat.

Dieses Buch führt sie anhand eines STM32F1 ab Kapitel 9 vor: 
http://stefanfrings.de/mikrocontroller_buch2/Einblick%20in%20die%20moderne%20Elektronik.pdf

Dort gehe ich auch auf die Makros ein, die "Mw E" meint.

von T. S. (signalprocessingbeta)


Lesenswert?

Danke für die ausführliche Erklärung.
Das ist ein wenig harter Tobak für mich, falls ich das jetzt korrekt 
verstehe wurden die Direction Register für die GPIO-Pins quasi falsch 
gesetzt bzw. es wurde nicht berücksichtigt, dass die GPIO Pins für SWD 
nicht beide als Eingang gesetzt werden sollen (sondern Boot0 als Ausgang 
und in der alternate function).

Was mich jetzt nur wundert ist, dass das Problem bei dem anderen 
"blinky"-Quelltext nicht aufgetreten ist:
1
/* use delay loop, 1 sec on 1 sec off * default 16MHz clock* LD2connects to PA5*/
2
3
#include "stm32f4xx.h"
4
void delayMs(int n);
5
6
  int main(void) {
7
  RCC->AHB1ENR |=  1;   /* enable GPIOA clock */
8
  GPIOA->MODER &= ~0x00000C00;    /* clear pin mode */
9
  GPIOA->MODER |=  0x00000400;    /* set pin to output mode */
10
  while(1) {
11
    GPIOA->BSRR = 0x00000020;   /* turn on LED */
12
    delayMs(1000);
13
    GPIOA->BSRR = 0x00200000;   /* turn off LED */
14
    delayMs(1000);
15
    }
16
  }
17
18
  /* 16 MHz SYSCLK */
19
  void delayMs(int n) {
20
  int i;
21
  for (; n > 0; n--)
22
    for (i = 0; i < 3195; i++);
23
}

(EDIT)
In dieser Codezeile
1
 GPIOA->MODER &= ~0x00000C00;    /* clear pin mode */
 werden ja nur die Bits verändert, die mit einer Null verodert werden. 
Also bleiben alle gleich, bis auf [hex] ~0x00000C00 = [binary] 
~110000000000 = [binary] ~001111111111 = [gpio nr] 00 11 11 11 11 11 = 
PA05. (PA05 ist Input und dessen alternate function ist inaktiv und alle 
anderen GPIOs (bis hier oder generell) sind Outputs)?


Naja, du hast jedenfalls recht: Das Problem ist hier die Bitsetzung von 
Mikrocontrollern die ich erst noch verstehen und verinnerlichen muss.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Tobias S. schrieb:
> Das Problem ist hier die Bitsetzung von
> Mikrocontrollern die ich erst noch verstehen und verinnerlichen muss.

Normalerweise hat man sich ein Projekt vorgenommen. Da soll der µC in 
einer Schaltung in einem Gerät etwas bestimmtes tun - und folglich hat 
man zunächst die Verwendung der verschiedenen Pins sich zu überlegen.

Das Erste, was man also im Programmfluß der zu schreibenden Firmware tun 
müßte, ist die Funktionen der Port-Pins richtig aufzusetzen und den 
Takt/die Takte des Ganzen richtig aufzusetzen bzw. an die zu 
verwendenden µC-Teile anzulegen.

Wenn du so etwa vorgehst, dann wirst du dir eben NICHT versehentlich die 
Funktionen ausschalten, die du zu benutzen gedenkst.


Und was das Thema "Bitsetzung" bzw. Benennungen von Bits betrifft, so 
kann man das in allen Richtungen übertreiben.
Sowohl ein

GPIOA->MODER &= ~0x00000C00;    /* clear pin mode */

ist unübersichtlich (weil man aus dem Kopf nicht weiß, welches die 
beiden Bits an Stelle des "C" bewirken, als auch

#define YELLOW_LED (1 << 27)

ist genau so unübersichtlich, weil man nicht weiß, für welchen Port das 
denn gelten soll und ob das nun bei low oder high die Lampe leuchten 
läßt.

Aber so etwas wie dieses:
1
// Alternativfunktionen, kommt in GPIOx_AFRL/AFRH
2
#define AF0   0
3
#define AF1   1
4
#define AF2   2
5
#define AF3   3
6
#define AF4   4
ist übersichtlich, weil man beim Lesen schon an der Überschrift sieht, 
wofür das gedacht ist. Gilt aber nur unter der Voraussetzung, daß das in 
der selben Quelle steht wie seine Benutzung, so daß keine unnötigen 
Abhängigkeiten damit erzeugt werden.

Nochwas:
Nun ist gerade bei den STM32 das Aufsetzen der Portpins ein bissel 
unangenehm unübersichtlich, denn da muß man mit MODER, OTYPER, OSPEEDR, 
PUPDR eben für jedes Portbit durch selbige Register hopsen und an 
diversen Stellen etwas einrichten. Für sowas hatte ich mir eine kleine 
Funktion geschrieben, die das anhand einer im Flash abgelegten Liste 
erledigt, so daß man an dieser Stelle nicht gar zu leicht einen 
Schusselfehler machen kann. Sowas dir selber zu schreiben, würde ich dir 
anraten. Sowas ist dann recht platzsparend im Flash (jedenfalls weitaus 
sparsamer als das separate Zuweisen für jedes einzelne Portpin) und es 
ist auch eine gute Übung für den Anfang.

W.S.

von Stefan F. (Gast)


Lesenswert?

W.S. rät von magischen Zahlen ab. Das ist mal eine gute Neuigkeit.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Stefan ⛄ F. schrieb:
> W.S. rät von magischen Zahlen ab. Das ist mal eine gute Neuigkeit.

Du siehst das ein wenig falsch.
Eine 32Bit Hex Magic Number sieht er als falsch an, aber ein:
PORT |= 1<<27 liebt er immernoch und ist damit ganz der Alte 
Dummschwätzer wie wir ihn kennen.

W.S. schrieb:
> als auch
>
> #define YELLOW_LED (1 << 27)
>
> ist genau so unübersichtlich, weil man nicht weiß, für welchen Port das
> denn gelten soll

Das war auch nur ein Beispiel du Knalltüte ;)

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

@Tobias S:
Werden denn in dem Buch "STM32 ARM Programming for Embedded Systems" 
diese Magic Numbers so vorgestellt und zur Verwendung empfohlen?

Wenn ja, dann das 14 Tage Rückgaberecht in Anspruch nehmen oder zur 
thermischen Verwertung zuführen ;)

Dem stefanus seine Seite ist dann die bessere Wahl zur Einarbeitung in 
die STM32.

Zum Problem selber:

Hier hast du den funktionierenden Code gepostet:
Beitrag "Re: STM32 Beispielcode zerstört F446RE ST-Link Verbindung"

Aber die Zeile des defekts fehlt da ja noch:
1
GPIOA->MODER &= ~0x0C000000;    /* clear pin mode to input mode */
Hier löscht du den IO Modus von PA13 und schon ist dein SWD im Eimer.

Der BOOT0 Pin ist nur nur wichtig wenn du den STM32 aus dem Reset holst.
Dann muss der 0 sein.
Was du danach mit dem im programm machst ist egal.
Nur gilt das eben nicht für die SWD Pins (SWIO/SWCLK).

von T. S. (signalprocessingbeta)


Angehängte Dateien:

Lesenswert?

Mw E. schrieb:
> @Tobias S:
> Werden denn in dem Buch "STM32 ARM Programming for Embedded Systems"
> diese Magic Numbers so vorgestellt und zur Verwendung empfohlen?

Ja, der Code ist direkt aus dem Buch. Man kann sich den Quelltext aus 
dem Buch auch auf der Onlineseite ansehen: 
http://www.microdigitaled.com/ARM/STM_ARM/Code/STM_codes.htm
(Program 2-3 ist z.B. das fehlerhafte aus dem Thread hier)

Mw E. schrieb:
> Wenn ja, dann das 14 Tage Rückgaberecht in Anspruch nehmen oder zur
> thermischen Verwertung zuführen ;)

Nur leider habe ich jetzt schon einiges in dieses Buch-"Paket" 
investiert :)
In dem angehängten Foto sieht man ein sogenanntes "Trainer-Board", dass 
ich mir aus den USA habe liefern lassen und zu dem es einige 
Code-Beispiele für den F446RE eben von den gleichen Autoren wie von dem 
Buch hier gibt. Falls es jemanden interessiert, hier wird es näher 
beschrieben: http://www.trainer4edu.com/edubase_v2/f446.html

Aber leider habe ich nicht damit gerechnet dass es in dem Buch teilweise 
auch fehlerhaften Code gibt, dass ist natürlich nicht optimal. Ich werde 
jetzt aber trotzdem mal damit arbeiten, dass Buch von Stefan habe ich 
aber schon mal als pdf in meinem STM32 Ordner hinterlegt und auch schon 
etwas darin gestöbert.

W.S. schrieb:
> Normalerweise hat man sich ein Projekt vorgenommen. Da soll der µC in
> einer Schaltung in einem Gerät etwas bestimmtes tun - und folglich hat
> man zunächst die Verwendung der verschiedenen Pins sich zu überlegen.
>
> Das Erste, was man also im Programmfluß der zu schreibenden Firmware tun
> müßte, ist die Funktionen der Port-Pins richtig aufzusetzen und den
> Takt/die Takte des Ganzen richtig aufzusetzen bzw. an die zu
> verwendenden µC-Teile anzulegen.
>
> Wenn du so etwa vorgehst, dann wirst du dir eben NICHT versehentlich die
> Funktionen ausschalten, die du zu benutzen gedenkst.

Genau deswegen habe ich mir dieses Buch und das Trainer-Board besorgt, 
einfach um viele Dinge aus der "modernen" (STM32) 
Mikrocontrollerprogrammierung ohne echte Anwendung vorbereitend zu 
lernen bzw. praktisch zu erproben. Ich bin Masterstudent aber leider 
kein Elektronikbastler, habe ein Praktikum in 
Mikrocontrollerprogrammierung im Bachelorstudium gehabt und in meiner 
Bachelorarbeit ein Launchpad programmiert, beides habe ich mit sehr 
guten Noten abgeschlossen. Aber leider habe ich noch nie ein PCB 
erstellt. Daher möchte ich mich jetzt privat in den Cortex M4 
einarbeiten, mit dem ja auch DSP-Aufgaben erledigt werden können, um 
dann in meiner Masterarbeit etwas entsprechendes in Angriff zu nehmen 
und auch mal richtig eine Mikrocontrollerplatine zu designen und nicht 
nur fertige Module zusammenzustecken.

Ich weiß dass ich jetzt mit meiner Entblößung einiges an Angriffsfläche 
geboten habe und hoffe dass nicht so viele User aus dem Ausbildungsforum 
nun hier aufschlagen werden :D

von T. S. (signalprocessingbeta)


Lesenswert?

Mw E. schrieb:
> Zum Problem selber:
>
> Hier hast du den funktionierenden Code gepostet:
> Beitrag "Re: STM32 Beispielcode zerstört F446RE ST-Link Verbindung"
>
> Aber die Zeile des defekts fehlt da ja noch:GPIOA->MODER &= ~0x0C000000;
> /* clear pin mode to input mode */
> Hier löscht du den IO Modus von PA13 und schon ist dein SWD im Eimer.

Um noch mal zum Problem zurück zu kommen:
Es hat sich einfach nur um einen Tippfehler gehandelt. Habe GPIOA->MODER 
&= ~0x0C000000; abgetippt anstatt GPIOC->MODER &= ~0x0C000000; sehe ich 
gerade. Und daraus ist dann der Fehler entstanden den ihr mir erklärt 
habt. Der Schalter ist an PC13 angeschlossen und nicht an PA13. Naja, 
zumindest habe ich jetzt mal ST Link besser kennengelernt :)

Komischerweise hat das Programm trotzdem funktioniert.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Tobias S. schrieb:
> Ich bin Masterstudent aber leider
> kein Elektronikbastler,

Nun, es würde auf das Fach ankommen. Wer Chemie studiert oder 
Maschinenbau, wird wohl weniger mit Elektronik zu tun haben - und wer 
Jura studiert wohl gar nicht.

Tobias S. schrieb:
> Ich weiß dass ich jetzt mit meiner Entblößung einiges an Angriffsfläche
> geboten habe

Ach was. Vernünftige Leute hier in diesem Forum sind um Hilfe für andere 
bemüht - und nur die ewigen Querulanten versuchen, irgendwo einen 
Ansatzpunkt zu finden, um an jedem herumzunörgeln und sich häßlich zu 
benehmen. Es ist deren negative Einstellung zu Anderen - und um solche 
Leute solltest du dich nicht scheren.

Tobias S. schrieb:
> Genau deswegen habe ich mir dieses Buch und das Trainer-Board besorgt,
> einfach um viele Dinge aus der "modernen" (STM32)
> Mikrocontrollerprogrammierung ohne echte Anwendung vorbereitend zu
> lernen bzw. praktisch zu erproben.

Bei solchen Sätzen (und solchen Gedanken dahinter) fühle ich mich sehr 
unwohl. So etwas läuft auf's "Exerzieren" hinaus - aber nicht auf's 
tatsächliche Verstehen. Und auch nicht auf's Anwenden-Können.

Jetzt kommt es drauf an, was für ein Studienfach du tatsächlich belegst 
und ob du erwartest, in deinem künftigen Arbeitsleben als 
Entwicklungs-Ingenieur tätig zu sein und dabei eben auch Mikrocontroller 
nebst anderen Dingen einzusetzen für die Geräte, die du entwickeln und 
konstruieren wirst. Bedenke mal, daß der reine Programmierer bei 
Mikrocontrollern fast immer ein bissel wie der Eunuch dasteht, eben weil 
er von der ganzen Elektronik und der ganzen Gerätetechnik rings um den 
µC nichts wirklich versteht.

Wenn dein Lebensweg eine andere Richtung einschlagen sollte, wären all 
die hier geführten Diskussionen nicht so wichtig, aber für Entwicklungen 
in der Industrie hingegen sehr wohl. Und da solltest du verstehen und 
nicht nur etwas exerziert haben. Es ist auch die mentale Hinwendung zum 
Thema wichtig. Ich will jetzt nicht gleich "Liebe" sagen, das könnte 
sexuell mißverstanden werden. Da du nun schon am Ende des Studiums 
angekommen bist und dich bisher noch nicht zu den Elektronikbastlern 
zählst, vermute ich mal, daß dir das Thema eher fernsteht. Das sind 
keine guten Voraussetzungen für ein Leben als Entwicklungsingenieur.

Vielleicht wäre es für dich im Moment wichtiger, mal ganz nüchtern eine 
Art Selbstanalyse zu machen als dir irgendwelche Dinge anhand eines 
Trainer-Boards einzupauken.

W.S.

von ... (Gast)


Lesenswert?

W.S. schrieb:
> Tobias S. schrieb:
>> Ich weiß dass ich jetzt mit meiner Entblößung einiges an Angriffsfläche
>> geboten habe
>
> Ach was. Vernünftige Leute hier in diesem Forum sind um Hilfe für andere
> bemüht - und nur die ewigen Querulanten versuchen, irgendwo einen
> Ansatzpunkt zu finden, um an jedem herumzunörgeln und sich häßlich zu
> benehmen. Es ist deren negative Einstellung zu Anderen - und um solche
> Leute solltest du dich nicht scheren.

Genau deswegen sollte Tobias dich (W.S.) ignorieren.
Du hast hier schon desöfteren Leute im Forum beschimpft, wenn diese 
nicht 1zu1 so programmieren wollen wie DU es ihnen vorzuschreiben 
versuchst!

Noch tut er halbwegs freundlich, aber das kann und wird sich schlagartig 
ändern.

von T. S. (signalprocessingbeta)


Lesenswert?

Und schon bekomme ich das Interesse am Thema abgesprochen und werde dazu 
aufgefordert meinen Lebensweg zu überdenken. Naja, danke für die Hilfe 
am Anfang des Themas aber ich ziehe es vor mich jetzt mit meinem 
Mikrocontroller zu beschäftigen anstatt mich hier demotivieren zu 
lassen.

von ... (Gast)


Lesenswert?

Tobias, wie ich geschrieben hab:
W.S. einfach ignorieren, dann wird dir hier geholfen!

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Die Persona W.S. wird langsam kritisch.
Jetzt werden die Foristen hier nicht mehr nur mit Magic Numbers, 
Lernbettys und Ansichten aus den 80ern genervt, sondern es werden Leute 
aktiv beschimpft und aus dem Forum vergrault.

@W.S.
Aber sonst sind bei dir noch alle Tassen im Schrank?

@Tobias
Also ich helf dir hier gerne noch und stefanus sicherlich auch.

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.