这一次的话算是花了一下午差不多解决了一个问题,具体我是用 stm32f103c8t6(20k RAM, 128k Flash) 移植的LVGL库(屏幕是240x240的st7789, 因为RAM的buf不太够所以缩小了显示面积)
直接切入主题: 如果出现花屏问题, 这个问题出在你自定义编写的lv_set_flush函数中,
对于这个函数的编写, 官方的文档给出了一个示例, 但是这个示例有问题, 按照这个示例编写就会产生花屏现象。
lv_display_set_flush_cb(display, my_disp_flush);
void my_disp_flush(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
int32_t x, y;
/*It's a very slow but simple implementation.
*`set_pixel` needs to be written by you to a set pixel on the screen*/
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
set_pixel(x, y, *color_p); // 我的错误代码中使用 lcd_write_data(lv_color_to_u16(*color_p)) 类似语句;
color_p++;
}
}
lv_display_flush_ready(disp); /* Indicate you are ready with the flushing*/
}
正确的方法如下:
解决前我是从颜色位数考虑是否出了问题的, 后来就到 lv_display.h 中寻找对应的颜色设置, 于是找到了下面的定义。
typedef void (*lv_display_flush_cb_t)(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
typedef void (*lv_display_flush_wait_cb_t)(lv_display_t * disp);
可以看出, 这个参数设置和上面的 my_disp_flush
中最后一个参数明显不同, 因此实际上给出的是一个 uint8_t
类型的数组
因此可以改为如下的代码
// 每一次接受两个字节的数据并拼接后发送
/* Render the screen's content */
/* @caution: lv_color_t is a 8 bit-pixel map */
static void disp_flush(lv_display_t *disp, const lv_area_t* area, uint8_t* px_map){
int32_t w = area->x2 - area->x1 + 1;
int32_t h = area->y2 - area->y1 + 1;
Address_set(area->x1, area->y1, area->x2, area->y2);
int32_t x, y;
for (y = 1; y <= h ; y++){
for (x = 1; x <= w; x++){
// lv_color_to_u16(*color_p);
uint16_t colordata = (uint16_t)(*px_map) << 8;
px_map ++;
colordata |= (*px_map);
LCD_WR_DATA(colordata);
}
}
lv_display_flush_ready(disp); /* Indicate you are ready with the flushing*/
}
在9.1版本中, 在 lv_port_display_init 最后加上lv_display_set_flush_cb(display, disp_flush);
即可初始化完成。
修复之后, 测试结果如下:
使用下面代码 (目前我那个控件绘制还有问题, 所以只做显示颜色测试)
lv_obj_set_style_bg_color(lv_screen_active(), lv_palette_main(LV_PALETTE_BLUE), LV_PART_MAIN);
修复效果如下(已经正常绘制了, 可能手机拍屏有点花):