因为GUI-Guider神一般的存在,NXP的MCU在配置性能允许的情况下,必须要运行一下LVGL。
MCXA156的SDK中很贴心的提供了LVGL的例子,但没有配套的屏幕,也就无从下手了。
只有一个220*176的8位并口屏,因陋就简吧。
一、GUI-Guider
安装了GUI-Guider 1.8.1,只支持LVGL v8.3.10,并且已支持的板子中没有MCXA156。


所以Simulator开局

不支持220*176,需要打开.guiguider扩展名的文件,将其中分辨率的部分都修改成220、176,再打开GUI-Guider,这时画布就是220*176的了。
勾勾画画在上面放几个部件,算是完成,然后Generate Code

二、移植LVGL
1、拿SDK_2_16_100_FRDM-MCXA156\boards\frdmmcxa156\lvgl_examples\lvgl_guider做模板
1)将其中的generated目录用前面GUI-Guider生成的generated替换掉。
2)从LVGL 官方SDK中拷贝lv_port_disp.c、lv_port_disp.h文件到lvgl_guider,代替lvgl_support.c
lvgl_support是基于FLEXIO的LVGL支持文件,改起来费劲,还是从LVGL SDK标准接口文件入手直接一些。
3)在lvgl_guider建个LCD目录,将LCD的驱动文件拷贝到LCD
4)在keil中添加generated、LCD、lv_port_disp的*.c、*.h,去掉lvgl_support、原来generated的*.c、*.h,增加include路径。
2、lv_port_disp.c
void lv_port_disp_init(void)
void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    disp_init();
    /*-----------------------------
     * Create a buffer for drawing
     *----------------------------*/
    static lv_disp_draw_buf_t draw_buf_dsc_2;
    static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/
	
    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/
    static lv_disp_drv_t disp_drv;                  /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/
    /*Set up the functions to access to your display*/
    /*Set the resolution of the display*/
    disp_drv.hor_res = MY_DISP_HOR_RES;
    disp_drv.ver_res = MY_DISP_VER_RES;
    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;
    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_2;
    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}disp_flush
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    if(disp_flush_enabled) {
        /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
        int32_t x;
        int32_t y;
        for(y = area->y1; y <= area->y2; y++) {
            for(x = area->x1; x <= area->x2; x++) {
                /*Put a pixel to the display. For example:*/
                put_px(x, y, (uint16_t *)color_p);        //画点函数
                color_p++;
            }
        }
    }
    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}定义2个空函数
void lv_port_pre_init(void)
{
}
void lv_port_indev_init(void)
{
}3、主程序文件
main()
int main(void)
{
    stat = xTaskCreate(AppTask, "lvgl", configMINIMAL_STACK_SIZE + 800, NULL, tskIDLE_PRIORITY + 2, NULL);
}void AppTask(void *param)
static void AppTask(void *param)
{
    lv_port_pre_init();
    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();
    s_lvgl_initialized = true;
    disp_enable_update();
    setup_ui(&guider_ui);        //调用generated目录下的函数
    events_init(&guider_ui);
    custom_init(&guider_ui);
    for (;;)
    {
        lv_task_handler();
        vTaskDelay(5);
    }
}/*!
 * @brief FreeRTOS tick hook.
 */
void vApplicationTickHook(void)
{
    if (s_lvgl_initialized)
    {
        lv_tick_inc(1);
    }
}4、LCD驱动文件
put_px
void put_px(int32_t x,int32_t y, uint16_t *color_p)
{
	setXY(x, y, x, y);                //设置输出区域
	lcd_write_data_word(*color_p);    //输出颜色
	clrXY();
}lcd_write_data_word
void lcd_write_data_word(uint16_t data)
{
    unsigned char c[2];
    c[0] = (data >> 8) & 0xFF;
    c[1] = data & 0xFF;
    LCD_CS_CLR;
    LCD_RS_SET;
    gpio_lcd_write_data(c, 2);
    LCD_CS_SET;
}void gpio_lcd_write_data(uint8_t* data, size_t length)
void gpio_lcd_write_data(uint8_t* data, size_t length) {
    for (size_t i = 0; i < length; i++) {
        for (int bit = 0; bit < NUM_BITS; bit++) {
            // 检查当前位是否为1
            if (data[i] & (1 << bit)) {
                GPIO_PinWrite(dbPins[bit].GPIOx, dbPins[bit].GPIO_Pin, true);
            } else {
                GPIO_PinWrite(dbPins[bit].GPIOx, dbPins[bit].GPIO_Pin, false);
            }
        }
				LCD_WR_CLR;
				LCD_WR_SET;
        // 如果需要,可以在这里添加延时或其他处理
    }
}因为8位并口屏对应MCU引脚地址不连续,用不了DMA,只能用写GPIO的方法输出,效率不高。
三、运行效果


LCD 接在板子arduino接口上。
本来想用板载温度传感器+LCD显示温度的,但是两者引脚冲突了,只能作罢。

 
					
				
 
			
			
			
						
			 
					
				 
					
				 
					
				 
					
				 
					
				
 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

