Diese Library bindet die STemWin (in Version 5.22) ein (ohne OS).
“emWin” ist von SEGGER (www.segger.com) und ST hat für seine STM-Familie eine kostenlose vorkompilierte Library dazu veröffenlicht “STemWin”
Mit “STemWin” kann eine Windows ähnliche GUI programmiert werden mit Buttons, Fenstern usw.
Das ganze ist sehr Umfangreich und ich kann hier nicht jede Funktion erklären. Dazu gibt es viele Dokus im Internet u.a. auch von Segger und ST (einfach mal suchen).
Auf der Internet Seite von Segger gibt es auch viele Beispiel-Programme als “C-Files” für die einzelnen Funktionen die man direkt benutzen kann.
In meinem Beispiel sieht man die Init-Funktion (das ist nur eine Zeile) und danach wird ein Text und ein Button gezeichnet. Wenn man auf dem Button drückt, wird er gelöscht.
Ich habe alle notwendigen Librarys (LCD, TOUCH, SDRAM, I2C, SPI) in den emWIN-Ordner kopiert, weil ohne diese Files das ganze eh nicht läuft.
Ich hab auch ein “Show-Projekt” hochgeladen, mit dem original Demo von ST in dem man ziemlich viele Funktionen zu sehen bekommt.
Hinweis zum Landscape-Mode :
zum drehen von GUI+Touch habe ich die Funktion “UB_STemWIN_GUIRotate” geschrieben. Diese funktioniert aber nur, wenn der GUI genügend RAM zur Verfügung steht. Dazu muss das externe SDRAM benutzt werden. Um dieses zu aktivieren, muss im File “GUIConf.c” der Define “USE_SDRAM_AS_GUIMEM 1″ gesetzt werden. Dies führt allerdings dazu, das die GUI viel langsamer wird.
Zum vergleich :
mit internem RAM der CPU : 35.215.000 Pixel/sec (Portrait)
mit externem SDRAM : 1.375.000 Pixel/sec (Landscape)
Beispielbild :
Enumerationen :
1 2 3 4 5 6 | typedef enum { ROTATE_0 = 0, // Portrait ROTATE_90, // Landscape ROTATE_180, // Portrait ROTATE_270 // Landscape }STEMWIN_Rotate_t; |
Funktionen :
1 2 | ErrorStatus UB_STemWIN_init(void); // zum init und start von STemWin ErrorStatus UB_STemWIN_GUIRotate(STEMWIN_Rotate_t mode); // zum drehen der GUI |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | //-------------------------------------------------------------- // File : main.c // Datum : 09.12.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F429 // IDE : CooCox CoIDE 1.7.4 // GCC : 4.7 2012q4 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der STemWin-Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" // In Configuration diese Define hinzufügen : // "STM32F429_439xx" , "__ASSEMBLY__" , "USE_STDPERIPH_DRIVER" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_stemwin.h" int main(void) { BUTTON_Handle hButton; SystemInit(); // Quarz Einstellungen aktivieren // init und start von STemWin UB_STemWIN_init(); // Font einstellen GUI_SetFont(GUI_FONT_20F_ASCII); // Text ausgeben GUI_DispStringHCenterAt("Hello world!", 80, 20); // Button-Demo while(1) { GUI_SetFont(&GUI_Font8x16); GUI_DispStringHCenterAt("Click on button...", 160, 90); // Create the button hButton = BUTTON_Create(110, 110, 100, 40, GUI_ID_OK, WM_CF_SHOW); // Set the button text BUTTON_SetText(hButton, "Click me..."); // Let window manager handle the button while (GUI_WaitKey() != GUI_ID_OK); // Delete the button BUTTON_Delete(hButton); GUI_ClearRect(0, 50, 319, 239); GUI_Delay(1000); } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Hallo,
ich danke dir erst einmal recht herzlich für die vielen tollen Beispiele hier auf der Seite. Das einbinden der STemWin hab ich schon gesucht und bin hier endlich fündig geworden. Vielen vielen Dank dafür.
Eine frage hätte ich noch:
Ich benutze das STM32F429I-DISCO Board. Gibt es da eine Möglichkeit Dezimalzahlen oder Float um 90° zu drehen, sodass diese über die breite Seite angezeigt werden. In der Doku zu STemWin hab ich leider nur das für Text gesehen. Wenn es keine direkte Möglichkeit gibt, dann muss ich halt das ganze in Strings umwandeln und dann über Text ausgeben.
Danke dir.
sorry, wie schon geschrieben ich hab das über 1000 Seiten lange PDF zu “emWin” nicht durchgelesen, kann dir also nicht weiterhelfen.
Wie man Seiten mit dem GuiBuilder erstellt und einbindet hast du nicht zufällig probiert?
nein
das einbinden einer Gui ist einfach, nur die Interaktion wird kompliziert:
– erstelle eine Gui
– binde sie ins projekt ein “FramewinDLG.c”
– rufe die Funktion in der Main auf CreateFramewin();
ich habe dazu ein informatives Video gefunden.
Ist zwar nicht für die STemWin Version aber die sind ja fast gleich.
http://www.youtube.com/watch?v=stan5a_r6kg
Hallo Cortex – Einsteiger,
inzwischen habe ich es soweit hin bekommen. Jetzt würde ich gerne ein callback routine einfügen. (WM_SetCallback)
Will mir aber nicht recht gelingen.
Ich will damit z.B. das Datum anzeigen.
Bis du da schon weiter?
Es steht zwar auf der To-Do-Liste, habe aber erstmal an einem anderen Projekt zu knabbern. Für meine ersten kleinen Tests hatte ich den “Reaktionscode” direkt in die FramewinDLG reingeschrieben:
case WM_NOTIFICATION_RELEASED:
FRAMEWIN_SetClientColor(pMsg->hWin, GUI_RED);
break;
Hi Uwe,
vielen vielen Dank für die hervorragende Arbeit mit dem Landscape Mode.
Jetzt habe ich mit der GUI endlich ein Werkzeug nach dem ich schon seit Jahren suche.
Allerdings schießt durch das Drehen die Copile Time auf das Zehnfache in die Höhe
und die Binary Size steigt von 200k auf 600k, aber es funktioniert.
Besten Dank, Adolf
Glücklich bin ich mit der Lösung nicht, aber im Netz hab ich bis jetzt keine Alternative gefunden.
Man kann in der GUIDRV_stm32f429i_discovery.c
Zeile 155 und folgende GUIDRV_LIN_32 auf GUIDRV_LIN_OSX_32
das dreht zwar das ganze aber es entsteht völliges chaos auf dem display. Im Handbuch Seite 1036
Ich fand die alte GUI von ST eigentlich besser, zwar nicht so modern gestylt, dafür aber wesentlich einfache wenn man verschachtelte Menüs programmieren wollte.
Es gibt eine preiswerte GUI von microe, leider nur mit deren eigenen Compilern kompatible http://www.mikroe.com/visualtft/
Hallo,
erstmal vielen, vielen Dank für die super Library!
Gibt es eine Möglichkeit das ganze um FreeRTOS zu erweitern?
Ich hab nun schon einige Stunden versucht das hinzubekommen, aber es funktioniert nicht.
Nach allein FreeRTOS includes, angepasster config, etc. schaut meine main() so aus:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
SystemInit(); // Quarz Einstellungen aktivieren
/* Activate the use of memory device feature */
WM_SetCreateFlags(WM_CF_MEMDEV);
/* Create background task */
xTaskCreate(Background_Task,
(signed char const*)”BK_GND”,
Background_Task_STACK,
NULL,
Background_Task_PRIO,
&Task_Handle);
/* Create demo task */
xTaskCreate(Demo_Task,
(signed char const*)”GUI_DEMO”,
Demo_Task_STACK,
NULL,
Demo_Task_PRIO,
&Demo_Handle);
if( !Task_Handle && !Demo_Handle )
{
return 0;
}
/* Start the FreeRTOS scheduler */
vTaskStartScheduler();
Aber es ist, als würden die Tasks nicht gestartet werden.
Hast du eine Idee?
Vielen Dank!
Grüße
Markus
Hallo,
super Arbeit mit den Library’s funktionieren bei mir (unter Linux) alle wunderbar bis auf die STemWin Geschichte Hab nun extra mal ein Windoof XP unter VMWare aufgesetzt um die Library mal mit der CoIDE zu testen. Da liefs natuerlich alles wunderbar. Nun frage ich mich wo das Problem liegen kann? Ich hab in dieser CoIDE aber auch kein Makefile oder irgendwas aehnliches gefunden (Nichtmal die generierte binary %)). Da ich aber nur Streifen auf dem TFT sehe gehe ich mal davon aus das etwas mit dem Timing nicht stimmt!? (Wundert mich nur da deine LCD Librarys wunderbar funktionieren)
Liegt es eventuell dadran:
Diese zwei Files muessen auf 8MHz stehen
// “cmsis_boot/stm32f4xx.h”
// “cmsis_boot/system_stm32f4xx.c”
// In Configuration diese Define hinzufügen :
// “STM32F429_439xx” , “__ASSEMBLY__” , “USE_STDPERIPH_DRIVER”
Wo muss das 8MHz bzw 8000000 denn stehen!? HSE? Oder was? Und die defines?
Das erste ist klar.. hab ich direkt in der header file deklariert. Aber die anderen beiden!? Die STDPERIPH sind ja soweiso in meiner Makefile drin.
Vielleicht hast du oder jemand anderes ja noch einen Ansatz was ich probieren könnte Kann auch gerne mal mein bisherigen kram mal posten (Kommt drauf an ob noch jemand Linux nutzt ;P)
Gruß Michael
die zwei Files sind, wenn sie original von einem neuen CooCox-Projekt angelegt werden, für einen 25MHz Quarz ausgelegt. Weil aber auf dem Discovery-Board nur ein 8MHz eingebaut ist, müssen beide Files angepasst werden. Mach einfach mal einen Textvergleich mit deinen und meinen Files (meine stimmen
Die Defines werden in der CoIDE unter “Configuration” in der Registerkarte “Compile” und dem Feld “Defined Symbols” per “Add” hinzugefügt.
okay, ich hab zumindest rausfinden können das es nicht am Timing liegt, also stimmen meine Files auch (habs trotzdem mal 1:1 von dir übernommen) aber trotzdem kommt nach dem UB_STemWIN_init(); nichts mehr auf dem Display. Ich werde morgen mal mit dem Debugger bei gehen und schauen wo er genau haengt… Es werden nur Streifen/Punkte angezeigt. Und die defines hab ich auch in meine Makefile basteln müssen da ja deine bzw. auch die ST Files diese Defines nutzen.
Hello,
why rotate doesnt work? at least for me it doesnt
even after define this #define USE_SDRAM_AS_GUIMEM 1
and call screen rotation function UB_STemWIN_GUIRotate (ROTATE_90);
The screen remain white after all.
I noticed when define sdram as gui memory compilation time is x10 more.
Thanks in advance!
hmm, i have tested it and it worked with my settings. The function to rotate must placed directly under “UB_STemWIN_init”. And yes the compilation time ist much longer but also the working speed is much slower. So try not to rotate or find a better solution as i do.
I would like to express my thanks for your libraries – they are clear and working without any problem. It’s a lot of work you did instead of us.
With best regards
Igor
Hallo,
wenn ich die Rotate-Funktionen ausführe, um ein Landscape-Format zu nutzen,
schnellen die link-time und die Hex-File-Größe in die Höhe, die Flash-Zeiten bleiben aber unverändert. Ursache ist der benutzte SDRAM-Speicher, den der Linker jetzt zum Binary dazulinkt, der Flasher aber nicht flasht, weil der SDRAM-Adressbereich nicht im Flash-Adressbereich liegt. Abhilfe schafft eine kleine Änderung im Linkerscript, indem die HeapMemSection als NOLOAD deklariert wird:
.HeapMemSection (NOLOAD) :
{
*(.HeapMemSection)
} > sdram
Tip: kommt es bei Rotate zu einem Hard Fault, ist der SDRAM nicht in der GUI alloziiert. Nach UB_LCD_Init() und vor GUI_SetOrientation (Rotation) GUI_Init() ausführen, das ruft dann GUI_ALLOC_AssignMemory(extMem, GUI_NUMBYTES) (in GUIConf.c) auf, das den SDRAM zuweist.
Hallo!
vielen danke für die Lib! Ich habe schon so standart sachen hin bekommen wie BUTTONs und auch die progressbar. Nur sobald in der Creat funktion hParent vor kommt weiß ich nicht wie ich das benutzen kann. Ich habe schon herrausgefunden das das mit dem WM zusammen hängt und das dieses OBjekt (Spinbox) ein “Kind” von dem Fenster seien muss. Nun meine frage warum Muss das bei Knöpfen nicht sein und wie erstelle ich ein Spinbox bzw dann auch das Window?
Danke Marcel
Um mal auf die unbeantwortete Frage nach einer Variante mit FreeRTOS in Kombination mit der emWIN GUI, beantworten zu wollen – (unberücksichtigt dessen, dass diese Frage schon älter ist) kann ich sagen dass dies theoretisch funktioniert. Ich benutze emWIN 5.24h in Kombination mit dem Keil eigenen RTOS “RTX” und dass funktioniert tadellos. Es ist jedoch ein immenser Unterschied ob man mit einer Superloop arbeitet, oder mit einem RTOS. Das liegt im wesentlichen an der unterschiedlichen Art wie Prozesse von einander isoliert und mit unterschiedlichen Prioritäten abgearbeitet werden.
Zunächst müssen zwei Prozesse generiert werden die in der Superloop nicht benötigt werden. Die Message-Queue muss periodisch bearbeitet werden sonst passiert nicht mal ein Bildaufbau denn selbst ein GUI_Clear() löst zunächst auch nur eine Message in der MSGQ aus. Der Background-Handler des GUI sollte alle 50ms mal aufgerufen werden. Ich hab die Zeit auf die Hälfte reduziert dann sieht es auf meinem 5″ TFT mit SSD1963 am FSMC des STM32F4Disco angeschlossen, sehr flüssig aus. Da dürfte jeder Arduino-Nutzer vor Neid erblassen. Zum zweiten benötigt man noch einen Task der das Eingabegerät abfragt und die Message in die MsgQ stellt. Im einfachen Fall wird ein resistives Touchpanel via SPI angeschlossen und mit Hilfe der vorhandenen API der GUI-Library bedient und diese Aufrage in einem Task der alle 50ms gestartet wird, erledigt. Kompliziert wird es, wenn mehr als ein Gerät am gleichen SPI klebt denn dann muss der Zugriff auch noch Semaphoren geregelt werden sonst gibbet es Mecker. Meine Eingangs erwähnte Einschränkung “funktioniert theoretisch” bezieht sich auf die Nutzung von FreeRTOS und der damit zusammenhängende Einsatz von GCC als Compiler. Mir ist es bis her nicht gelungen, ein Bild hinzubekommen. Das OS läuft bereits sichtbar, denn ich lasse einige TASKs bereits LED’s , CAN-Bus, ADC per DMA und RS232 bedienen. Ob der SPI ein Problem sein wird, werde ich noch sehen.
Ich versuche dieses vorhandene Projekt vom Keil-Compiler zu portieren damit die Übersetzungszeit erträglicher wird, denn die KEIL-IDE unterstützt kein paralleles übersetzten und einen Geschwindigkeitsrekord bricht der Keil-Compiler auch nicht.
Die IDE ist auch nicht besonders komfortabel, jedoch für einen Anfänger ist sie sehr geeignet, da das Setup für ein Board schnell eingestellt ist.
Klasse gemacht!
Habe vorher mit Keil gearbeitet und habe StemWin nicht integriert bekommen ohne das er mir die Init Sequenz versemmelt. Jetzt arbeite ich mit Coo und das Ding rennt egal was ich da in die Main klatsche!
DAC Example aus der SDT PERIPH 1.3 zusammen mit deinem Hello World zusammen klappt auch wunderbar aber VORSICHT: Header und Sources nachziehen und in der Main deklarieren.
Das wären: dac,tim,dma.
Kopiert einfach das Wesentliche aus der Main.c(Std Periph Examples/ DAC) raus und ins Hello World rein(InitStruct DMA,DAC,Funktionen am Fußende usw.).
Ergänzt die Main.h um die DAC Addy(zwei Zeilen aus der Example DAC/Main.h)
Tauscht nur noch eine Kleinigkeit aus :
Da das LCD Display mit VSYNC H an PA4 verbunden ist, scheidet ein DAC Ausgang aus, und zwar Channel 1…im Quelltext wäre das:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
DAC_Cmd(DAC_Channel_2, ENABLE);
DAC_DMACmd(DAC_Channel_2, ENABLE); (diese Zeilen austauschen)
Wählt das Signal eurer Wahl aus indem ihr es einkommentiert und die anderen auskommentiert, könntet natürlich auch Buttons am Bildschirm benutzen…gutes Training für die GUI.
Ihr könnt es natürlich auch so lassen und ein Sägezahn in den VSYNC jagen, man sieht nur leider nichts mehr.
Nur noch die Buttons entfernen(Keypressed ect(nur das aus dem DAC Beispiel). …der Compiler wird schon meckern, einfach entfernen)
Wem das zu viel ist gerne nachfragen, kann auch mal zeigen wie man Pixel im Bildschirm titschen lässt.
Grüße
Roman
Also… ich hab’s immer noch nicht kapiert… warum ist das Dingens denn so schrecklich langsam im Landscape mode? Kann man denn nicht einfach das sicherlich vorhandene entsprechende Bit im Display-Controller des on-Chip Peripherals umschalten und die Sache hat sich?
Laut Uwe’s Vergleich zwichen internem u. externem RAM liegt ein Zeitunterschied von ca 1:35(!). Eigentlich kann man diese Variante des Umschaltens nichtmal einem “Arduino-Power-User” zumuten…
Hey,
First of all, thanks for the great site! im finding it very useful and i would like to ask you if I can use this library together with freeRTOS (on STM32F4 discovery board) or do i have to compile it diffrently ? Thank you!
Biaggi