awtk/docs/lcd.md
2018-05-27 07:57:53 +08:00

2.9 KiB
Raw Blame History

LCD接口的三种实现方式

LCD是对显示设备的抽象提供了基本的绘图函数。自己实现一个LCD虽然不难但是需要花费不少功夫所以AWTK提供了几种缺省的实现利用这些缺省的实现在移植到新的平台时一般只需要很少的代码就行了。下面我们介绍一下几种常见的LCD实现方式

一、基于寄存器实现的LCD

在低端的嵌入式平台上内存只有几十K没有足够的内存使用framebuffer通常直接向寄存器中写入坐标和颜色数据。lcd_reg.inc提供了基于寄存器实现的LCD用它实现不同平台的LCD时只需要提供两个宏即可

  • set_window_func 设置要写入颜色数据的区域,相对于每次设置坐标而言,可以极大提高工作效率。
  • write_data_func 写入颜色数据。

下面是STMF103ze上LCD的实现这里把set_window_func定义为TFT_SetWindow把write_data_func定义为TFT_WriteData:

#include "gui.h"
#include "lcd_driver.h"

#include "base/mem.h"
#include "lcd/lcd_reg.h"

typedef uint16_t pixel_t;
#define set_window_func TFT_SetWindow
#define write_data_func TFT_WriteData

#include "blend/rgb565.inc"
#include "blend/pixel_ops.inc"
#include "lcd/lcd_reg.inc"

基于寄存器实现的实现有几个限制:

  • 由于内存和CPU性能的问题不提供任何类型的动画。
  • 由于读取LCD当前内容速度很慢所以需要与底色进行混合时由GUI自己处理(APP无需关心)。

二、基于framebuffer实现的LCD

这是在嵌入式平台上最常见的方式。一般有两个framebuffer一个称为online framebuffer一个称为offline framebuffer。online framebuffer是当前现实的内容offline framebuffer是GUI当前正在绘制的内容。lcd_mem_rgb565提供了rgb565格式的LCD实现lcd_mem_rgba8888提供了rgba8888格式的LCD实现它们都是在lcd_mem.inc基础上实现的要增加新的格式也是很方便的。

下面是STMF429上LCD的实现

extern u32 *ltdc_framebuf[2];
#define online_fb_addr (uint8_t*)ltdc_framebuf[0]
#define offline_fb_addr (uint8_t*)ltdc_framebuf[1]

lcd_t* platform_create_lcd(wh_t w, wh_t h) {
  return lcd_mem_rgb565_create_double_fb(w, h, online_fb_addr, offline_fb_addr);
}

三、基于vgcanvas实现的LCD

在支持OpenGL 3D硬件加速的平台上(如PC和手机)我们使用nanovg把OpenGL封装成vgcanvas的接口在vgcanvas基础之上实现LCD。lcd_vgcanvas.inc将vgcanvas封装成LCD的接口这里出于可移植性考虑并没有直接基于nanovg的函数而是基于vgcanvas的接口所以在没有GPU时如果CPU够强大也是可以基于agg/picasso去实现的LCD。

这种方式实现,一般不会在嵌入平台上使用,读者不需要关注它。

总结

以上几种实现方式基本上涵盖了最常用的场景所以在移植到新的平台时并不需要在实现LCD接口上费多少功夫。