一、目的
在自己的嵌入式产品,尤其是单片机/arm/dsp之类的裸机产品或者轻量级产品上,为了运行快速、缓存低、轻量级的界面设计开发,需littlevgl恰好满足这个目的,且由于其免费,所以值得设计者研究或者去利用移植到自己平台上。
本次移植是在nuc970这个arm9平台实现的,其他平台类似。littlevgl的界面移植很简单,并不繁琐,很容易移植到终端mcu平台中。
二、移植关键阐述
对于littlevgl移植,最基本的移植为图像移植,人机互动则是input移植。只要移植好这两个方面,基本就能将littlevgl的ui库加载到我们自己的平台上了。其中图形移植,见另外一章,这里只阐述input移植。
input移植其实概用官方所述,只要实现两个关键的东西,一个是触摸数据上报,一个是触摸类型配置。在littlevgl中提供了这些属性的通用接口函数和流程。
即申请一个input变量,然后实现这个变量的数据上报函数和类型。比如:
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type =... /*input type.*/
indev_drv.read_cb =... /*input fun to get input data.*/
/*Register the driver in LittlevGL and save the created input device object*/
lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
上面完成的就是创建了一个indev_drv的一个变量,然后配置它的type和read_cb两个接口。前面那个为触摸的类型,根据触摸的设备和功能来选择,毕竟触摸有屏,pad,按键、鼠标等。具体可配置如下:
LV_INDEV_TYPE_POINTER touchpad or mouse
LV_INDEV_TYPE_KEYPAD keyboard or keypad
LV_INDEV_TYPE_ENCODER encoder with left, right, push options
LV_INDEV_TYPE_BUTTON external buttons pressing the screen
read_cb是核心函数。即littlevgl获取触摸的属性只能通过其向它的系统中同步对应的触摸数据。littlevgl图形系统会自动的去查询这个数据,然后做对应操作。即我们要在这个函数中加载对应触摸屏对应的lcd屏像素点,注意,重要事情再重复一遍,这个函数加载的数据不是触摸直接出来的数据,是和你对应lcd屏对应的数据,一般而言触摸屏的点数大于显示屏的像素的,要有个换算。下面是对read_cb的编写:
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_input_read;
...
bool my_input_read(lv_indev_drv_t * drv, lv_indev_data_t*data)
{
data->point.x = touchpad_x;
data->point.y = touchpad_y;
data->state = LV_INDEV_STATE_PR or LV_INDEV_STATE_REL;
return false; /*No buffering now so no more data read*/
}
需要注意的是,为了降低littlevgl的cpu占有率,尽量不要在read函数上直接调用触摸函数去读取触摸数据。触摸数据最好在littlevgl去读取的时候,数据已经准备好。后面真实中会体现。
三、实例
这里设计是基于NUC平台所做的。
第一步、创建一个触摸对象并配置其值,然后注册
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);//init
indev_drv.read = touchpad_read;//config read fun
indev_drv.type = LV_INDEV_TYPE_POINTER;//config type
lv_indev_drv_register(&indev_drv);//register
第二步、实现触摸数据上报
static bool touchpad_read(lv_indev_data_t *data)
{
static int16_t last_x = 0;
static int16_t last_y = 0;
sysprintf(" x1 = %d, y1 = %d \r\n", g_GT911.X1,g_GT911.Y1);
if(g_GT911.S1){
data->state = LV_INDEV_STATE_PR;
data->point.x = g_GT911.X1 /(1024 / 800.0f);//获取相对值,当前触摸屏水平是1024,lcd是800像素
data->point.y = g_GT911.Y1 /(600 / 480.0f);
last_x = data->point.x;
last_y = data->point.y;
g_GT911.S1 = 0;
sysprintf(" x2 = %d, y2 = %d \r\n", data->point.x,data->point.y);
}else{
data->point.x = last_x;
data->point.y = last_y;
data->state = LV_INDEV_STATE_REL;
sysprintf(" x3 = %d, y3 = %d \r\n", data->point.x,data->point.y);
}
return false;
}
上面的数据read_cb是直接获取到data形参中的。具体数据是配置了触摸的中断函数。当有触摸事件发生的时候,数据直接保存g_GT911这个变量中。
四、结论
不会上传动画,所以这里没有法子展示。