这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【FRDM-MCXA156评测】5、8位并口屏运行LVGL

共6条 1/1 1 跳转至

【FRDM-MCXA156评测】5、8位并口屏运行LVGL

助工
2024-11-14 14:51:45     打赏

因为GUI-Guider神一般的存在,NXP的MCU在配置性能允许的情况下,必须要运行一下LVGL。

MCXA156的SDK中很贴心的提供了LVGL的例子,但没有配套的屏幕,也就无从下手了。

只有一个220*176的8位并口屏,因陋就简吧。

一、GUI-Guider

安装了GUI-Guider 1.8.1,只支持LVGL v8.3.10,并且已支持的板子中没有MCXA156。

image.png

image.png

所以Simulator开局

image.png

不支持220*176,需要打开.guiguider扩展名的文件,将其中分辨率的部分都修改成220、176,再打开GUI-Guider,这时画布就是220*176的了。

勾勾画画在上面放几个部件,算是完成,然后Generate Code

image.png

二、移植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的方法输出,效率不高。

三、运行效果

微信图片_20241114144242.jpg

f8ecfaf30ea3caeb29d9e44b3df204e.jpg

LCD 接在板子arduino接口上。

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





关键词: 评测     FRDM-MCXA156    

专家
2024-11-14 23:09:19     打赏
2楼

感谢分享


专家
2024-11-14 23:13:39     打赏
3楼

感谢分享


专家
2024-11-14 23:16:00     打赏
4楼

感谢分享


工程师
2024-11-15 10:26:11     打赏
5楼

666


专家
2024-11-21 09:27:44     打赏
6楼

使用并口LCD,比较废GPIO口。


共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]