1.LVGL快速移植

发布时间 2023-11-27 10:39:54作者: =天赋=

一、拷贝lvgl 整个文件夹到工程中,lv_conf_template.h 文件要重命名为lv_conf.h,该文件里面#if 0改成#if 1 ,如下所示

 

 

二、工程里面添加所有文件和头文件路径,这一步过程比较长长,但还是要做好,

然后编译,可能报错.Undefined symbol __aeabi_assert (referred from qrcodegen.o).,需要添加NDEBUG到预处理,进行暂时屏蔽断言

 

 

 三、注册屏幕驱动接口给lvgl

lv_port_disp.c是屏幕驱动接口,是移植重点,可以拷贝lvgl / env_support / rt_thread / lv_rt_thread_port.h进行修改

如下所示:

只有一个put_px()函数需要自己根据屏幕类型去实现,即画点函数

  1 /**
  2  * @file lv_port_disp_templ.c
  3  *
  4  */
  5 
  6 /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
  7 #if 1
  8 
  9 /*********************
 10  *      INCLUDES
 11  *********************/
 12 #include "lv_port_disp.h"
 13 #include "../../lvgl.h"
 14 #include "main.h"
 15 #include "custom.h"
 16 
 17 /*********************
 18  *      DEFINES
 19  *********************/
 20 #define ONE_BUFFER 1
 21 #define TWO_BUFFER 0
 22 
 23 #define COLOR_SIZE         (CLCD_WIDTH * CLCD_HEIGHT)
 24 /**********************
 25  *      TYPEDEFS
 26  **********************/
 27 
 28 /**********************
 29  *  STATIC PROTOTYPES
 30  **********************/
 31 static void disp_init(void);
 32 
 33 static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
 34 //static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
 35 //        const lv_area_t * fill_area, lv_color_t color);
 36 
 37 /**********************
 38  *  STATIC VARIABLES
 39  **********************/
 40 
 41 /**********************
 42  *      MACROS
 43  **********************/
 44 
 45 /**********************
 46  *   GLOBAL FUNCTIONS
 47  **********************/
 48 
 49 void lv_port_disp_init(void)
 50 {
 51     /*-------------------------
 52      * Initialize your display
 53      * -----------------------*/
 54     disp_init();
 55 
 56     /*-----------------------------
 57      * Create a buffer for drawing
 58      *----------------------------*/
 59 
 60     /**
 61      * LVGL requires a buffer where it internally draws the widgets.
 62      * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
 63      * The buffer has to be greater than 1 display row
 64      *
 65      * There are 3 buffering configurations:
 66      * 1. Create ONE buffer:
 67      *      LVGL will draw the display's content here and writes it to your display
 68      *
 69      * 2. Create TWO buffer:
 70      *      LVGL will draw the display's content to a buffer and writes it your display.
 71      *      You should use DMA to write the buffer's content to the display.
 72      *      It will enable LVGL to draw the next part of the screen to the other buffer while
 73      *      the data is being sent form the first buffer. It makes rendering and flushing parallel.
 74      *
 75      * 3. Double buffering
 76      *      Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
 77      *      This way LVGL will always provide the whole rendered screen in `flush_cb`
 78      *      and you only need to change the frame buffer's address.
 79      */
 80 
 81     /* Example for 1) */
 82     static lv_disp_draw_buf_t draw_buf_dsc_1;
 83     static lv_color_t buf_1[COLOR_SIZE];                          /*A buffer for 10 rows*/
 84     lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, COLOR_SIZE);   /*Initialize the display buffer*/
 85 
 86     /* Example for 2) */
 87     //static lv_disp_draw_buf_t draw_buf_dsc_2;
 88     //static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
 89     //static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
 90     //lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/
 91 
 92     /* Example for 3) also set disp_drv.full_refresh = 1 below*/
 93     //static lv_disp_draw_buf_t draw_buf_dsc_3;
 94     //static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/
 95     //static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*An other screen sized buffer*/
 96     //lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/
 97 
 98     /*-----------------------------------
 99      * Register the display in LVGL
100      *----------------------------------*/
101 
102     static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
103     lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/
104 
105     /*Set up the functions to access to your display*/
106 
107     /*Set the resolution of the display*/
108     disp_drv.hor_res = CLCD_HEIGHT;
109     disp_drv.ver_res = CLCD_WIDTH;
110 
111     /*Used to copy the buffer's content to the display*/
112     disp_drv.flush_cb = disp_flush;
113 
114     /*Set a display buffer*/
115     disp_drv.draw_buf = &draw_buf_dsc_1;
116 
117     /*Required for Example 3)*/
118     //disp_drv.full_refresh = 1
119 
120     /* Fill a memory array with a color if you have GPU.
121      * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
122      * But if you have a different GPU you can use with this callback.*/
123     //disp_drv.gpu_fill_cb = gpu_fill;
124 
125     /*Finally register the driver*/
126     lv_disp_drv_register(&disp_drv);
127 }
128 
129 /**********************
130  *   STATIC FUNCTIONS
131  **********************/
132 
133 /*Initialize your display and the required peripherals.*/
134 static void disp_init(void)
135 {
136     /*You code here*/
137     drv_clcd_init();
138 }
139 
140 /*Flush the content of the internal buffer the specific area on the display
141  *You can use DMA or any hardware acceleration to do this operation in the background but
142  *'lv_disp_flush_ready()' has to be called when finished.*/
143 static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
144 {
145     /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
146     #if 1
147     int32_t x;
148     int32_t y;
149     for(y = area->y1; y <= area->y2; y++)
150     {
151         for(x = area->x1; x <= area->x2; x++)
152         {
153             /*Put a pixel to the display. For example:*/
154             put_px(x, y, *((u16*)(color_p)));
155             color_p++;
156         }
157     }
158     #endif
159 
160     //LCD_Color_Fill(area->x1, area->y1, area->x2, area->y2, (uint16_t*)color_p);
161 
162     /*IMPORTANT!!!
163      *Inform the graphics library that you are ready with the flushing*/
164     lv_disp_flush_ready(disp_drv);
165 }
166 #if LV_USE_LOG
167 static void lv_rt_log(const char *buf)
168 {
169     SYSTEM_DEBUG(buf);
170 }
171 #endif /* LV_USE_LOG */
172 lv_ui guider_ui;
173 
174 void lv_100ask_demo_course_2_1_1(void)
175 {
176     #if 0
177     lv_obj_t * obj = lv_obj_create(lv_scr_act());
178     lv_obj_set_size(obj, LV_PCT(100), LV_PCT(10));
179     lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0);
180     #endif
181     setup_ui(&guider_ui);
182 
183     lv_obj_t * label = lv_label_create(lv_scr_act());
184     lv_label_set_text_fmt(label, "ver:%d.%d.%d\n",LVGL_VERSION_MAJOR, LVGL_VERSION_MINOR, LVGL_VERSION_PATCH);
185     lv_obj_align(label, LV_ALIGN_DEFAULT, 0, 0);
186     lv_label_set_recolor(label,1);
187 
188 }
189 
190 static void lvgl_thread_entry(void *parameter)
191 {
192     #if LV_USE_LOG
193     lv_log_register_print_cb(lv_rt_log);
194     #endif /* LV_USE_LOG */
195     lv_init();
196     lv_port_disp_init();
197     //lv_port_indev_init();
198     //lv_user_gui_init();
199     //lv_disp_set_rotation(NULL,LV_DISP_ROT_90);
200 
201 #if 0
202     lv_100ask_demo_course_2_1_1();
203 #endif
204 
205     /* handle the tasks of LVGL */
206     while(1)
207     {
208         lv_task_handler();
209         rt_thread_mdelay(1);
210 
211     }
212 }
213 struct rt_thread lvgl_thread;
214 static rt_uint8_t task1_stack[4096];
215 
216 static int lvgl_thread_init(void)
217 {
218     rt_err_t err;
219 
220     err = rt_thread_init(&lvgl_thread, "LVGL", lvgl_thread_entry, RT_NULL, &task1_stack[0], sizeof(task1_stack), 2, 0);
221     if(err != RT_EOK)
222     {
223         SYSTEM_DEBUG("Failed to create LVGL thread");
224         return -1;
225     }
226     rt_thread_startup(&lvgl_thread);
227 
228     return 0;
229 }
230 INIT_ENV_EXPORT(lvgl_thread_init);
231 
232 
233 /*OPTIONAL: GPU INTERFACE*/
234 
235 /*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
236 //static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
237 //                    const lv_area_t * fill_area, lv_color_t color)
238 //{
239 //    /*It's an example code which should be done by your GPU*/
240 //    int32_t x, y;
241 //    dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
242 //
243 //    for(y = fill_area->y1; y <= fill_area->y2; y++) {
244 //        for(x = fill_area->x1; x <= fill_area->x2; x++) {
245 //            dest_buf[x] = color;
246 //        }
247 //        dest_buf+=dest_width;    /*Go to the next line*/
248 //    }
249 //}
250 
251 
252 #else /*Enable this file at the top*/
253 
254 /*This dummy typedef exists purely to silence -Wpedantic.*/
255 typedef int keep_pedantic_happy;
256 #endif

 我的屏幕画点函数如下:

 1 // 设置光标位置
 2 void LCD_SetCursor(uint16_t x, uint16_t y)
 3 {
 4 LCD_WR_REG(0x2A);
 5 LCD_WR_DATA(x);
 6 //LCD_WR_DATA((CLCD_HEIGHT- 1) & 0xFF);
 7 LCD_WR_DATA(x);
 8 
 9 LCD_WR_REG(0x2B);
10 LCD_WR_DATA(y);
11 //LCD_WR_DATA((CLCD_WIDTH- 1) & 0xFF);
12 LCD_WR_DATA(y);
13 
14 //LCD_WR_REG(0x2c);//
15 }
16 
17 void put_px(u16 x,u16 y, u16 color)
18 {
19 LCD_SetCursor(x, y);
20 LCD_WR_REG(0x2C);
21 LCD_WR_DATA(color);
22 }