Hi,
ich benutze Coocox IDE und ein STM32 Discoveryboard mit einem
STM2L152R8T6, an dem auf PB7 eine LED angeschlossen ist.
Ich habe einen Compiler heruntergeladen und die Treiber für STLink. Ich
kann (so schaut es zumindest aus) mit Coocox flashen und erasen.
Mein Programm wird auch übersetzt, aber an der LED tut sich nichts.
Ich habe die HSI enabled und dem Systemclock zugewiesen. Anschließend
aktiviere ich die Clocks für Port A-D.
Es sind bestimmt Anfängerfehler, aber für Hilfe wäre ich dankbar :).
Zuviele magische Zahlen in Deinem Code. Da gibt es sicher Header Defines
für.
Schau mal im Debugger nach ob Du die Werte in den GPIOB Registern auch
wieder auslesen kannst. Eventuell fehlt noch irgendwo ein Enable Bit.
Andre schrieb:> ich benutze Coocox IDE und ein STM32 Discoveryboard mit einem> STM2L152R8T6, an dem auf PB7 eine LED angeschlossen ist.
Es wurden keine mit deiner Suchanfrage - STM2L152R8T6 -
übereinstimmenden Dokumente gefunden.
Ist doch klar, dass ich den STM32L152R8T6 meinte :).
Die entsprechenden Defines muss ich erstmal finden, das war bis jetzt ja
schon unübersichtlich genug :(.
Und du glaubst echt das
- jemand der alle konstanten im kopf hat bock hat deine durchzugehen
- jemand der nicht die konstanten im kopf hat bock hat im Datenblatt
nach allen konstanten zu suchen.
Ach ja, nur beim instruktionen zählen ist mir aufgefallen:
es müssten 5 instruktionen zur konfiguration von GBOIOB_x als ausgang
sein, OHNE den wert zu setzen. Damit fehlt wahrscheinlich 1.
Ich sehe aber nur 4 passende Register.
Input/Output, Speed, Type, Pullup/down
Dann gibts noch Data Out/In. Lock, Alternate Funktion benutze ich nicht,
kann laut Datenblatt alles auf 0 bleiben.
pegel schrieb:> was soll das am Ende bringen?
Jeder ist seines eigenen Glückes Schmied.
Irgendwann wird er es schon checken.
Vor allem auch dass CooCox nicht das Glückseeligmachende ist.
Was du da machst hat für dich der Hersteller ST bereits gemacht, du
musst das Rad nicht neu erfinden indem du auf Registerebene arbeitest.
Hier:
http://www.st.com/en/embedded-software/stsw-stm32077.html
Diese Bibliothek in dein Projekt einbinden und die Funktionen verwenden
Diese Bibliothek übernimmt die ganze Registerarbeit für dich verpackt in
C-Funktionen und Strukturen die du nur noch aufrufen musst.
Dann hast du solche Funktionen wie:
RCC_AHB1(RCC_GPIOA,ENABLE); // Clock aktivieren
// ...
GPIO_Struct.Pin = 5
GPIO_Struct.Speed = 100 // MHz
GPIO_Struct.Type = Output
// ...
// ...
GPIO_Init(GPIOA, Strukturvariable mit allen Einstellungen);
Das was du machst , mit Registern zu arbeiten, ist bei der AVR-Plattform
noch in Ordnung. Aber bei STM32 wirst du besonders als Anfänger
untergehen, einfach weil es sehr kompliziert ist und sehr viel
Datenblattkenntnisse erfordert.
Die StdPeriph hat noch vieles weitere Nützliche, was du besonders
brauchen wirst, um schnell eine LED zum blinken zu bringen:
>83 examples for 24 different peripherals
Es sind bereits ganze Beispiele vorprogrammiert: Wie schalte ich einen
Ausgang, wie lese ich einen Eingang, SPI-Bus, I2C-Bus, UART, DMA, ....
Damit befassen (und gute Englischkenntnisse haben) und von dort kopieren
und an deine Situation anpassen (richtigen Pin, ..)
>Template project for 3 different IDEs
Hier kriegst du bereits vorgefertigte leere Projekte, die alles
initialisiert haben, wenn du in deine main gelangst.
Damit hast du: Richtig konfigurierten Clock inkl. aktivierten Quarz,
initialisierte Interruptvektoren, "sauberen" RAM (alles mit Nullen
vorinitialisiert!)
Also bitte die Templates verbwenden, denn bei einem STM32
Mikrocontroller musst du sehr viel erst vorkonfigurieren, bevor du was
in der main anstellen kannst.
Andre schrieb:> Ich sehe aber nur 4 passende Register.
Irgendwas scheint aber trotzdem falsch zu sein. Schon um die Fehlersuche
zu erleichtern würde ich mal den Coide-examplecode mit
RCC_Configuration();
und
GPIO_Configuration();
nehmen.
RCC->CR = 0x01;
RCC->CFGR = 0x01;
RCC->AHBENR = 0x0F;
Ich hab sowas noch nie selbst gemacht. in der Stm-Funktion sind aber
Warteschleifen drin. Vielleicht haben die doch einen Sinn?
Die Delays mit der Warteschleife werden evtl. nicht funktionieren, weil
die Dummyvariable zwar volatile deklariert ist, dies aber
funktionslokal. Evtl. optimiert das der Compiler trotz volatile weg.
Deklarier die lieber als globale Variable.
Mal abgesehen davon, daß man so ein Delay eh über den Systick machen
würde mit Systemzeit, aber für den ersten Schnellschuß ist ein
provisorisches Delay ja OK.
Merkwürdig finde ich, daß bei Dir der Init dermaßen einfach ist. Also
bei den Oszillatoren etwa gehört noch ne Warteschleife dahinter, daß der
auch wirklich losgegangen ist (RCC_CR abfragen). Das Reference Manual
enthält oftmals interessante Hinweise, was man wie machen soll.
Bei den Clocks kann's noch sein, daß außer AHB auch noch APB geclockt
werden muß, das kommt aber auf den Chip an (Datenblatt nachschlagen).
Ich finde den Hinweis auf die HAL mit "nimmt einem alles ab" übrigens
nicht produktiv. Wenn ein Anfänger sich schon die Mühe macht, den Chip
wirklich verstehen zu wollen, dann finde ich das positiv bemerkenswert.
Ist etwas steiniger, ja, aber der Lerneffekt ist weitaus größer, als
wenn man in der HAL bloß lernt, welche Funktionen man aufrufen soll.
Nop schrieb:> Ich finde den Hinweis auf die HAL mit "nimmt einem alles ab" übrigens> nicht produktiv.
Wer schreibt hier was von HAL? Kein Schwein.
Es wurde nur berechtigterweise "gemeint" doch die SPL und deren
Set-Funktionen zu verwenden.
Ich hoffe du kennst den Unterschied zwischen HAL und SPL?
>Ich finde den Hinweis auf die HAL mit "nimmt einem alles ab" übrigens>nicht produktiv. Wenn ein Anfänger sich schon die Mühe macht, den Chip>wirklich verstehen zu wollen, dann finde ich das positiv bemerkenswert.
Ist nicht HAL, sondern stdperiph. Und warum soll diese Bibliothek nicht
lernfördernd sein? Sie ist open-source und dokumentiert und arbeitet
auch mit Registern, aber mit vielen Defines.
Man kann jederzeit da reinschauen in die Funktionsimplementierung und
sehen welche Register in welcher Reihenfolge ansteuert werden und sich
davon insperieren lassen.
Das was der Threadersteller oben gemacht hat, kann er morgen nicht mehr
nachvollziehen, weil da Bits gesetzt werden, aber die Zugehörigkeit der
Bits nicht aus dem Code hervorgeht. Wenn er diesen Weg weitergeht, wird
irgendwann alles zusammenbrechen weil die Komplexität zu groß geworden
ist.
>Merkwürdig finde ich, daß bei Dir der Init dermaßen einfach ist.
Wenn der Threadersteller ein IDE-Template verwendet hat, kann es sein,
dass vielleicht vorher etwas schon initialisiert wurde.
Wenn nicht, dann kann es so überhaupt nicht funktionieren. Wo ist z.B.
die PLL-Konfig (richtigen Multiplikator setzen), Quarzaktivierung?
Ich kenne den STM32 nicht, aber so weit mir bekannt, kann man bei
solchen Teilen, mit den Defaults, keine LED beeindrucken.
Üblicherweise sind alle Pins - Reset-Modus - Eingänge und somit sollte
man zumindest den Gewünschten Port explizit davon überzeugen ein Ausgang
zu werden.
Noch eine kleine Randbemerkung zum Anfangspost:
Die Bibliothek von ST verwenden für die Ausgangspins die folgenden
Register anstelle von ODR:
->BSRR (Ausgang auf HIGH setzen)
->BRR (Ausgang auf GND)
Das könnte der folgende Grund sein, da man weniger Instruktionen
braucht:
but you have to read the ODR register, OR (|) or AND(&) (modify) it with
a mask and then write it back to the ODR register. This means that at
the assembly language level, at least three instructions are used to
set/clear an I/O which can significantly slow down toggling speed. A
better way would be to use the BSRR register and the BRR registers for
setting and clearing pins. They enable 'atomic' access that allows the
I/O pin to be clear/set in as short a time as possible.
derjaeger schrieb:> Ist nicht HAL, sondern stdperiph.
Spielt keine Rolle.
> Und warum soll diese Bibliothek nicht> lernfördernd sein? Sie ist open-source und dokumentiert und arbeitet> auch mit Registern, aber mit vielen Defines.
Weil hier genau schon wieder sowas kam:
"Diese Bibliothek übernimmt die ganze Registerarbeit für dich verpackt
in
C-Funktionen und Strukturen die du nur noch aufrufen musst."
Auf gut deutsch: man muß sich nicht mit der Hardware befassen, machen
alles ganz tolle vorgefertigte Funktionen, damit man auch ja nichts über
den Chip lernen muß. Großartig, und die Konsequenz ist, daß man dann
blöd dasteht, wenn man einen nicht-ST-Chip bearbeiten soll/will. Oder
wenn die rottige ST-Software mal wieder nicht das tut, was sie soll.
> Das was der Threadersteller oben gemacht hat, kann er morgen nicht mehr> nachvollziehen, weil da Bits gesetzt werden, aber die Zugehörigkeit der> Bits nicht aus dem Code hervorgeht.
Ja klar, das sollte man mit vernünftigen Bitmasken-Defines machen.
> Wenn nicht, dann kann es so überhaupt nicht funktionieren. Wo ist z.B.> die PLL-Konfig (richtigen Multiplikator setzen), Quarzaktivierung?
Braucht man nicht. Der TE schrieb doch, daß er auf HSI geht, also kein
Quartz nötig. Sicher hat man dann nur 16 MHz (je nach Chip) und nicht
den vollen Rums, aber um eine LED blinken zu lassen, langt der HSI auch
ohne PLL.
Ich habe bisher nur mit 8bittern mit AVR/PIC gearbeitet. Auf dem ersten
Blick sieht das Datenblatt des STM32 etwas komplexer aber definitiv
nicht komplizierter aus.
Wo es die Bitmasken Defines gibt ist mir auch noch ein Rätsel. Warum es
Hersteller wie ST nicht hinbekommen eine übersichtliche Software wie
Microchip/Atmel zu erstellen ist mir ein Rätsel. Das hat auch mMn nichts
mit Anfängertum etc. zu tun, sondern mit Benutzerfreundlichkeit. Die ST
Homepage ist ja nun übertroffen unübersichtlich. Nimm hier eine IDE,
hier hast du 1000 Bibliotheken, irgendwo gibts auch noch hier ein Paket
zu finden mit 1000 Programmen.
>Warum es>Hersteller wie ST nicht hinbekommen eine übersichtliche Software wie>Microchip/Atmel zu erstellen ist mir ein Rätsel.
Welche Software? Die IDE? Was hat denn die IDE mit der richtigen
Programmierung des ARM zu tun?
>Wo es die Bitmasken Defines gibt ist mir auch noch ein Rätsel.
Entschuldige, DU hast doch die Headerdatei eingebunden. Mal reinschauen?
>/******************* Bit definition for GPIO_MODER register >*****************/>#define GPIO_MODER_MODER0 ((uint32_t)0x00000003)>#define GPIO_MODER_MODER0_0 ((uint32_t)0x00000001)>#define GPIO_MODER_MODER0_1 ((uint32_t)0x00000002)>#define GPIO_MODER_MODER1 ((uint32_t)0x0000000C)>#define GPIO_MODER_MODER1_0 ((uint32_t)0x00000004)>/******************* Bit definition for GPIO_OTYPER register >****************/>#define GPIO_OTYPER_OT_0 ((uint32_t)0x00000001)>#define GPIO_OTYPER_OT_1 ((uint32_t)0x00000002)>#define GPIO_OTYPER_OT_2 ((uint32_t)0x00000004)>#define GPIO_OTYPER_OT_3 ((uint32_t)0x00000008)>#define GPIO_OTYPER_OT_4 ((uint32_t)0x00000010)
Andre schrieb:> Das hat auch mMn nichts mit Anfängertum etc. zu tun
Doch genau das ist es. Du hast dich noch nicht ausreichend
zurechtgefunden, das "was ist wo" fehlt dir noch.
Andre schrieb:> RCC->CR = 0x01;
Das ist meiner Meinung nach wirklich sehr unleserlich. Viel besser wäre
1
RCC->CR=RCC_CR_HSION;
Die Bitmasken sind standardisiert nach dem Schema
PERIPHERIE_REGISTER_FELDBEZEICHNER und entsprechen 1:1 den Abkürzungen
im Reference Manual.
Andre schrieb:> RCC->AHBENR = 0x0F;
Auch hier wäre mMn RCC-> AHBENR |= RCC_AHBENR_GPIOBEN; deutlich besser.
Man sollte auch aufpassen wegen "|=" und "=" und wo sinnvoll, verodern
statt einen fixen Wert zuzuweisen.
Die HSI-Konfiguration würde ich erstmal komplett weglassen, da der L1 ja
ab Reset mit 2 MHz MSI läuft.
Warum es bei dir nicht funktioniert kann ich nicht sagen. Es ist gut
möglich, dass Coocox hinter deinem Rücken schon irgendeine
Taktkonfiguration vorgenommen hat, wobei ich mir nicht erklären kann
warum das einen Unterschied machen sollte (abgesehen von der Frequenz
mit der die LED flackert). Wenn man von einer Taktquelle auf eine andere
umschaltet sollte man jedenfalls das jeweilige "Ready-Bit" abfragen, da
es jeweils ein paar Takte dauern kann bis HSI, HSE, PLL und Co
eingeschwungen sind.
Wenn du dich auf Registerebene mit den STM32 beschäftigen willst und den
Frustfaktor möglichst gering halten willst, dann würde ich dir die
STM32-Snippets empfehlen (
http://www.st.com/en/embedded-software/stm32snippets.html ), die gibt es
für die F0 und L0 Serie und sind auf das F072-Discovery bzw.
L053-Discovery Board zugeschnitten. Letzteres gibt es derzeit in der
Bucht für ~13€ inkl. Versand
http://www.ebay.de/itm/Discovery-kit-for-STM32L0-series-with-STM32L053C8-MCU-1-Stuck-/311934443991?hash=item48a0bde1d7:g:8tQAAOSwGrFZiWcP
Bei den "Snippets" wird im Prinzip die komplette Peripherie abgedeckt
und es gibt zu allem Beispielcode woran man sich orientieren kann. Dazu
dann noch das Reference-Manual und in relativ kurzer Zeit weißt du was
die Welt im innersten zusammen hält.
Als IDE würde ich dann für den Einstieg SW4STM32 nehmen. Coocox ist ein
totes Pferd, bei dem aktuelle Controller-Familien schon nicht mehr
unterstützt werden und es mehr als zweifelhaft ist ob sich das jemals
ändern wird. Das gleiche gilt für die so oft gepriesene StdPeriphLib.
Die L4-Serie wird zum Beispiel nicht unterstützt, was eine Portierung
von L0 oder L1 sehr schwierig gestalten dürfte.
Grundsätzlich sollte man sich auch überlegen, inwieweit man sich
überhaupt an eine IDE binden will. Zum Flashen oder gelegentlichen
graphischen Debuggen ist das sicherlich nützlich, aber den eigentlichen
Build mache ich lieber mit Scripten.
Mit der SW4STM32 geht es auf Anhieb, auch mit Registern. So habe ich mir
das vorgestellt - IDE installieren, neues Projekt und ich kann mich auf
das Programmieren konzentrieren.
Und das hat auch so fantastische Funktionen wie Auto Ergänzung.
Strg + Leertaste
Oder Anzeige der Werte und Funktionen.
mit der Maus drüber oder markieren und F3