94-Simple_GUI-Library (STM32F4)

Diese Library ermöglicht es eine “einfache” Graphische Benutzeroberfläche
mit dem STM32F407 und einem Grafik-Display (mit Touch) zu realisieren.

Hier ein Demo-Bild :

Simple GUI

Simple GUI

Es ist die gleiche Library wie für den STM32F429 (LIB-27) nur wird hier ein Display
mit ST7783-Chip und ein Touch mit ADS7843-Chip benutzt.

Zur Beschreibung bitte die Version vom F429 durchlesen, die ist identisch.
hier der Link : SGUI_F429

Die Demo-Files sind auch identisch zur F429-Version, einmal ein Hello-World
mit nur einem Button und einmal eine komplette Demo von allen Objekten.

Hier die Library zum Download :

ub_stm32f4_sgui_v103

Hier der komplette CooCox-Projektordner zum Download : (Hello-World)

Demo_94_SGUI

Hier der komplette CooCox-Projektordner zum Download : (Demo aller Objekte)

Demo_94b_SGUI


18 Antworten auf 94-Simple_GUI-Library (STM32F4)

  1. Axel R. (DG1RTO) sagt:

    Hallo Uwe,
    vielen Dank für die nette GUI. Eine Menge Arbeit…
    Die Einträge in der Scroll-Listbox lassen sich mit dem dicken Finger schlecht treffen.
    In “ub_sgui_listbox.c” habe ich beim Zeichnen der Items mit font->height(+5) etwas Luft geschaffen. Den ersten Eintrag in der Liste habe ich etwas herab gesetzt( y-Rahmendicke-5). Leider trifft der touch nicht mehr…
    Könntest Du bitte ein "#define Item_distance" einführen, dass man die Einträge der Listbox etwas “luftiger” gestalten kann.
    Ich steige leider so ganz nicht dahinter, wie alles bis ins kleinste Detail verwoben ist…
    Der Touch ist kalibriert (STMPE811) und funktioniert hervorragend.
    Danke auch dafür!
    Das Bord ist das Farnell-Bündle STM32F407/DM-STF4BB/DM-LCD35RT.
    Gruß
    Axel

    • admin_ub sagt:

      da lohnt ein update nicht es sind nur zwei Zeilen zu ändern
      in der Funktion : “SGUI_ListboxTouch” die Zeile :

      zeile=yd/SGUI_LISTBOX.ptr[n]->font->height;
      in
      zeile=yd/(SGUI_LISTBOX.ptr[n]->font->height+Item_distance);

      und in der Funktion “P_SGUI_ListboxDraw” die Zeile :

      fh=ptr->font->height;
      in
      fh=ptr->font->height+Item_distance;

  2. Axel R. (DG1RTO) sagt:

    Das ist GENAU das, was ich gestern abend gemacht habe :)
    (Da hate mich der Ergeiz gepackt, ich wollte die Lösung vor dir posten)
    Ich gebe den Text noch um die halbe “Item_distance” erhöht aus, damit er vertikal zentriert steht. Damits schön aussieht, noch ein 3D-RoundedRect drumrum. LOWERED und RAISED – immer im Wechsel.
    Vielen lieben Dank! Es macht großen Spaß, damit rumzuspielen …
    Axel R.

    • admin_ub sagt:

      Ja, man könnte noch soviel einbauen. Buttons mit Bilder, Hintergrundgrafik usw. Wenn man sich an das “Grundgerüst” hält ist das meiste nur copy&paste. Die Bedienung mit dem Touch gefällt mit nicht so sehr. Die Slider sollten z.B. mit einem Wisch bewegt werden können, wäre auch machbar, aber im Moment habe ich gar keinen Trieb mehr. Nach dem Echo hier braucht das ganze aber scheinbar keiner wirklich.

      • Stefan F. sagt:

        Gerade über die Realisierung so einer “Wischfunktion” für Slider bin ich am grübeln. Problematisch hierbei ist ja der Refresh vom Slider auf dem Display. Wie könnte man sowas denn elegant lösen ? Ist da der Weg über den Slider als eigenes grafisches Objekt von dem nur ein Teil neu gezeichnet wird der richtige Schritt ? Und wenn ja wie würde man dann den Hintergrund erhalten wenn nicht alles neu gezeichnet wird ?
        (Grafik Chip hat nur ein Layer)
        Bzw geht der Refresh der Grafik dann noch schnell genug das das Bewegen des Sliders wie eine flüssige Bewegung aussieht ?
        Bin für jeden Tip dankbar :)

        • admin_ub sagt:

          mit nur einem Layer wirst du wahrscheinlich ein “flackern” sehen. Ich würde den Slider aus zwei Graphischen Objekten machen. Ein gefülltes Rechteck als “Hintergrund” und darauf ein kleineres gefülltes Rechteck als “Positionsanzeige”. Dann im Programm

          1
          2
          3
          4
          
          if(act_value!=old_value) {
            drawSliderBody();
            drawSliderKnob(act_value);
          }

  3. Axel R. (DG1RTO) sagt:

    Eines fiel mir auf, wo ich nicht wirklich weiter komme:
    rufe ich eine Funktion im gesetzten Funktionshandler auf, findet der Compiler die Rücksprungadresse zu (zB.) “lb_main_fkt” nicht. Muss “lb_main_fkt”, da sie als Pointer der Listbox zugewiesen wurde, irgentwo extra oder besonders bekannt gegeben werden?
    Prozeduraufrufe (SGUI_Windowshow) funktionieren wie erwartet, nur Funktionsaufrufe finden zu ” lb_main_fkt” nicht zurück.
    Wie wird das richtig gemacht?
    Danke
    Axel


    //globale Variable
    uint16_t check = 0; //Check, ob Firmware aktuell

    void lb_main_fkt(uint16_t aktiv_nr) {

    if(aktiv_nr==0) SGUI_WindowShow(WND_AUSW_1);

    if(aktiv_nr==1) {

    check = check_new_FW(Parameter[0].text); // Hier kommt er nicht mehr zurück
    // es wird nach „check_new_FW“ der default_Handler angesprungen
    sprintf(fw_buf,“check_FW; %d“,check );
    UB_Uart_SendString(COM3,fw_buf,CRLF); // DEBUG Ausgabe

    if ( check == 1 ) {

    // set_active_item = fw_update, also „1“ erster Eintrag.
    SGUI_ListboxInsertItem(lb_param_c1,0,“FW-UPDATE“);
    update = 1;
    }
    else if (check == 1001) {
    // Timeout – kein Copter angeschlossen
    SGUI_ListboxSetAktivItemNr(lb_main ,-1); // disable all items
    SGUI_WindowShow(1);

    }

    SGUI_WindowShow(WND_2); //Zweites Fenster

    }
    if(aktiv_nr==2) SGUI_WindowShow(WND_SETUP); // drittes Fenster
    //Setup ( Uhrzeit/Datum usw )
    }

    • Axel R. (DG1RTO) sagt:

      ich antworte gleich selbst:
      der Stack war zu klein, die lokalen Variablen doch etwas “ausladend”.
      Die "check_new_FW" Funktion testhalber etwas abgespeckt und siehe da – geht doch :)

      Danke und Gruß, viel Spaß allen
      Axel DG1RTO

    • Axel R. (DG1RTO) sagt:

      … es lag an der sprintf() Anweisung …
      Statt den Intergerwert in der Funktion über COM3 via sprintf() zu printen, verwende ich diesen nun als Rückgabewert. In der aufrufenden Funktion (Hier der Listbox-handler) kann man nun alles damit machen – inlusive sprintf() undd Ausgabe auf einer der seriellen. Ich hatte testhalber das makro STACK_SIZE in startup_stm32f4xx.c


      /*----------Stack Configuration-----------------------------------------------*/
      #define STACK_SIZE 0x00000200 /*!< The Stack size suggest using even number */
      __attribute__ ((section(".co_stack")))
      unsigned long pulStack[STACK_SIZE];

      von 0×200 auf 0×400 und auch auf 0×800 erhöht. Ging trotzdem nicht…
      Leider fehlt mir der Durchblick beim Linkersript.
      Muss/kann ich am Linkersript noch etwas verändern?

      Viele Grüße
      Axel (DG1RTO)

  4. Rodrigo sagt:

    hello, congratulations for the great code, I use the LCD with SSD1289, how do the necessary changes, thanks for the effort.

    • admin_ub sagt:

      first : download the c+h file for the display from here http://mikrocontroller.bplaced.net/wordpress/?page_id=1357
      and use these two files instead the included “st7783″ version.
      second : change all include lines from
      #include “stm32_ub_lcd_st7783.h”
      to
      #include “stm32_ub_lcd_ssd1289.h”
      that should work.

  5. Rodrigo sagt:

    Thank you for dedicated effort, I admire people like you who share knowledge, I use STM32F4DISCOVERY with open407v-d expansion, and had to make some changes, but now is working very well, thank you again. follow the link with the changes in stm32_ub_lcd_ssd1289.c file

    http://pastebin.com/msyrj885

    best regard

  6. Joerg B. sagt:

    Moin Uwe,
    wo platziere ich am einfachsten einen Zähler Reset (bei Touch Event) um die Hintergrundbeleuchtung nach einer gewissen Zeit aus zu schalten?

    Grüße

    Jörg

    • admin_ub sagt:

      im File “stm32_ub_sgui.c” gibt es die Funktion “SGUI_TIM_ISR_HANDLER”
      diese wird jede ms aufgerufen.
      Einfach eine Globale uint32_t definieren und diese in der ISR incrementieren.
      Außerhalb der ISR (z.B. in der Main) die Variable löschen und prüfen auf Sollwert.
      Das gleiche macht die Funktion “SGUI_Pause_ms” mit der Variablen “UB_SGUI.pause_cnt”

      • Joerg B. sagt:

        Da hab ich mich wohl nicht klar genug ausgedrückt.
        Die variable muss bei jedem Touch Ereignis zurück gesetzt werden. Damit wenn nichts passiert die LED ausgeschaltet wird.

        • admin_ub sagt:

          falls es reicht zu erkennen ob der Touch an irgendeiner stelle gedrückt wurde gibt es im File “stm32_ub_sgui.c” in der Funktion “SGUI_Do” die Abfrage “if(Touch_Data.status==TOUCH_PRESSED) {”

          Wenn nur bei den Buttons oder Schaltern reagiert werden soll, muss die Variable “touch_aktion” ausgewertet werden und zwar ganz am Ende der Funktion. Die Variable ist “true” wenn irgendein sichtbares Objekt betätigt wurde.

          • Joerg B. sagt:

            Nein es reicht wenn irgend ein Touch ausgelöst wurde.

            Ich werde das heute Abend mal testen…

            Danke

          • admin_ub sagt:

            Die Variable “Touch_Data.status” ist global das bedeutet die kannst du auch irgendwo in der Main abfragen.


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert