Hallo,
ich habe in letzter Zeit ein kleines Tutorial über STM32 Mikrocontroller
geschrieben und dachte, dass sich hier ein paar Leute dafür
interessieren könnten:
http://diller-technologies.de/stm32.html
Ich bin selbst erst seit kurzen von AVRs auf STM32 umgestiegen, soll
heißen, dass in den Texten/Code durchaus noch Fehler drin stecken
können. Wenn jemand was findet, auch wenn's Rechtschreibfehler sind oder
was unverständlich ausgedrückt ist, darf er's mir gerne (hier)
mitteilen.
Falls jemand eine gute Möglichkeit kennt C-Code in bunten HTML/CSS Code
umzuwandeln, würde ich mich auch sehr über eine Mitteilung freuen.
Das Tutorial wird auf jeden Fall noch erweitert, sofern mal Zeit dafür
übrig ist.
Endlich mal eine Anleitung wie man sie sich als Umsteiger wünscht:
anfängertauglich und voll mit Hinweisen auf Stolperfallen und
Beispielcode. Sogar die IDE wird erläutert. Klasse!
An die Moderatoren/Admins: Laßt das nicht in die der Versenkung
verschwinden. Ein klarer Fall für die Artikelsammlung, aber ganz weit
oben!
endlich das Tutorial, das ich in den letzten Wochen gesucht habe... ;-)
Ich steige auch gerade von AVR auf STM32 um und werde mir das in den
nächsten Tagen mal genauer ansehen.
Danke!
Ich möchte hier gerne noch einen Querverweis zu einem Thread mit einem
Workspace für CoIDE und STM32F4-Discovery einbringen, der mir bei der
Inbetriebnahme geholfen hat...
Beitrag "CooCox CoIDE mit STM32F4-Discovery Board"
Moritz dein Tutorial sieht super aus, war mir aber bei der
Installationsbeschreibung der Toolchain etwas zu knapp. Trotzdem vielen
Dank für deine Mühe. Ich werde das mal alles nachmachen.
Hast du das Olimex Maple Board aus deinem Tutorial auch unter CoIDE zum
laufen gebracht? Könntest du da vielleicht auch einen einfachen
Workspace hochladen? Mir sind diese ganzen Arduinosachen suspekt.
Gruß
Tim
Das mit der Toolchain hab ich nicht weiter erklärt, weil's auf der
CooCox-Seite ne super Anleitung mit Screenshots gibt:
http://coocox.org/CoIDE/Compiler_Settings.html
Aber du hast recht, den Link sollte ich im Text erwähnen.
Beim Maple Board hab ich für den SWD-Connector nen Adapter zum ST-Link
gelötet. Dem Mikrocontroller ist es relativ egal, was an Peripherie
dranhängt, die Programmierung läuft gleich ab. In dem Fall ist es ein
STM32F103RB. Den einfach in CooCox beim Projekterstellen auswählen und
CooCox legt für dich einen auf den Chip angepassten Workspace an.
Mit Arduinos hab ich vorher auch noch nie was gemacht. Seh's einfach
also günstiges Board mit schönen Buchsen, LEDs, Tastern und einem
CAN-Treiber etc. an. ;-)
Torsten S. schrieb:> An die Moderatoren/Admins: Laßt das nicht in die der Versenkung> verschwinden. Ein klarer Fall für die Artikelsammlung, aber ganz weit> oben!
Den kann man dort selbst einstellen...
Moritz Diller schrieb:> Mit Arduinos hab ich vorher auch noch nie was gemacht. Seh's einfach> also günstiges Board mit schönen Buchsen, LEDs, Tastern und einem> CAN-Treiber etc. an. ;-)
Das heißt, du nutzt das Board ohne die Arduino Lib?
Sogut wie allen Code im Tutorial hab ich auf dem Board getestet. CAN
funktioniert auch wunderbar, bis jetzt hatte ich nur noch keinen zweiten
Sender um den Datenempfang auszuprobieren.
Wird aber in absehbarer Zeit nachgeholt.
Da könnte ich dir für Basteleien das hier empfehlen:
http://www.kreatives-chaos.com/artikel/can-debugger
Einfach mal anschreiben, vielleicht hat er noch Platinen.
Ist nocht perfekt, aber für kleines Geld eine gute Hilfe bei CAN.
Moritz Diller schrieb:> Beim Maple Board hab ich für den SWD-Connector nen Adapter zum ST-Link> gelötet.
Welchen Stecker auf der SWD Seite hast du für den Adapter genommen?
Wenn ich das richtig sehe, handelt es sich um ein 1,27 mm Raster.
Danke.
Genau, Raster liegt bei 1,27 mm, heißt sowas würde gehen:
http://de.farnell.com/fci/20021311-00010t4lf/buchse-vert-1-27mm-tht-10wege/dp/1865313
... gibt bestimmt günstigere Alternativen. ;-)
@Tim
Thx für den Tipp. Hatte noch keine Zeit mir das Projekt genauer
anzuschauen, werd ich aber nachholen. Bis jetzt tut's der Logic
Analyzer, aber der kann logischerweise nix raussenden.
Ich habe jetzt von Farnell diesen Stecker genommen: 1865335
Den kann man direkt auf ein entsprechend feines Flachbandkabel
aufpressen.
Damit habe ich mir wenigstens auf der einen Seite die Löterei gespart.
Als Kabel habe ich ein altes Festplattenkabel geschlachtet.
Gruß
Peter
Hi,
mir schwirrt da gerade eine etwas blöde Frage im Kopf rum.
Nachdem ich mir das Errata Sheet mal angesehen habe und auf meinem Maple
Board eine 1 hinter dem ARM auf dem STM32F103RBT6 steht, gehe ich von
einer Revision 1 aus.
Aber wie steht die 1 mit den anderen Revisionen im Zusammenhang?
Gennant werden B, Z, Y und 1 und zwar auch in der Reihenfolge.
Was ist neu und was ist alt?
Ein älteres Errata zum Vergleichen konnte ich nicht finden.
Kann mich da jemand aufklären?
Danke!
Gruß
Tim
Das ist echt ein super Tutorial geworden, vielen Dank dafür.
Hast Du das CAN Beispiel auf dem Discovery laufen lassen? Ich dachte
nämlich bisher, dass der dort verwendete STM32 keinen CAN Controller
hat. Kann mich aber täuschen, da ich momentan nur wenig Zeit habe, mich
mit dem Teil zu beschäftigen.
mfg
Michael
Ich finde auch, das ist ein gute Tut, vielen Dank!
Kannst Du ein Link auf Deine Seite im Artikel STM32 machen?
Am besten unter "Demo-Projekte" ein Unterabschnitt Tutorial auf machen
und da den Link eintragen.
Update:
- neue Kapitel über 13 ADC, 14 DMA und 15 Häufige Fehler
- Controllertypen stehen jetzt rechts oben am Code
- Hinweis zu verschiedenen STM32 Familien in der Einleitung
- Link zur Einstellung der Compiler Settings auf coocox.org
- Links zu wichtigen Dokumenten
- Hinweis zu den Funktionen für die PWM-Channels CH2...4
Wem noch Punkte zu "Häufige Fehler" einfallen, darf sie hier posten.
Auf der Artikelseite hat bereits jemand ganz unten bei Weblinks einen
gesetzt. Wenn du den wo anders deutlicher haben möchtest kannst du's
gerne selbst anpassen, ich bin grad zu faul nachzulesen, wie's geht. ;-)
Eine Kleinigkeit, die mir heute aufgefallen ist:
Im Tutorial unter Punkt 7 hast du die beiden letzten Kommentare
vertauscht.
1
GPIO_Mode_Out_OD–AusgangOpen-Drain
2
GPIO_Mode_Out_PP–AusgangPush-Pull
3
GPIO_Mode_AF_OD–AlternativeFunktionPush-Pull
4
GPIO_Mode_AF_PP–AlternativeFunktionOpen-Drain
Noch eine Frage zu GPIOs. Wenn ein Port mit einem Takt versorgt wird,
wie initialisiert man einen ungenutzten Pin?
Bei den ATmegas steht beispielsweise im Datenblatt, dass ungenutzte Pins
als Eingang mit aktivertem PullUp geschaltet werden sollen. Für die
STM32 habe ich nichts finden können.
Hat denn vielleicht auch noch jemand einen Hinweis zu meiner Frage zur
Chip Revision (s.o.)?
Gruß
Tim
Thx für den Hinweis, Fehler ist ausgebessert.
Floatende Eingänge sind laut Theorie nie gut, wenn's um den
Stromverbrauch geht, das dürfte bei den STM32 nicht anders sein. Ist
meiner Meinung nach aber eh nur relevant, wenn's um jedes µA geht. Bei
nem ATmega hab ich's mal nachgemessen und konnte mit dem Multimeter
keinen Unterschied feststellen.
Zur Chip Revision kann ich dir leider auch nix Genaueres sagen, aber
solang das aktuelle Errata für deinen Chip gültig ist gibt's doch kein
Problem, oder?
Noch ein kleiner Wunsch:
Update doch bitte das Datum ganz oben auf der Tutorialseite oder führe
eine Versionsnummer ein, dann hat man es leichter (auch ohne diesen
Thread) Änderungen zu erkennen. Danke.
Ansonsten tolle Arbeit!
Also ich habe es mal bei einem AT90CANxxx gemessen und da hat es schon
signifikant etwas ausgemacht. Nämlich soviel, dass ein 7805 bei 24V
Eingangsspannung nicht mehr zu heiß wurde.
Bei der Chiprevision ist das Problem bei einer Aussage wie "ab Revision
x gilt", wobei ich jetzt gerade ohne nachzugucken nicht mehr weiß, ob
sowas wirklich vorkam. Interessierte mich halt einfach.
Ja, des mit dem Datum hatte ich zunächst auch vergessen, hab's aber
vorhin schon mit aktuallisiert. Auf meiner Startseite gibt's zu jedem
(umfangreicheren) Update eine Zeile unter "News". ;-)
Hallo,
ich habe mir die CooCox IDE wie im Tutorial beschrieben installiert
incl. CoFlash und verwende auch das im Tutorial beschriebene STM32 Value
Line Discovery-Board mit STM32F100RB. Beide Jumper an CN3 sind gesteckt.
Leider findet das Flash-Tool mein Board nicht. Sobald ich das Board
anstecke bekomme ich einen Wechseldatenträger mit den folgenden 3 Links:
STMicroelectronics - Microcontrollers - 8-bit microcontrollers, 16-bit
microcontrollers and 32-bit ARM microcontrollers
STM32 (CORTEX M3) - 32-bit Microcontrollers
STM8S - 8-bit Microcontrollers
Das richtige Derivat habe ich in CoFlash ausgewählt. Beim
Zugriffsversuch bekomme ich allerdings die Meldung: "Adapter not found".
Grüße,
Jochen
Den Treiber hatte ich schon installiert, hab ihn nochmal entfernt /
erneut installiert, jedoch ohne Erfolg. Komisch ist auch, dass der bei
der installation angegebenen Pfand ..programme/stmi.... nicht angelegt
wird.
kleines Update:
- Syntax-Highlighting
- Neue Optionen rechts oben: Wahl zwischen auf 800x600 und 1024x768
optimierter Auflösung
Der Internet Explorer schneidet überstehende Codezeilen ab, anstatt sie
umzubrechen. Ich finde es unverständlich, dass Microsoft es in Version 9
immernoch nicht fertig bringt Standards zu implementieren, die z.B.
Firefox seit Version 1.0 unterstützt.
@Jochen
Falls das Problem noch besteht, würde ich alles mal auf einem anderen PC
installieren, damit kannst du rausfinden, ob es am PC liegt oder du noch
irgendwas übersehen hast. ;-)
Hallo zusammen
nachdem ich heute endlich meinen LQFP48 Adapter für's Steckbrett fertig
hatte ging es gleich ans Bestücken. Siehe da alles läuft wie geplant.
Jetzt fehlte nur noch ein Testprogramm. Auf der Suche nach einem
Tutorial bin ich dann über dass hier verlinkte gestolpert, welches mir
sehr geholfen hat.
Deshalb wollte ich mich an dieser Stelle vielmals für deine Mühen
bedanken, welche du in das Tutorial gesteckt hast, um den Einstieg in
die STM32 Controllerfamilie zu vereinfachen.
Gruß
Jasper
:-)
In dem PDF geht es halt nur um den Core. Da gibt es auch ein recht
schönes Buch: "The Definitive Guide to the ARM Cortex-M3". Das war das
Erste, was ich zum M3 gelesen hatte. In der Praxis finde ich die
Informationen aber eher weniger relevant -> besser man ließt sich die
Dokumente von ST durch. Zumindest als Anfänger war für mich das Buch
kaum hilfreich um in die STM32 Controller einzusteigen.
Nagut, für Leute, die es ganz genau wissen wollen macht es schon Sinn
sich intensiver mit dem Core auseinander zu setzen. Ich werde mir
überlegen, ob ich den Link beim nächsten Update mit aufnehm.
Was ist eigentlich der Unterschied zwischen CMSIS und der Standard Lib
von ST?
Baut die Standard Lib auf CMSIS auf, oder ergänzt sie ihn nur?
Wenn man auf beides verzichtet muss man selber auf Registerebene
arbeiten, richtig?
CMSIS ist eine Schicht unter der Standard Lib. Ohne CMSIS hat man
nichtmal Aliase für die Registeradressen. CMSIS is grob gesagt, sowas
wie die io.h bei AVRs (verbessert mich, wenn ich falsch liege^^).
Moin Zusammen
CMSIS ist ein Standard für den Aufbau von PerephrieLibs für Cortex µCs.
Das hat nichts mit den Register Definitionen zu tun die stehen in der
stm32Fxxx.h. Die Definitionen die jeder Cortex Kern braucht finden sich
in der cmx_core.h die haben aber nichts mit CMSIS zu tun. Das ist viel
eher die Geschichte Perephrie_Funktion() benennung und andere
Richtlinien.
Das soll eigendlich dazu dienen das do von STM32 schnell auf LM3S
umsteigen kannst. Was mit Einschränkungen auch funktioniert.
MfG
Tec
Moritz Diller schrieb:
ähem, in seiner Anleitung:
"Im Gegensatz zu beispielsweise AVRs sollte man die Register der STM32
nicht direkt ansprechen, sondern über Funktionen der Standard Peripheral
Library"
Huch, wie kommst du zu so einer Aussage?
Natürlich benutzt man in einem uC-Projekt die Register des uC direkt,
was denn sonst!! - wir haben ja hier kein Betriebssystem mit
Virtualisierung, API und nem geordneten Treiber-Stack wie z.B.
WindowsCE. Wer also was mit der Peripherie anstellen will, greift direkt
drauf zu.
BTW: Hast du dir eigentlich schon mal diese unsägliche ST-Lib
angeschaut? Für mich z.B. ein Grund, diese Lib nie und nimmer zu
benutzen.
W.S.
Hallo Moritz,
ich hab das Tutorial jetzt nur kurz überflogen und denke aktuell noch
nicht an einen Umstieg.
Ich möchte mich aber trotzdem bei dir bedanken für die viele Arbeit die
du dir gemacht hast. Dafür beide Daumen hoch!!!
@ W.S.
Ich seh's halt so, dass einen die Funktionen der ST-Lib vor vielen
Fehlern schützen und man dadurch kaum auf Bit-Ebene arbeiten muss. Der
Code wird nebenbei wesentlich leichter lesbar.
Klar hab ich mir die Lib schon oft angeschaut, wo genau siehst du da
Probleme?
@Eumel
Thx. Kommt natürlich immer drauf an, was man in der speziellen Anwendung
braucht, auf jeden Fall sind die STM32 vom Preis-Leistungs-Verhältnis
recht gut. Bei AVRs sieht's z.B. mit CAN-Interface recht schlecht aus.
Erstmal möchte ich dir für das Tutorial danken. Ich habe schon sehr
lange nach so etwas gesucht, aber das Wort Tutorial wollte mir nicht
eifallen :D
Ein paar Anmerkungen habe ich:
Du empfehlst das Discovery VL Board, das entsprechende Datenblatt hast
du aber nicht verlinkt. Ich habe jetzt nur das für den F103xB
(Olimexino) gesehen. Ist ja nicht schlimm, aber der Vollständigkeit
wegen würde ich es erwähnen.
Dann noch einige Rechtschreibfehler beim Überfliegen entdeckt. Auch fiel
mir auf, dass du gerne Kommas weglässt, wo welche hin müssen.
Hier noch ein kleiner Auszug zu Rechtschreibfehlern:
Thx, die drei Fehler sind ausgebessert, den Link füg ich mal ein, wenn
Zeit übrig ist. ;)
HalfWord ist auch durchaus bisschen korrekter.^^
Die Sache mit den Kommas hatte ich leider noch nie wirklich gut drauf.
Wenn's dich stört einfach posten, dann besser ich das gerne aus.
Hi, bin Anfaenger und habe eine Frage.
In Abschnitt 7 im ersten Codeblock wird Port B konfiguriert als OUT PP.
Doch mir ist nicht klar, warum das nur die Pins von Port B betrifft.
Angenommen es waeren noch die Ports A und C aktiviert, wie teile ich dem
Controller mit, dass ich nicht Port A oder C meine sondern nur B.
Ich weiss nicht, ob ich klar machen kann, was ich genau meine. Kann
jetzt am Handy auch schlecht Copy Paste durchfuehren.
super Tutorial hat mir richtig gut geholfen! Möchte mich ganz herzlich
bei dir bedanken. Kannst du evtl. sagen wann es ungefähr weiter geht und
welche Themen als nächstes kommen? (Kommt auch etwas zur RTC?)
Bin leider immernoch im Stress und komm wahrscheinlich erst wieder in
ca. zwei Monaten dazu am Tutorial richtig weiter zu schreiben.
Ganz oben auf der Liste stehen CAN-RX, Watchdog, RS485 bzw. USART und
DAC, da hab ich auch teilweise schon Code rumliegen.
Je nachdem, wie motiviert ich dann bin pack ich noch die RTC mit drauf.
;)
Ich bitte Dich inständig, das Projekt alsbald weiterzuführen und nicht
in Vergessenheit geraten zu lassen. Für viele von uns erleichtert das
den Einstieg unvorstellbar.
Klar, das in jedem Fall. :)
Hab nur gerade zwei andere Projekte am Laufen, die schnellstmöglich
fertig sein müssen und in zwei Wochen beginnen dann schon die ersten
Klausuren. Insofern ist µC Basteln grad eher ungut.^^
Hallo,
ich versuche gerade das allererste Beispiel des Tutorials zum Laufen zu
bekommen.
Ich habe auch alles so eingestellt wie auf den Screenshots.
Frage: Ist die StdPeriphLib bei CooCox standardmäßig schon dabei? Ich
bekomme nämlich den Fehler
[code}
warning: implicit declaration of function 'RCC_APB2PeriphClockCmd'
[-Wimplicit-function-declaration]
error: 'RCC_APB2Periph_GPIOC' undeclared (first use in this function)
[/code]
Muss ich also die Lib vorher noch mit einbinden?
Vielen Dank!
Hallo,
dein tutorial finde ich voll interessant.
jedoch hätte ich eine Frage, und zwar wo kann ich ein Befehlsatz( C und
Assembler) von dem STM32 herunterladen.
sowohl für ADC als auch Timer und alle andere Sachen.
viele Grüße
Das Zitat: "Die Struktur GPIO_InitTypeDef besitzt drei Elemente: "
stimmt nicht, die Struktur hat 5 Elemente.
Schreibfehler in "Andernfalls muss das CAN-Modul manuell neue
initialisiert werden.".
Änder es doch, rechts gibt es einen "Bearbeiten" Link, mit dem man jeden
einzelnen Abschnitt ändern kann. Geht ganz leicht ;-)
Die Lib von ST wird ständig erweitert und entsprechend updatet sich der
Artikel STM32 auch nicht alleine von Geisterhand.
Auf meiner Seite geht es nur um den Cortex M3 bzw. die STM32F10x. Für
die STM32F4xx stimmt die Aussage, dort sind es wirklich fünf Elemente.
Bei den M4 wird eine andere Library von ST angeboten in der es einige
Unterschiede zu der für die M3 gibt.
Schreibfehler ist geändert, danke für den Hinweis.
Markus, ich muss dich leider enttäuschen, aber auf meiner Seite gibt es
keinen "Bearbeiten" Link. ;)
Moritz
Großartiges Tutorial, habe ich aber schon geschrieben.
Kleines Update für Version 1.6.2: C99 muß man nun in
View->Configuration->Compile in "Misc Controls" "-std=c99"
eintragen. Habe einige Zeit verbracht das zu finden.
Vielen Dank für das Tutorial - das hilft wirklich weiter.
Darf ich dich fragen woher du die Infos hast? Die STM32 Libs sind ja
fürchterlich schlecht beschrieben, und teilweise finde ich mehrere
Befehle für die gleichen Sachverhalte.
Ja, also meistens läuft es folgendermaßen ab, wenn ich ein neues Feature
benutzen will:
(1) Reference Manual dazu lesen: Hier steht eigentlich alles drin, was
die Einheit im µC kann, wie sie initiallisiert werden will und was man
danach im laufenden Betrieb machen muss. Prinzipiell weiß man dann, wie
man das Peripheriemodul nutzen würde, wenn man direkt auf die Register
zugreifen würde.
(2) Nachschauen, ob es schon ein Beispiel von ST gibt: In der ST-Lib ist
ein Ordner mit vielen Beispielen und wenn man nicht was ganz
Ausgefallenes braucht wird man hier meist fündig. Dann den Code kopieren
und bisschen was ändern, so dass er auf einem Eval-Board läuft.
(3) Rausfinden, wie genau der Code funktioniert: Wenn man vorher das
Ref. Manual gelesen hat erklärt sich das Meißte ziemlich gut mit der
Dokumentation zur ST-Lib.
(4) Bei den Dingen die man nicht versteht muss man wohl oder übel in den
Code der ST-Lib reinschauen und mithilfe des Ref. Manual in den Register
Beschreibungen am Ende jedes Kapitels herausfinden, was die
ST-Funktionen tun. Beispiele:
- CAN_FilterMaskIdHigh aus CAN_FilterInitTypeDef ist so ein Punkt wo
die ST-Lib recht hässlich ist. Im Mask-Mode stellt das Element eine
Bitmaske dar, allerdings ist es im List-Mode eine "normale" ID. Ebenso
müssen hier noch Bitshifts gemacht werden, was in der ST-Doku einfach
unter den Tisch gekehrt wird.
- TIM_ClockDivision von TIM_TimeBaseInitTypeDef ist nicht, wie man
erstmal denkt, ein weiterer Vorteiler für den Timer, sondern hat nur
dann Einfluss, wenn der Timer über einen herausgeführten Pin getaktet
wird. ST-Lib: "Specifies the clock division." ... -> Nicht!
Irgendwann kommt man also trotz ST-Lib an den Punkt an dem man sich
nicht mehr um das Bitgeschubse drücken kann. ;)
Astrein, schönes Tutorial :-)
Hätte ich vor einem Jahr mal gebraucht ;-)
Finde die ARM-Programmierung nicht sonderlich schwer...
Referenzmanuell durchschauen um zu sehen was für Möglichkeiten es gibt
und wie es funktioniert,
und in der Lib nachschauen wie das Structure aufgezogen ist,
dementsprechend weiß man wie viele Sachen man angeben muss.
Ich habe damals KEIL als IDE Plattform genommen.
Ging aber ohne Probleme ;-)
Wie schaffe ich es denn, dass ich z.B. Pin 8 und 9 bei PortC als Ausgang
habe und Pin 5 an PortC als Eingang für nen Knopf... bzw einen anderen
Pin an Port C als Analog?
Also wie muss dann meine Init Struct aussehen? Irgendwie raff ich es
noch nicht so ganz.
Angenommen ich erstelle mit nun noch eine neue Struct und schreibe die
dann auch auf PortC wird die vorherige nicht ersetzt?
Deine Intitstruct muss einmal so aussehen, dass du pin 8 und 9 je einen
ausgang hast... denn übergibst du sie an die funktion gpio_init danach
änderst du sie so um dass pin 5 ein eingang ist und übergist sie nochmal
mit einmal übergeben wird das nichts
Ahh danke. War halt nur am überlegen, ob dann nicht am Ende die
vorherige Konfiguration überschrieben wird. Denke halt noch in
PIC-BIT-Schubser Varianten...
Hallo Moritz,
schönes Tutorium!
Ein vollständiges CoIDE-Projekt inklusive CAN-Transfer kann hier
heruntergeladen werden.
Da lädt leider nur das I2C DMA Projekt herunter.
Grüße
Jörg
Ja, das passt schon, das Beispielsprojekt bezieht sich auf Kapitel 22.
Zuerst werden über I2C zwei Bytes ausgelesen und anschließend per CAN
verschickt, so wie es im Screenshot des Logic Analyzers zu sehen ist. ;)
Hallo Moritz,
Vielen Dank für das STM32-Tutorial, ich bin sehr sehr dankbar, dass du
dir die Mühe gemacht hast, deine Erfahrungen anderen Usern einfach so
mitzuteilen.
Ich habe meinen Job gewechselt und bin jetzt in einem Technologiezentrum
tätig und habe ein Projekt mit dem STM32... bekommen. Nach anfänglicher
Panik beim Lesen der umfangreichen englischen Doku... bin ich jetzt viel
entspannter, denn dein Tutorial hilft ungemein, diesen Prozessor in
betrieb zu nehmen. Meine vorgeschriebene Entwicklungsumgebung ist von
IAR-Embedded Workbench. Weißt du zufällig Näheres zur Implementation der
Standard Peripheral Library? IAR hat dazu etwas veröffentlicht, aber der
Link funktioniert nicht.
Eine große Bitte: arbeite weiter an diesem Projekt und lasse das
Tutorial noch lange online, es wird sicher noch vielen verzweifelten
Entwicklern eine unschätzbare Hilfe sein!!!
Viele Grüsse von Kalle aus dem Allgäu
Hi Moritz,
danke für diese umfangreiche tolle Arbeit und für Deinen Aufwand das
alles so gut aufzubereiten. Ich hab seit Monaten ein STM32F4-Discovery
rumliegen
http://shop.myavr.com/Top%20Sellers/STM32F4-Discovery.htm?sp=article.sp.php&artID=200072
und traue mich nicht dran. Besonders weil ich a) keine Peil habe wo
anzufangen und b) mir schon der eine oder andere ARM-Programmierer
abgeraten hatte ("... VIEL komplexer als AVRmega ...")
Frage: glaubst (oder weißt) Du, ob Dein Tutorial auch für STM32F4 geht?
Also STM32F407VGT6 32 Bit ARM Cortex-M4F.
@Kalle
Danke für dein Feedback, leider hab ich mit IAR bisher noch keine
Erfahrung.
Keine Angst ich habe in nächster Zeit nicht vor die Website offline zu
nehmen, ich komme nur momentan nicht dazu weiter daran zu arbeiten.
@Walter
a) Wenn du das Board sowieso schon rumliegen hast probier doch einfach
mal paar Dinge aus, wie z.B. eine LED blinken zu lassen. Von ST gibt es
sehr viele Code Beispiele, aus denen man sich das Meiste abschauen kann.
b) Komplexer ja, aber nicht wirklich komplizierter zu programmieren - es
ist eben anders. Bei AVRs bewegt man sich eher auf der
Register-/Bitebene, bei der Programmierung der STM32 ist es sinnvoller
die „Standard Peripherals Library“ zu benutzen um dann mehr in Richtung
Objektorientierung seinen Code zu schreiben. D.h. um seine Peripherie
einzustellen nimmt man eine Struktur, schreibt in deren Elemente die
Werte für die Peripherie und übergibt sie einer Funktion. Persönlich
finde ich das recht angenehm.
Wenn du das Prinzip von den STM32F1 verstanden hast, lassen sich die
Beispiele ganz gut auch auf die STM32F4 anpassen. Die Strukturen sind
dort in vielen Fällen nicht identisch und haben i.d.R. mehr Elemente -
weil die F4 eben mehr können. Zur ST-Lib gibt es eine Dokumentation in
der alle Funktionen und Stukturen beschrieben sind. Zusammen mit den
Code Beispielen von ST solltest du meine Beispiele recht schnell
anpassen können. Also: Einfach loslegen und nicht zu schnell aufgeben,
dann klappt das schon. ;)
Moritz Diller schrieb:> ...> a) Wenn du das Board sowieso schon rumliegen hast probier doch einfach> mal paar Dinge aus, wie z.B. eine LED blinken zu lassen
Vielen Dank für die Aufmunterung! Werd ich mal angehen. Da wird mir
sicher erstmal Dein Tutorial helfen (müssen). Hat ja schon geholfen,
weil ich bis heute dachte, dass ich auch noch nen ST-LINK/V2 dazu kaufen
müsste. Aber im Datenblatt hab ich eben gelesen:
... and includes an ST-LINK/V2 embedded debug tool interface ...
Also wirds wohl ein interessantes Wochenende - wo eh das Wetter nicht
viel outdoor verspricht.
Walter Jo schrieb:> und traue mich nicht dran. Besonders weil ich a) keine Peil habe wo> anzufangen und b) mir schon der eine oder andere ARM-Programmierer> abgeraten hatte ("... VIEL komplexer als AVRmega ...")>> Frage: glaubst (oder weißt) Du, ob Dein Tutorial auch für STM32F4 geht?> Also STM32F407VGT6 32 Bit ARM Cortex-M4F.
Also ich habe mein F4-Discovery auch mit dem Tutorial + ein paar andere
im Internet ohne grössere Probleme in 30min zum ersten mahl am laufen
gehabt.
Der einzige RIESIGE Unterschied ist die Abrstaktion. Beim AVR hast du
dich noch mit den Datenblättern bemüht, sollange es simple Anwendungen
sind, brauchst du nur die std_periph_lib und du hast deine ersten
Erfolge.
Nur Mut, das Ding geht nicht kapput.
Patrick B. schrieb:> Der einzige RIESIGE Unterschied ist die Abrstaktion. Beim AVR hast du> dich noch mit den Datenblättern bemüht, sollange es simple Anwendungen> sind, brauchst du nur die std_periph_lib und du hast deine ersten> Erfolge.
Das liegt aber nur daran, dass ST selber die abstrakte Library auf ihrer
Website hat. Für die AVR's gibts auch 1000e Libraries zur Abstraktion
der Hardware, nur eben nicht auf atmel.com . Außerdem sind die ST
Libraries nur spärlich dokumentiert, ohne Studium der Datenblätter ist
deren Benutzung nicht gerade offensichtlich. Dabei hilft die "Qualität"
der ST Datenblätter natürlich ungemein...
Walter Jo schrieb:> Hi Moritz,>> danke für diese umfangreiche tolle Arbeit und für Deinen Aufwand das> alles so gut aufzubereiten. Ich hab seit Monaten ein STM32F4-Discovery> rumliegen> http://shop.myavr.com/Top%20Sellers/STM32F4-Discovery.htm?sp=article.sp.php&artID=200072> und traue mich nicht dran. Besonders weil ich a) keine Peil habe wo> anzufangen und b) mir schon der eine oder andere ARM-Programmierer> abgeraten hatte ("... VIEL komplexer als AVRmega ...")>> Frage: glaubst (oder weißt) Du, ob Dein Tutorial auch für STM32F4 geht?> Also STM32F407VGT6 32 Bit ARM Cortex-M4F.http://www.mySTM32.de ;-)
für wirklich blutige Anfänger ist ein AVR aber schon verständlicher.
Gruß J.
Hallo Moritz,
Danke dir für das coole Tutorium. Ich habe erst jetzt dein Tut gesehen
da ich bis vor kurzem von der STM32 nicht gehört habe. Gestern ist ein
Kumpel mit einem Entwicklungs Board gekommen und hat mich in staunen
versetzt. Bis jetzt habe ich auch nur was mit AVR gemacht. Seit einem
Monat mache ich was an einer DSP rum. Tms320F2808. Da meine Applikation
immer grösser wird ueberlege ich gerade die F2808 durch eine F2810 zu
ersetzen. Ich habe hier auch mal die Frage gestellt wie kompliziert wird
der Code um Programmierung. Seit ich jetzt die ARM entdeckt habe bin ich
so was von nicht mehr sicher was ich machen soll. Kannst du mir mal
bitte sagen, wie schwer der Wechsel von AVR auf STM32 ist. Was sind die
Vorteile? Ist ausreichend Material vorhanden? How about du gibst mir
deine Mail, ich sende dir mal paar Code Ausschnitte und du sagst mir ist
das möglich oder wird das nichts?
Danka Danke
Da sind mir die beiden Zeilen mit FilterMaskIdHigh und FiltermaskIdLow
nicht ganz klar.
Beide sind laut stm32f10x_can.h vom Typ uint16_t, wenn ich jetzt 0xFE0
<< 5 zuweise (bei FilterMaskIdHigh) passt das nicht mehr in uint16_t,
gleiches gilt für die andere Maske. Warum die Masken eigentlich 5 Bits
nach links shiften? Habe versucht das laut RM0008 (Seite 640)
nachzuvollziehen, habe aber nichts gefunden - oder ich habs übersehen.
André
Hallo André,
das mit den Filtern ist in der Tat etwas umständlich, hab auch ne Weile
gebraucht, das zu checken und mir ist auch bis heute nicht ganz klar,
warum das in der ST Lib auf zwei 16-Bit Strukturelemente anstatt ein
32-Bit Element aufgeteilt wurde. Die Bezeichnungen IdHigh und IdLow sind
ebenfalls sehr irreführend.
Standard IDs haben 11 Bit, also ist der maximal mögliche Wert 0x7FF.
Schiebt man den um 5 Bit nach links, so passt das noch in eine uint16_t
Variable. Bei Extended sind es 29 Bit, diese werden um 3 nach links
geshiftet und passen deshalb ebenfalls in eine 32 Bit Variable (bzw.
zwei zusammengesetzt 16 Bit Variablen).
Warum muss man eigentlich shiften? -> Auf Seite 640 (RM0008) warst du
schon richtig, in Figure 229 ist angegeben, wie die IDs in den Registern
gespeichert werden.
Schauen wir uns dort zunächst mal die Variante "Two 16-Bit Filter -
Identifier Mask" an: Die STID ist dort linksbündig im Register
gespeichert. In Variablen speichert mal aber Daten rechtsbündig, also
z.B. bei der Anweisung x = 123; Um in die linksbündige Variante zu
kommen müssen die Bits einfach um 5 nach links geschoben werden.
Bei Extended IDs sind die oberen 11 Bits die Bits des Standard ID Feldes
im Frame, nur werden zusätzlich später im Frame noch 18 weitere Bits für
die unteren Bits der ID gesendet. -> z.B. Variante "One 32-Bit Filter -
Identifier Mask" ist ebenfalls linksbündig, bei 32 - 29 = 3 muss also um
3 nach links geschoben werden.
So, ich hoffe damit sind alle Unklarheiten beseitigt. Viel Spaß
weiterhin. ;)
Schöne Grüße
Moritz
Hallo,
erstmal ein dickes Danke für das Tutorial. Erste Sahne. :)
Ich habe durch das Tutorial die Tage schon ein paar LED's zum Blinken
gebracht. Jetzt wollte ich mich an die Timer machen. Dazu habe ich
einfach mal das erste Timer-Beispiel kopiert und es läuft. :)
Dann habe ich gemessen, aber irgendwie stimmen meine Werte nicht mit
denen aus dem Tutorial überein. Meine sind um den Faktor 9 bis 10 zu
groß. Habe dazu mal einen Screenshot angehängt. Als Board nutze ich ein
STM32 Nucleo F103RB.
Was könnte ich falsch machen?
Viele Grüße,
Sebastian
Sebastian schrieb:> Ich habe durch das Tutorial die Tage schon ein paar LED's zum Blinken
Klasse. Mit AVR hättest das in ner Stunde hingekriegt.
> einfach mal das erste Timer-Beispiel kopiert und es läuft. :)
Kopieren kann ja jeder.
> Dann habe ich gemessen, aber irgendwie stimmen meine Werte nicht
Der Teufel liegt eben im Detail.Bzw. in zu vielen davon. Nimm AVR und
gut ist. Langt eigentlich immer.
@Sebastian
Da die Periodendauer von deinem Ausgangssignal ziemlich genau um den
Faktor 9 größer ist, vermute ich, dass dein Prozessor mit 8 MHz anstatt
den 72 MHz läuft, für die die Werte im Beispiel berechnet sind. Schau
mal in die Datei "system_stm32f10x.c", dort sollte das Define
"SYSCLK_FREQ_72MHz" nicht auskommentiert sein, alle anderen fünf dagegen
schon.
Wenn du's genauer wissen möchtest les dir das Kapitel 7.2 im Reference
Manual RM0008 durch. Der Clock Tree in Figure 8 ist am Anfang vielleicht
etwas verwirrend, aber wenn man ihn dann verstanden hat kann man daraus
sehr gut ablesen, wie man alle Optionen für die Taktversorgung
einstellen muss. Für den Anfang sollten aber die vorgefertigten
Funktionen in system_stm32f10x.c ausreichen. ;)
@Moby
Du solltest dich echt mal fragen, was in deinem Leben schief läuft, wenn
du dir Nachts Threads zu STM32 Controllern durchliest nur um dann
nutzlos rumzuhaten warum man lieber was anderes nehmen soll. Wenn du mit
"moderneren" Mikrocontrollern als deinen AVRs nicht klar kommst, dann
ist das OK, aber geh bitte anderen deswegen nicht auf die Nerven. Es ist
manchmal besser nicht von sich auf die Allgemeinheit zu schließen, vor
allem wenn es darum geht was man kann oder eben nicht kann!
Hey,
danke für die schnelle Antwort. Moby ignoriere ich einfach mal. :)
Also ich habe das Projekt mit der CooCox IDE erstellt, dann die
entsprechenden Komponenten gewählt und sonst nichts verändert. Die von
dir angesprochene Zeile ist (leider) nicht auskommentiert und ich habe
mal einen Breakpoint in die SetSysClockTo72-Funktion gesetzt und diese
wird auch aufgerufen.
Habe dann einfach mal nacheinander die jeweiligen Frequenzen ein und
auskommentiert: Die Messwerte ändern sich lustigerweise gar nicht. Was
mache ich nur falsch?
Viele Grüße,
Sebastian
Hm, ich seh gerade, dass der Quarz auf dem Nucleo Board standardmäßig
nicht bestückt ist. Die PLL lässt sich aber nur mit einer externen
Taktquelle, nicht mit dem internen 8 MHz RC Oszillator nutzen.
Oder hast du bereits einen Quarz aufgelötet? Wenn ja, dann mal mit dem
Oszi messen, ob er auch schwingt.
Hm, ich kann dir gerade nicht ganz folgen. :) Sind meine ersten
Erfahrungen mit einem Mikrocontroller. Komme auch eher aus der
Java-Ecke.
Also einen Quarz habe ich nicht angelötet. Was bedeutet das jetzt für
mich? Das der Mikrocontroller immer nur mit den 8MHZ laufen wird,
solange ich keinen Quarz anlöte?
Viele Grüße,
Sebastian
OK, alles klar.^^ Also was ein Quarz ist und macht steht z.B. hier:
Schwingquarz
Will man höhere Frquenzen als ca. 25 MHz erzeugen benutzt man
üblicherweise eine PLL
(http://de.wikipedia.org/wiki/Phasenregelschleife#Frequenzsynthese).
Damit kann der Takt "hochmultipliziert" werden.
Aber zurück zum Thema, den internen Taktgenerator kann man nur direkt
benutzen oder noch weiter herunter teilen. Abgesehen davon ist er auch
nicht besonders genau. Also für Frequenzen größer als 8 MHz musst du X3,
C33, C34, R35 und R37 auf der Platine bestücken.
Mit dem internen RC-Oszillator (8MHz) vom STM32F103 kann man mittels PLL
auch nur 64MHz erzeugen, keine 72MHz.
Wenn man USB nutzen möchte, dann sollte die CPU mit 48MHz oder 72MHz
getaktet sein.
Erst beim STM32F2xx / F4xx sind mehrere PLL's im Chip und man kann die
Clock's flexibler gestalten.
Moritz Diller schrieb:> nutzlos rumzuhaten
Nö. Manch einer spart mit so einem dezenten Hinweis vielleicht viel
Zeit, Geld und Energie- fürs gleiche Ergebnis wohlgemerkt ;-)
Hey,
darf ich noch eine Frage stellen? Ich habe mir die Wikipedia Artikel mal
durchgelesen, schlauer bin ich nun aber nicht. :(
Ich habe mir jetzt selber auf Basis der 8MHZ die passenden Parameter
errechnet und damit ein PWM-Signal für Servos erzeugt. Klappt
einwandfrei.
Wie kann ich denn nun höhere Taktfrequenzen benutzen? Nach den letzten
Beiträgen scheint das ja doch zu gehen. Ich könnte in das Reference
Manual schauen, allerdings wüsste ich nicht, wonach ich überhaupt suchen
muss. Will es mir vielleicht jemand von euch verraten? ;)
OK, zunächst mal kurz ganz grob die Funktionsweise einer PLL:
Takte runterzuteilen ist recht einfach. Will man einen Takt
beispielsweise durch 8 teilen kann man einen 4 Stufigen Binärzähler
nehmen und das letzte Bit als Ausgangssignal benutzen.
Takte vervielfachen geht aber nicht ganz so einfach. Bei einer PLL
verwendet man zunächst einen "billigen" Oszillator, dessen Frequenz über
eine Spannung verstellt werden kann (VCO). Soll nun ein vorgegebener
Takt z.B. verdoppelt werden, so stellt man den VCO "ungfähr" auf die
gewünschte Frequenz ein, teilt diese durch zwei und vergleicht sie mit
dem Referenztakt. Genauer gesagt werden die Phasen miteinander
verglichen. Die PLL regelt den VCO nun so aus, dass der Originaltakt und
der halbierte Takt des VCO übereinstimmen. Folglich liegt am Ausgang des
VCO exakt die doppelte Frequenz des Referenztakts an.
Für die Einstellungen im STM32 schaust du dir am besten den Clock Tree
(Seite 90 RM0008) an. Es muss der Schalter PLLSRC auf den oberen Pfad
gestellt werden, PLLMUL auf den gewünschten Faktor und SW auf PLLCLK.
Am einfachsten passt du die Funktion "SetSysClockTo72" in
"system_stm32f10x.c" an.
Die erste Zeile löscht alle relevanten Bits im CFGR Register, in der
unteren werden dann die neuen Werte gesetzt. Was es für Werte gibt und
was sie bewirken ist auf Seite 98 bis 100 beschrieben.
In deinem Fall muss "RCC_CFGR_PLLSRC_HSE" durch
"RCC_CFGR_PLLSRC_HSI_Div2" ersetzt werden. Könnte man auch weg lassen,
da das Define 0 ist, aber so ist der Code danach verständlicher. Der PLL
Faktor kann maximal auf 16 gesetzt werden ("RCC_CFGR_PLLMULL16").
Hab's selbst nicht ausprobiert, ich hoffe das war soweit alles was nötig
ist. ;)
Wegen Deinen PWM Servos, Die Timer haben alle einen Prescaler. Wenn der
CPU Takt statt 8MHz nun 72MHz ist (9x mehr) so erhöht man den Prescaler
um den entsprechenden Wert.
Wenn die PLL auf mehr als 36MHz gestellt wird, so muss der Bus APB1 auf
den halben CPU Takt eingestellt werden. Entsprechend sind die Prescaler
nur halb zu erhöhen (4,5 bei 72MHz), der Peripheriemodule die da dran
hängen.
Siehe z.B. CPU Schaubild im Artikel STM32
Für die Timer an APB1 gilt allerdings, dass deren Eingangstakt nochmals
verdoppelt wird, falls APB1 Prescaler != 1 ist.
In SetSysClockTo72 ist der APB1 Prescaler 2, also sieht der Timer
effektiv wieder den AHB Takt.
Hallo,
auch von mir ein Lob für das Tutorial.
Ich habe ebenso wie Sebastian ein paar Sachen durchprobiert und versuche
jetzt gerade zu verstehen wie das PWM Signal mit PA0 verknüpft ist, bzw.
wie ich es auf einen andern Port/Pin legen kann.
Bitte um Hilfe.
Vielen Dank im Voraus schonmal :)
Grüße Ruven.
Code aus dem Tutorial:
R. D. schrieb:> PWM Signal mit PA0 verknüpft ist, bzw.> wie ich es auf einen andern Port/Pin legen kann.
Als erstes nimmst du dir das Datenblatt und schaust auf die Seite
Pinouts and pin description , nicht jeder Pin kann alles;) Dort
erfaehrst du auch welchen Timer du für den jeweiligen Pin verwenden
musst.
In der InitStructure fuer den GPIO, den GPIO Pin aendern. Anschließend
wird diese Struktur dem Port uebergeben -> Port aendern. Der Timer muss
auch entsprechend angepasst werden... Achte darauf, dass die Clocks fuer
den Port und den Timer aktiviert sind. Alles kein Hexenwerk :D
Gruß
Hallo,
müsste im Abschnitt CAN nicht das Wort "nicht" gestrichen werden:?
"Mask gibt an, welche Bits in ID nicht zur Filterung berücksichtigt
werden?"
Es heißt im Reference Manual:
"0: Don’t care, the bit is not used for the comparison
1: Must match, the bit of the incoming identifier must have the same
level has specified in the corresponding identifier register of the
filter."
Gruß Martin
Hallo Moritz,
Vielen Dank für dieses wirklich unglaublich tolle Tutorial!
Kurz und knackig erklärt was man alles tun muss, um irgendetwas zum
laufen zu bringen. Ist ja grundsätzlich nicht so schwer, aber nach x
Microcontrollern und ebensovielen SPI (etc.) Initialisierungen ists mir
mittlerweile schon mühsam mich dafür zu begeistern.
Ich will einfach, dass es läuft... :D
Und mit deinem Tutorial gehts wirklich schnell. Außerdem deckt es alle
wichtigen Standardmodule ab. Das macht es für mich zum Nachschlagewerk
Nr. 1 beim STM32 was Codebeispiele anbelangt.
Vielen Dank. Du hast mir wertvolle Zeit erspart!
lg
Helmut
Hi,
sorry das ich den Fred nochmal aufleben lasse ;P Aber ich hab gelesen
das ihr auch das Nucleo Board benutzt und wohl auch schon einen Externen
Quarz aufgelötet habt... meine Frage ist nun wozu die Widerstaende R35
und R37 denn genau sein sollen. In allen Beispielverdrahtungen sind
diese Widerstaende nicht gegeben sondern nur die Kondensatoren die ich
mit 22pF Dimensioniert habe mit einem 8MHz Quarz. Kann ich die
Widerstaende einfach mit 0Ohm Brücken setzen oder wie komm ich auf die
passenden Werte? Im Datenblatt des F103, so wies in der Beschreibung vom
Nucleo steht, finde ich leider nichts oder übersehe die Stelle.
Vielleicht kann mich diesbezüglich ja mal jemand aufklären :)
Gruß Michael
Hi Michael,
die Widerstände kannst du nach Application Note AN2867 auslegen. Der an
OSC_IN wird mit 0R bestückt, der andere liegt irgendwo in der Gegend von
1...1,5kR und begrenzt den Strom, welcher in den Quarz fließt. Der Wert
ist nicht wirklich kritisch, aber wenn du doch merken solltest, dass
dein Quarz komische Sachen macht, würde ich den Wert nochmal genauer
nachrechnen. ;)
Hallo zusammen und vielen Dank für das gute Tutorial,
ich habe nun basierend auf dem Tutorial mein komplettes Projekt
aufgezogen und nun geht es an den RS485. Leider weniger erfolgreich. Ich
habe fertige Hardware (STM32F1x mit 8MHz Quarz) die nun mit neuer
Software bespielt werden soll. Mein Transceiver (ISL83072EIBZA) ist wie
folgt beschaltet TX = (Pin78 – PC10), RX = (Pin79 – PC11), EN = (Pin80–
PC12), jedoch habe ich Probleme den Beispielcode auf diese Beschaltung
umzuschreiben. Zumindest spuckt der Transceiver keine Frames aus, was
wohl mit sehr hoher Wahrscheinlichkeit an der fehlerhaften
Hardwarekonfiguration liegen sollte.
Ich wäre für jeden Tipp dankbar :)
Gruß Frank
Hallo Frank,
hast du schon am TX-Pin gemessen um auszuschließen, dass es am
Transceiver liegt?
Wird UART4 oder USART3 genutzt? Bei letzterem müsste die Remap-Funktion
aufgerufen werden.
Evtl. wurde der falsche DMA Channel oder Controller konfiguriert.
Am besten wäre es, wenn du deinen Code postest, das wären jetzt nur
allgemein ein paar Punkte die ich als erstes überprüfen würde.
Gruß Moritz
Hallo Moritz,
laut STM32 Anleitung passt die Beschaltung zum "PartialRemap", ich bin
mir nur unsicher wann ich die passende Funktion dafür durchführen muss,
die geschieht im aktuellen Code vor der Aktivierung von USART3. Laut
STM32 Anleitung wird auf diesen Pins USART3 verwendet und DMA1 Channel 2
für TX und Ch 3 für RX benötigt. Ich habe versucht den Code anzupassen,
hat jedoch leider nicht zum Erfolg geführt. Die Hardware ist komplett
Funktionstüchtig und hat zuvor noch mit alter Software funktioniert. Ich
werde sofort noch mal TX und EN messen.
Schon mal vielen Dank im vorraus.
Mein Code befindet sich in der abgehangenen Datei...
Noch eine Frage zum Verständnis, wann würdest du genau die Funktionen
USARTx_IRQHandler und DMA1_Channelx_IRQHandler ausführe? Wie kann ich
sicherstellen, dass die Kommunikation auch abgeschlossen ist, bevor ich
den EN wieder deaktiviere...
Der Code Funktioniert nun bei mir. Zumindest kann ich mit dem
Oszilloskop hinter dem Transceiver die gesendeten Frames messen.
Jetzt stellt sich für mich halt nur noch die Verständnisfrage, wie ich
erkennen kann, dass alle Daten versendet wurden und ich mit
USART3_IRQHandler();
Wieder in den Empfangsmodus wechseln kann.
USART3_IRQHandler wird beim "Transmission Complete" Event aufgerufen,
also wenn alle 6 Bytes aus usart_transmit_array gesendet wurden. Du
musst in deinem Code noch zwei mal "USART2" durch "USART3" ersetzen.
Der Empfangsmodus ist von Anfang an aktiv, aber da beim Transceiver das
Empfangen zunächst deaktiviert ist, empfängt die USART Peripherie erst
Bytes, nachdem der DE-Pin auf low geschaltet ist. In GPIO_WriteBit
sollten die Parameter noch entsprechend angepasst werden. ;)
Hallo Moritz,
erstmal danke für deine Hilfe.
Ich bin schon die ganze Zeit am tüfteln, aber totaler Neuling was den
Umgang mit DMA / IRQ betrifft.
Ich habe nun noch mal den aktuellen Code angehangen. Dieser entspricht
eigentlich komplett deinem Beispiel, abgesehen von remapping. Das
Problem ist, dass wohl irgendwas mit dem DMA / IRQ Handling nicht
funktioniert. Immer wenn ich Daten (z.B. 3Byte) mit der „RS485_Trasmit“
Funktion versende, werden diese direkt wieder rückgelesen und stehen
dann im definierten Rx Datenbereich
Ebenfalls werden diese 3 Byte von Counter des DMA1_Channel3 gezählt.
Wenn ich
1
DMA_GetCurrDataCounter(DMA1_Channel3);
aufrufe kann ich nachvollziehen das genau um 3 Byte gezählt wurde.
Hast du einen Tipp, wie ich das Rückleseproblem in den Griff bekommen
kann?
Gruß
Frank
Ist die Receive-Enable Leitung des ISL83072EIBZA mit Drive-Enable
verbunden oder liegt der Pin dauerhaft auf GND? In letzterem Fall würde
der Transceiver während des Sendens das TX Signal auf die RX Leitung am
µC weiterleiten.
Also wenn dieser Uralt-Thread eh nochmal hoch gekommen ist:
@Moritz Diller: Vielen Dank für das tolle Tutorial!
Da die STM32F1xx - aus China bestellt - unheimlich billig sind, mache
ich inzwischen fast alles mit denen und Deinem Tutorial!
Hi,
erstmal vielen Dank für das Tutorial. Ich lese es ab und zu, um meine
erste Schritte in der ARM-Welt bewegen zu können.
Ich habe dennoch ein paar Frage, die ich noch nicht beantworten konnte:
1) Die Funktion:
1
void USART2_IRQHandler(void){
2
USART_ClearITPendingBit(USART2, USART_IT_TC);
3
GPIO_WriteBit(GPIOA, GPIO_Pin_0, RESET); // DE Pin low
4
}
wird als
1
USART2_IRQHandler
deklariert. Ok. Diese ist aber die einzige Definition und Deklaration,
die ich in den Dateien finden konnte. Diese Funktion wird nicht mal in
den Standard Peripheral Libraries erwähnt. Wie kann der Interrupt
wissen, dass er genau diese Funktion aufrufen muss, wenn er getriggert
wird? Sucht der Kompiler nach dem String "Handler" in den Namen der
Funktionen? Wo sind die Funktionen, die vom Interrupt aufgerufen werden,
definiert?
2) Ab und zu stoße ich in solche vordefinierte Registernamen:
1
USART_IT_RXNE
. Diese sind zwar in einer Datei vordefiniert, dennoch gibt es keinen
Kommentar oder ausführliche Erklärung. Und diese werden in keinem
Reference Manual oder Ähnliches erklärt. Woher weiß man, was für eine
Funktion diese vordefinierten erfüllen? Es gibt eine ganze Menge:
1
/** @defgroup USART_Interrupt_definition
2
* @{
3
*/
4
5
#define USART_IT_PE ((uint16_t)0x0028)
6
#define USART_IT_TXE ((uint16_t)0x0727)
7
#define USART_IT_TC ((uint16_t)0x0626)
8
#define USART_IT_RXNE ((uint16_t)0x0525)
9
#define USART_IT_ORE_RX ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */
10
#define USART_IT_IDLE ((uint16_t)0x0424)
11
#define USART_IT_LBD ((uint16_t)0x0846)
12
#define USART_IT_CTS ((uint16_t)0x096A)
13
#define USART_IT_ERR ((uint16_t)0x0060)
14
#define USART_IT_ORE_ER ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */
Dave A. schrieb:> Sucht der Kompiler nach dem String "Handler" in den Namen der> Funktionen?
Nette Idee, aber so geht das natürlich nicht. Eigentlich ist die Idee
hinter "Weak" ein Stück weit, dass Du Dir darüber keine Gedanken machen
musst. Du willst offenbar tiefer einsteigen.
> Wo sind die Funktionen, die vom Interrupt aufgerufen werden definiert?
In startup*.c stehen die Namen, die - wenn Du so willst - automatisch
(ohne "Handler"-in-den-Namen) erkannt werden. Es sind aber alle mit
"Handler".
Dave A. schrieb:> 2) Ab und zu stoße ich in solche vordefinierte Registernamen:>
1
USART_IT_RXNE
. Diese sind zwar in einer Datei vordefiniert,
> dennoch gibt es keinen Kommentar oder ausführliche Erklärung. Und diese> werden in keinem Reference Manual oder Ähnliches erklärt. Woher weiß> man, was für eine Funktion diese vordefinierten erfüllen? Es gibt eine> ganze Menge:>
1
> /** @defgroup USART_Interrupt_definition
2
> * @{
3
> */
4
>
5
> #define USART_IT_PE ((uint16_t)0x0028)
6
> #define USART_IT_TXE ((uint16_t)0x0727)
7
> #define USART_IT_TC ((uint16_t)0x0626)
8
> #define USART_IT_RXNE ((uint16_t)0x0525)
9
> #define USART_IT_ORE_RX ((uint16_t)0x0325) /* In
10
> case interrupt is generated if the RXNEIE bit is set */
11
> #define USART_IT_IDLE ((uint16_t)0x0424)
12
> #define USART_IT_LBD ((uint16_t)0x0846)
13
> #define USART_IT_CTS ((uint16_t)0x096A)
14
> #define USART_IT_ERR ((uint16_t)0x0060)
15
> #define USART_IT_ORE_ER ((uint16_t)0x0360) /* In
16
> case interrupt is generated if the EIE bit is set */
17
> #define USART_IT_NE ((uint16_t)0x0260)
18
> #define USART_IT_FE ((uint16_t)0x0160)
19
>
>> Danke!
Die stehen alle im reference manual, du darfst die nur nicht
wortwörtlich suchen.
Z.B. USART_IT_RXNE findet sich im USART status register, reference
manual S.998 des STM32F405
Normalerweise ist es eher umgekehrt, dass es Registeradressen gibt, die
ST nicht definiert hat. ;)
Moritz D. schrieb:> Hallo,>> ich habe in letzter Zeit ein kleines Tutorial über STM32 Mikrocontroller> geschrieben und dachte, dass sich hier ein paar Leute dafür> interessieren könnten:>> http://diller-technologies.de/stm32.html
Danke für das Tutorial!
Ich habe genau so etwas zur Einarbeitung gesucht.
Frank schrieb:> Hat jemand noch einen Link mit kurzem Beispiel für die Implementierung> des USB für den STM32?
Nicht kurz, aber vollständig ;-)
USB-Tutorial mit STM32