Forum: Projekte & Code STM32F103C8 Platformprojekt mit Display, FATFS und Examples


von Dieter B. (nichtgedacht)


Lesenswert?

Hallo

ich habe hier https://github.com/nichtgedacht/mini-sys ein komplettes 
Projekt für OpenSTM32 System Workbench (http://www.openstm32.org) hin 
gelegt.

Das Projekt lässt sich auf Knopfdruck installieren und ist für mich die 
Grundlage für alles weitere. Der original Code für das LCD stammt wie 
der übrige hinzugefügte Code aus den Firmware Repos von STM für den 
STM32F4xx und den STM32F1xx. Diesen Code habe ich stark verbessert, so 
dass man 1. Display beliebig drehen kann und 2. mehr der Chip vom 
Display die Arbeit macht. Da der initiale Code mit CubeMX erzeugt wurde, 
kann man damit auch weiterhin die Konfiguration verändern. Dieses Tool 
und die IDE sind auch für Linux erhältlich und beide sehr einfach zu 
installieren.

Als Hardware eignet sich eins diese billigen Boards "STM32 minimum 
development system" oder ein marple mini clone mit STM32F103C8 oder 
STM32F103CB und eins dieser ST7735 gesteuerten Displays mit 128x160 
Pixel und SD Karten Slot wie z.B das Teil von Adafruit oder ähnliche. 
Was man noch braucht sind ein paar Drähte eine Lochrasterplatte, 
Buchsenleisten und ein ST-Link V2 Debug Adapter, den man ebenfalls 
günstig bei ebay bekommt.

Gruß
Dieter

von Dieter B. (nichtgedacht)


Lesenswert?

Hallo

Auch wenn es wieder niemanden interessiert, jetzt mit MPU-9250 IMU.

Gruß
Dieter

von Mehmet K. (mkmk)


Lesenswert?

Dieter B. schrieb:
> Auch wenn es wieder niemanden interessiert

Das ist aus meiner Sicht so nicht zutreffend.
Aber ich sehe nicht ein, warum man sein Projekt auf einer anderen 
Webseite plaziert und es dann hier inseriert, obwohl dieses Forum all 
die dafür notwendigen Instrumente zur Verfügung stellt.
Ich an Deiner Stelle haette es hier im "Projekte & Code" vorgestellt. 
Oder das Ganze gleich im Wiki angesiedelt.

von Dieter B. (nichtgedacht)


Lesenswert?

Hallo Mehmet,

ich habe das Projekt ja eigentlich nur hier vorgestellt. Weil das Ganze 
ein OpenSTM32 System Workbench Projekt ist, und dort GIT integriert ist, 
nutze ich eben ein kostenloses öffentliches GIT Repo. Das gibt es hier 
bei mikrocontroller.net nicht, oder? Github ist für mich keine Webseite 
sondern ein leicht zugänglicher zentraler Speicherort.

Gruß
Dieter

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dieter B. schrieb:
> Das gibt es hier bei mikrocontroller.net nicht, oder?

Hier gibt es SVN und ein Wiki zur Dokumentation:

https://www.mikrocontroller.net/svn/list

von W.S. (Gast)


Lesenswert?

Dieter B. schrieb:
> Auch wenn es wieder niemanden interessiert, jetzt mit MPU-9250 IMU.

ich frag mich, wer und zu welchem Zwecke so etwas würde gebrauchen 
können. Mir fällt da rein garnichts ein. Bei deiner Dateipackung sucht 
man vergeblich nach irgend einem Anfang und einer Struktur.

Wozu hast du dir das denn so zusammenkopiert?

Also, was ganz sicherlich recht viele Leute gebrauchen könnten, wäre ein 
Projektrumpf, der einen echten Nutzen bringen würde.

Also angefangen bei einem sinnvoll designten Startupcode, weiter mit 
einem Konfigurations-Unit, wo man sich die Pinbelegung des Chips für 
seine konkrete Leiterplatte auf einigermaßen bequeme Weise definieren 
kann, die Pins damit aufgesetzt werden und der Takt eingerichtet wird. 
Weiter dann mit Peripherie-Treibern, die diesen Namen auch verdienen, 
Systemuhr, Utilities wie Konvertierungen und Event-System bis hin zu 
einem main, das zusammen mit dem anderen Zeug erstmal ein lauffähiges, 
modular konzipiertes System ergibt.

Das alles fehlt bei dir und stattdessen kommst du mit einer Orientierung 
auf irgend ein Board von Ebay und eine bestimmte IDE. Deshalb glaub ich 
nicht, daß dieses Projekt einen wirklichen Nutzen hat.

W.S.

von Dieter B. (nichtgedacht)


Lesenswert?

Hallo W.S.,

vielen Dank für Dein Feedback.

W.S. schrieb:
> Bei deiner Dateipackung sucht
> man vergeblich nach irgend einem Anfang und einer Struktur.

Was ist Dateipackung? Hast Du es laufen lassen und die Aufrufe verfolgt?

> Wozu hast du dir das denn so zusammenkopiert?

Ich habe vieles zusammenkopiert aber auch zusammen geklebt und 
weiterentwickelt. Vielleicht weil es Spaß gemacht hat?

> Also, was ganz sicherlich recht viele Leute gebrauchen könnten, wäre ein
> Projektrumpf, der einen echten Nutzen bringen würde.
>
> Also angefangen bei einem sinnvoll designten Startupcode,

Was ist unsinnvoll designt an der Initialisierung, oder was meinst Du
mit Startupcode?

> weiter mit
> einem Konfigurations-Unit, wo man sich die Pinbelegung des Chips für
> seine konkrete Leiterplatte auf einigermaßen bequeme Weise definieren
> kann, die Pins damit aufgesetzt werden und der Takt eingerichtet wird.

mini-sys/Drivers/BSP/STM32F1xx_MiniSys/stm32f1xx_minisys.h
mini-sys/mini-sys.pdf
CubeMX

> Weiter dann mit Peripherie-Treibern, die diesen Namen auch verdienen,

Ich habe fleißig abgekupfert aus den STM Firmware Repos. Aber das sind 
wahrscheinlich nicht so professionelle Coder. Ich habe den Code 
verbessert wo ich konnte, aber die Struktur beibehalten.

Als LCD Treiber für den ST7735 zusammen mit diesem Layer 
Grafikfunktionen habe ich nichts besseres für STM32 gefunden sonst hätte 
ich bestimmt von da kopiert ;-)

> Systemuhr, Utilities wie Konvertierungen und Event-System bis hin zu
> einem main, das zusammen mit dem anderen Zeug erstmal ein lauffähiges,
> modular konzipiertes System ergibt.

Das könnte noch daraus werden, Du machst mir ja Mut ;-)
Ich bin erst ein paar Wochen damit zu Gange und ein bischen mehr als 
Blinki Blinki ist es ja schon. Konkrete konstruktive Vorschläge sind 
immer willkommen.

> Das alles fehlt bei dir und stattdessen kommst du mit einer Orientierung
> auf irgend ein Board von Ebay und eine bestimmte IDE. Deshalb glaub ich
> nicht, daß dieses Projekt einen wirklichen Nutzen hat.

Nun, die Hardwarekosten beschränken sich dadurch auf < 20€ incl. 
Debugger Hardware und eine Stunde Löten. CubeMX und und OpenSTM32 System 
Workbench sind einfach auf jedem OS zu installieren, kostenlos und von 
STM supported. Man kommt dadurch ohne großen Aufwand in den Genuss einer 
Debugging Umgebung und HAL ist auch schon dabei. Gibt es einen Grund das 
selber zusammen zu basteln oder als Hobbyist eine IDE zu kaufen?

Gruß
Dieter

von W.S. (Gast)


Lesenswert?

Dieter B. schrieb:
> Was ist Dateipackung?

Ich habe den Versuch unternomme, mich möglichst dezent auszudrücken. Was 
ich bei dir sehe, ist zusammenkopiert und ohne Struktur. Ich kann auch 
stärkere Ausdrücke...

Dieter B. schrieb:
> Konkrete konstruktive Vorschläge sind immer willkommen.

Damit machst du weder dir noch mir nen Mut, denn ich sehe aus 
langjähriger Erfahrung, daß da ein Pensum vor dir liegt, was du noch 
nicht wirklich abschätzen kannst und was ich dir mal "so eben" auch 
nicht vermitteln kann, denn es ist umfänglich.

Dieter B. schrieb:
> Was ist unsinnvoll designt an der Initialisierung, oder was meinst Du
> mit Startupcode?

OK, fangen wir mal an mit dem ganz blutigen Anfang: Der Startupcode ist 
das, was bei den hier debattierten µC ab Adresse 0 zu stehen kommt und 
er sollte in Assembler geschrieben sein. Hat Gründe. Schau dir mal nen 
Startupcode deiner IDE an, das ist in 99.9% aller Fälle ein generischer 
mickriger Kram, neuerdings sogar in C (was ein nettes Linker-Thema 
ist..)

Und warum?
Weil er eben nur auf's Minimale geschrieben ist. Beispiele sind viele: 
alle Default-Ints und die System-Exceptions landen nur auf nem "B .", es 
gibt keinen Warmstart, kein Restart nach main oder Exceptions und so 
weiter.

Zur Initialisierung, die du offenbar mit dem Statup verwechselst, sollte 
man sich eine geeignete Vorlage in Form einer chipbezogenen config.c 
oder so machen, die man dann projektbezogen modifiziert (da ja die 
Pinverwendung von Projekt zu Projekt variiert).

Sowas nach Art der blutigen Anfänger in main zu tun und dabei nicht mal 
vor den ST-typischen Unsitten (XYZ_InitStructure..) zurückzuschrecken, 
ist ausgesprochen uneffektiv und verstopft main nur mit sowohl 
hardwarespezifischen als auch mit projektspezifischen Dingen, die man 
dort besser außen vorläßt.

Also was ich meine, ist z.B. eine config.c, die die Basis-Verwendung der 
Pins aufsetzt, die dafür benötigten Takte freischaltet, den Systemtakt 
aufsetzt und bei manchen µC eben auch den Bus nebst SDRAM initialisiert. 
Damit man in main ein bereits benutzbares System vorfindet - und damit 
man Dinge, die man per Debugger sowieso nur eher schlecht herausfindet, 
auch mal per Oszilloskop ansehen kann. Was machst du z.B. mit dem 
Debugger, wenn du den Systemtakt aufsetzen willst und nicht wirklich 
weißt, wie schnell dein gewählter PLL-Takt denn nun wirklich ist? geht 
nicht, dafür braucht's nen Oszi oder zumindest nen ausreichend schnellen 
LA.

Aber das ist nur ein winziges Detail vom Ganzen und nicht die 
Hauptsache.

Wichtiger sind Peripherie-Treiber, die diesen Namen auch verdienen.
Bei ST findest du so etwas nicht.
Wenn du in deren sogenannte "Treiber" schaust, dann findest du dort nur 
Umschreibungen ohne wirklichen Nutzinhalt, quasi heiße Luft - und die 
eigentliche Arbeit, einen echten Treiber draufzusetzen, bleibt dir am 
Hacken kleben.

Aber echte Treiber sollten die HW von der Benutzerschicht trennen. Ich 
geb dir mal ein Beispiel:
1
/* Liste der von aussen zu benutzenden Funktionen */
2
extern bool UsbRxAvail (void);    /* true, wenn Char's vom Host abholbar sind */
3
extern char UsbGetChar (void);    /* liest ein Char vom Host */
4
extern bool UsbTxReady (void);    /* true, wenn mindestens 1 Char gesendet werden kann */
5
extern bool UsbTxEmpty (void);    /* true, wenn der Sendepuffer total leer ist */
6
extern int  UsbTxFree  (void);    /* Anzahl freier Plätze im Sendepuffer */
7
extern char UsbCharOut (char c);  /* sendet ein Char zum Host */
8
extern void UsbStrOut  (char* S); /* sendet einen String zum Host */
9
extern word UsbSetup   (void);    /* Starten des USB-Cores */

Das ist die "usb.h" für einen virtuellen COM port. Wie du siehst, 
enthält sie keinerlei konkrete Hardware-Bezüge, sondern nur Zeugs, was 
man zum Benutzen des VCP's benötigt. Die innere HW-Bedienung, die gerade 
beim USB nicht simpel ist, bleibt komplett im Treiber, so daß man sich 
von außen darum nicht im Geringsten kümmern muß. Genauso geht es bei den 
echten seriellen Ports, siehe z.B.:
1
extern dword InitSerial1 (long baudrate);    /* liefert tatsächliche Baudrate zurück */
2
extern char  V24Char_Out1  (char c);         /* Zeichen senden */
3
extern int   V24numTxFree1 (void);           /* Anzahl freier Plätze im Sendepuffer */
4
extern bool  V24RxAvail1   (void);           /* ob Zeichen empfangen wurden */
5
extern char  V24GetChar1   (void);           /* empfangene Zeichen abholen */
6
extern void  V24TxDone1    (void);           /* warten bis Sendepuffer geleert ist */

und in gleicher Form für alle anderen seriellen Ports. Auch hier siehst 
du, daß die Treiber sämtlichen internen Kram erledigen, ohne daß man von 
der Benutzerseite sich hardwareabhängig machen muß. OK, die 
Entscheidung, ob und welche im konkreten Chip vorhandenen seriellen 
Ports man benutzen will und mit welcher Baudrate, bleibt einem noch.

Und jetzt vergleiche das mal mit dem ST-Zeigs in deinem 
zusammenkopierten Dingens. siehst du jetzt erste Unterschiede?

Mein Rat: lade dir mal die Lernbetty hier herunter und schau dort rein. 
Nee.. die ist erstens ausverkauft und zweitens inzwischen relativ alt, 
aber einige Grundprinzipien kannst du dort sehr gut erkennen. Bei der 
Lernbetty bin ich sogar so weit gegangen, daß ich die BettyBase quasi 
als Miniatur-Betriebssystem gestaltet habe, so daß man für eine konkrete 
Anwendung nur noch ein Applikationsprogramm schreiben mußte, ohne sih um 
die vielen Hardwareangelegenheiten kümmern zu müssen. So weit muß man 
das nicht treiben, aber das Prinzip, daß Peripherie-Treiber einen von 
einer konkreten HW entlasten sollen, bleibt. Gleiches gilt für den 
System-Setup oder Basis-Konfiguration (wie man's nennen will).

W.S.

von Dieter B. (nichtgedacht)


Lesenswert?

Hi

Alles was ich hier raus lese ist, dass die Entwicklungsumgebung AC6 
ebenso inakzeptabel ist, wie der von STM gelieferte Code. Da das Ganze 
aber beispielhaft zeigen soll, wie man mit CubeMX, AC6 und den 
Codebeispielen von STM schnell was bauen kann, trifft mich Deine Kritik 
wenig. Als ungeübter C HobbyCoder ist das Ergebnis vielleicht nicht 
lehrbuchhaft. Aber immerhin fliegt die Lochrasterplatte jetzt sehr schön 
als Quadrokopter. Sonst wäre ich vielleicht noch damit beschäftigt den 
Startupcode in Assembler zu schreiben.

Gruß
Dieter

von Sepp aus Hintertupfing (Gast)


Lesenswert?

W.S. schrieb:
> Ich kann auch
> stärkere Ausdrücke...

Das kann ich bestätigen ! :-(

von Holm T. (Gast)


Lesenswert?

...und einen Quatsch kann er erzählen..

SCNR;

Holm

von Micha (Gast)


Lesenswert?

W.S. schrieb:
> alle Default-Ints und die System-Exceptions landen nur auf nem "B .", es
> gibt keinen Warmstart, kein Restart nach main oder Exceptions und so
> weiter.

W.S. schrieb:
> Wichtiger sind Peripherie-Treiber, die diesen Namen auch verdienen.
> Bei ST findest du so etwas nicht.

Hast du Links zu Beispielen, die deiner Meinung nach gut gemacht sind?

von temp (Gast)


Lesenswert?

mbed

von W.S. (Gast)


Lesenswert?

Micha schrieb:
> Hast du Links zu Beispielen, die deiner Meinung nach gut gemacht sind?

Ich habe sowas in meinem persönlichen Portfolio. Ich habe sogar hie und 
da mal etwas davon hier gepostet. Also, warum fragst du?

W.S.

von grundschüler (Gast)


Lesenswert?

W.S. schrieb:
> Ich habe sowas in meinem persönlichen Portfolio. Ich habe sogar hie und
> da mal etwas davon hier gepostet. Also, warum fragst du?

Eine boardspezifische pinout-Datei, in der nur die verwendeten Ports und 
Pins angegeben werden und Macros für die i/o-Funktionen?
1
//avr specific
2
#if zucAVR
3
#define pinDIRin(x,y)       DDR(x)&=~(1<<y)
4
#define pinDIRout(x,y)      DDR(x)|=(1<<y)
5
#define pinVAL(x,y)        (PIN(x)&(1<<y))
6
#define pinPULLUP(x,y,z)   (z)?(PORT(x)|=(1<<y)):(PORT(x)&=~(1<<y))//0_no 
7
#endif

Hast du sowas für STM mit allgemeinem Bezug auf die STM-Register? Wäre 
ich sehr dran interessiert

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Gerade für die GPIO ist bei den diversen STM32Fxxx Reihen die Struktur 
der Port-Setup's derart unterschiedlich, daß man sich besser für jede 
Reihe seine dazu passende Strategie zum Aufsetzen ausbaldowert.

Solche Funktionen wie du sie dir vorstellst, sind da nicht drin, es sei 
denn, man grenzt sie auf eine ganz bestimmte Baureihe ein.

Was aber viel wichtiger ist, ist der Überblick darüber, was man denn an 
welchem Portpin so anliegen hat - und das sollte möglichst wenig 
Speicherplatz verbraten. Strategien dazu gibt es einige, ich hänge dir 
mal was zum Lesen hier dran.

Das erste Beispiel ist aus einem STM32F103 Projekt. Du findest dort als 
zentrale Einträge sowas wie
#define wf_PA0...
#define wf_PA1... usw.

Das zweite Beispiel ist aus einem STM32F3xx, dort sieht das gleiche 
Stück etwa so aus:
const word wfPortA[16] =
{ /* P.0  */   OUT,
  /* P.1  */   ALT + MedSpeed + AF1,

Der Grund für die Unterschiede sind die verschiedenen Port-Strukturen. 
Aber das alles ist Inhalt einer projektspezifischen 
Konfigurationsquelle, wo alle Portfunktionalität aufgesetzt wird, so daß 
man in den übergeordneten Schichten der Firmware nicht mit diesen Dingen 
hantieren muß. Wichtig ist hier, daß man den Überblick über die 
tatsächliche Verwendung behält.

Merke: Gerade bei allgemeinen Port-Pins ist ein Port-Pin-Treiber 
sinnlos. Die Verwendung der nackten Portpins sollte besser nur innerhalb 
von sinngebenden Anwendungs-Treiber erfolgen, also sowas zum Beispiel:
extern bool Handbremskontakt(void);
extern void RoteLampeEin(void);
extern void RoteLampeaus(void);
extern bool Sensor_vorn (void);
extern bool Sensor_hintenlinks  (void);
extern bool Sensor_hintenrechts (void);

Hier siehst du, daß es komplett im zugehörigen Treiber bleibt, über 
welche Pins und auf welche Art so ein Sensor oder Lampe oder Kontakt 
angeschlossen ist. Wichtig für das übergeordnete Programm ist lediglich, 
daß man eine Pin- und Controller-unabhängige Schnittstelle hat, worüber 
man deren Zustand abfragen kann. Ähnlih sieht das z.B. für eine serielle 
Schnittstelle aus:

extern dword InitSerial1 (long baudrate);
extern char  V24Char_Out1  (char c);
extern int   V24numTxFree1 (void);
extern bool  V24RxAvail1   (void);
extern char  V24GetChar1   (void);
extern void  V24TxDone1    (void);

Auch hier bleibt die gesamte Pufferung, der Interruptverkehr und die 
Setup-Details im Treiber, so daß das übergeordnete Programm sich darum 
nicht kümmern muß. Ja, es ist sogar egal, ob sich dahinter eine UART 
befindet oder z.B. ein USB-VCP.

W.S.

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.