Diese Library benutzt den internen DMA2D vom STM32F429 für das zeichnen von Linien Rechtecken, Kreisen und Bildern aus dem Flash.
Der DMA2D ist um ein vielfaches schneller wie die gleiche Funktion per “CPU”
z.B. dauert das löschen vom kompletten Screen ohne DMA2D ca. 11ms und mit DMA2D sind es nur noch 1ms
Im Beispiel werden 10.000 Kreise und 10.000 Rechtecke gezeichnet und danach kommt ein Beispiel wie man bewegte Objekte darstellen kann.
Hinweis : die LCD_ILI9341-Lib muss mindestens Version 1.2 sein
Hinweis zur Funktion “UB_Graphic2D_CopyImgDMA”
Der Funktion muss der Bildname und eine Struktur mit den Koordinaten übergeben werden. Mit den Koordinaten wird festgelegt welcher Teilabschnitt vom Bild (sx,sy,w,h) an welcher Position vom Display (dx,dy) angezeigt werden soll.
DMA2D (Memory to Memory) :
Beispielbild :
Funktionen :
1 2 3 4 5 6 7 8 9 | void UB_Graphic2D_ClearSreenDMA(uint16_t c); // löscht kompletten Screen void UB_Graphic2D_DrawPixelNormal(uint16_t xp, uint16_t yp, uint16_t c); // zeichnet ein Pixel void UB_Graphic2D_DrawLineNormal(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); // zeichnet schräge Linie void UB_Graphic2D_DrawStraightDMA(uint16_t xp, uint16_t yp, uint16_t l, LCD_DIR_t d, uint16_t c); // zeichnet Gerade Linie void UB_Graphic2D_DrawRectDMA(uint16_t xp, uint16_t yp, uint16_t w, uint16_t h, uint16_t c); // zeichnet Rechteck void UB_Graphic2D_DrawFullRectDMA(uint16_t xp, uint16_t yp, uint16_t w, uint16_t h, uint16_t c); // zeichnet gefülltes Rechteck void UB_Graphic2D_DrawCircleNormal(uint16_t xp, uint16_t yp, uint16_t r, uint16_t c); // zeichnet Kreis void UB_Graphic2D_DrawFullCircleDMA(uint16_t xp, uint16_t yp, uint16_t r, uint16_t c); // zeichnet gefüllten Kreis void UB_Graphic2D_CopyImgDMA(UB_Image *img, DMA2D_Koord koord); // zeichnet Teilimage aus dem Flash |
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | //-------------------------------------------------------------- // File : main.c // Datum : 26.11.2013 // Version : 1.1 // 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 DMA2D-Graphic-Lib // 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_lcd_ili9341.h" #include "stm32_ub_graphic2d.h" #include <stdlib.h> int main(void) { uint16_t x1,y1,x2,y2,r1,r2,c; uint32_t n,m; DMA2D_Koord koord; SystemInit(); // Quarz Einstellungen aktivieren UB_LCD_Init(); UB_LCD_LayerInit_Fullscreen(); // auf Vordergrund schalten UB_LCD_SetLayer_2(); while(1) { //------------------------------- // 1.) 10.000 Kreise zeichnen //------------------------------- for(n=0;n<10000;n++) { x1=rand() % (LCD_MAXX); y1=rand() % (LCD_MAXY); r1=rand() % (30); c=rand() % (65535); UB_Graphic2D_DrawFullCircleDMA(x1,y1,r1,c); } // kleine Pause for(n=0;n<30000000;n++); //------------------------------- // 2.) 10.000 Rechtecke zeichnen //------------------------------- for(n=0;n<10000;n++) { x1=rand() % (LCD_MAXX); y1=rand() % (LCD_MAXY); x2=rand() % (LCD_MAXX); y2=rand() % (LCD_MAXY); c=rand() % (65535); UB_Graphic2D_DrawFullRectDMA(x1,y1,x2,y2,c); } // kleine Pause for(n=0;n<30000000;n++); //------------------------------- // 3.) bewegter Kreis //------------------------------- r1=0;r2=0; x1=111;y1=111; for(n=0;n<5000;n++) { UB_Graphic2D_ClearSreenDMA(RGB_COL_GREEN); UB_Graphic2D_DrawFullCircleDMA(x1,y1,60,RGB_COL_RED); UB_LCD_Refresh(); if(r1==0) { x1++; if(x1>240-60) r1=1-r1; } else { x1--; if(x1<60) r1=1-r1; } if(r2==0) { y1++; if(y1>320-60) r2=1-r2; } else { y1--; if(y1<60) r2=1-r2; } } // kleine Pause for(n=0;n<30000000;n++); //------------------------------- // 4.) bewegtes Teil Bild aus einem Image //------------------------------- r1=0;r2=0; x1=111;y1=111; // Koordinaten (nur ein Teilbild von 100x80 Pixel) koord.source_xp=20; koord.source_yp=20; koord.source_w=100; koord.source_h=80; koord.dest_xp=x1; koord.dest_yp=y1; for(n=0;n<5000;n++) { UB_Graphic2D_ClearSreenDMA(RGB_COL_GREEN); UB_Graphic2D_CopyImgDMA(&Emo2_Image,koord); for(m=0;m<500;m++); // pause (sonst flicker) UB_LCD_Refresh(); for(m=0;m<100000;m++); // pause (sonst zu schnell) if(r1==0) { x1++; if(x1>240-101) r1=1-r1; } else { x1--; if(x1<2) r1=1-r1; } if(r2==0) { y1++; if(y1>320-81) r2=1-r2; } else { y1--; if(y1<2) r2=1-r2; } koord.dest_xp=x1; koord.dest_yp=y1; } //------------------------------- // 5.) Ende //------------------------------- // kleine Pause for(n=0;n<30000000;n++); // wieder auf Vordergrund schalten UB_LCD_SetLayer_2(); UB_LCD_SetTransparency(255); } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Die Kugel könnte man in Verbindung mit dem Sensor auf der Rückseite kombinieren
Super Beispiel für DMA2D Speicher zu Speicher kopieren
Jetzt sind paar Sache ein bissen mehr klar
Gruß.
Fabrice.
Moin moin! Zuersteinmal ein großes Lob für die wirklich nützlichen Libs.
Ich bin gerade dabei ein 24 Bit Display anzusteuern und stelle daher gerade auf ARGB8888 um ( die 16 Bit Variante lief korrekt ), allerdings will mir das noch nicht so ganz gelingen.
Bisher habe ich
LCD_FRAME_OFFSET verdoppelt,
LTDC_Pixelformat_ARGB8888 in UB_LCD_LayerInit_Fullscreen und UB_Graphic2D_ClearScreenDMA gesetzt (hier auch den Farbparameter auf 32 bit geändert und zerlegt in die entsprechenden Felder des InitStructs gelegt),
UB_LCD_SetCursor2Draw von Byte-Faktor 2 auf 4 gestellt.
Einige Sachen scheine ich aber zu übersehen, da die Ausgabe statt eines Rechtecks einen recht motiviert rennenenden Pixelbrei ergibt.
Für einen Hinweis in welchen Ecken ich noch Änderuzngen durchführen muss wäre ich sehr dankbar!
Achja und bei dieser Lib hat sich ein kleiner Tippfehler eingeschlichen, bei UB_Graphic2D_ClearSreenDMA fehlt ein c
sorry, da kenn ich mich nicht aus
Hallo zusammen,
gute Arbeit!!!
Dank der libs konnte ich mich in Rekordtempo mit dem STM32 einarbeiten.
Ich habe nach den ersten Gehversuchen die einzelnen Hardwarekomponenten ans laufen bekommen inklusive COOS mit Powersave (Sleep und Stop).
Die Pinbelegung ist am STM32F429Disco mal nicht gerade berauschend (LCD und RAM belegen fast alle AF-Funktionen).
Daher habe ich statt HW-PWM eine SW-PWM implementiert => ein wenig löten am Board und schon ist die Hintergrundbeleuchtung am Display einstellbar.
Nun habe ich die LCD_ILI9341-Lib, Graphic2D-Lib und Font-Lib per define auf RGB565, RGB888 und ARGB8888 erweitert. Das Blending für Bachground, Layer1 und Layer2 ermöglicht so im ARGB8888 Mode einfache GUI Programmierung. In RGB565 und RGB888 geht da durch Colorkeying (Transparente Farbe) auch eine ganze Menge.
Hard-FPU aktiviert, und color konverter geschrieben (HSB to RGB, RGB to HSB, color to RGB, RGB to color, Color Fader)
Farbkreisdarstellung + Cursor => Fertig ist ein Farbwähler für RGB Lichtquellen.
+ RTC + Teiltransparente Zeiger => coole analog Uhr gleich mit integriert
+ COOS = Speicherverwaltung, Taskmanagement
+ Sleep/Stop/Standby => niedriger Stromverbrauch für Akkubetrieb
ToDo:
NRF24 Modul implementierung und fertig ist eine RGB Fernbedienung.
NRF24 Modul + STM Nucleo Board + FET-Treiber => RGB-Treiber mit niedrigem Standby Stromverbrauch.
das klingt beeindruckend,
hast du vor deine Ergebnisse online zu stellen? würde da gerne etwas dran rumprobieren
mit dem NRF-Modul habe ich schon am STM32 gearbeitet, da gibts fertige Libs im Netz, aber auch so ist die Doku gut und die Module sehr umkompliziert, eine gute Wahl!
Wie kann ich ein anderes Bild reprroducir Beispiel? Ich habe versucht, die reemplazaer. C, die im Ordner bilder ist, aber es gibt mir Fehler. Danke!
zum erzeugen von Image-Files (*.c) kann mein ImageGenerator Programm benutzt werden.