因为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显示温度的,但是两者引脚冲突了,只能作罢。

我要赚赏金
