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
intmain(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?
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 */
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.
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.
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.
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
voiddelayMs(intn);
5
6
intmain(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
voiddelayMs(intn){
20
inti;
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.
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.
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 ;)
@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).
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
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.
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.
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.
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.
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.