AT32F403A, IAR, ST7735S, LVGL8.3。
一、现象:
本来想着用LVGL做一个摄像头的显示功能 + 切换动态。可是死活实现不了功能。
因为移植好LVGL后,首先测试了显示按键,功能正常,以为是一切正常。在模拟器上调试效果完成后,将代码搬运到IAR工程里。却发现无法正常显示,也就是不显示。
二、分析:
一开始以为模拟器与实际项目有差别,因为以前出现过这种现象:
lv_canvas_create(lv_scr_act()); //不显示
lv_canvas_create(NULL);//显示
于是分步测试代码功能。我使用的动态显示摄像头数据的实现是:
lv_img。直接写lv_img的源.data数组,再lv_obj_invalidate来通知绘图函数重绘。
既然这样不显示,那么我就试试其它的方法。比如调用lv_img_set_src(, );、使用canvas等,都没有用,而且还发现在static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)里面,px_map指向的是内存,而这片内存的数据里都是0,也就是背景色。我还专门将图象的左上角设置成多种颜色,放在(0,0)位置处,同样px_map里面存的是0。
于是问题陷入了僵局,问题应该在别处而我又找不到。想到的几个方法是
1、断点跟踪问题:
在移植的绘图函数里找断点,通过callback view向上分析:
到底哪里拷贝了px_data数据,是不是那里出现了什么错误。
但这样一来就需要修改lvgl内核源码,可能会产生更多问题,更是会消耗更多时间。
2、再次移植LVGL源码:
第一次移植的是开发者版本的源码,但是运行直接卡死。没办法重下了8.3的版本,由于两者相差比较大,索性重新移植。前面的问题就是在这第二次移植的基础上出现的。
这次直接移植也只是重下后,进行文件替换。
结果编译发现出错:
LV_IMG_CF_TRUE_COLOR 、与 LV_COLOR_SIZE未定义。
LV_COLOR_SIZE可以改为LV_COLOR_DEPTH,就在lv_conf.h里定义,这个很好找。
但是LV_IMG_CF_TRUE_COLOR我一直在enum _lv_color_format_t里找到,里适合的是LV_COLOR_FORMAT_RGB565。
两者区别如下:
LV_IMG_CF_TRUE_COLOR | 4 |
LV_COLOR_FORMAT_RGB565 | 0x12 |
怪不得出错,第一个移植8.3的程序我是直接将缺少的定义复制到头文件里,不只是名字的区别。看来是被LV_COLOR_SIZE误导了一下。
三:原因:
LV_COLOR_FORMAT_RGB565 != LV_IMG_CF_TRUE_COLOR
猜测可能lvgl官网的图片转换用的还是老版本的,不支持8.3。
四、解决:
解决如下:
const lv_img_dsc_t test = {
.header.cf = LV_COLOR_FORMAT_RGB565,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 160,
.header.h = 128,
.data_size = 20480 * LV_COLOR_SIZE/ 8,
.data = test_map,
};
于是图片可以正常显示了: