2018-05-27 07:57:53 +08:00
|
|
|
|
## 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接口上费多少功夫。
|
|
|
|
|
|
|
|
|
|
|
2018-05-27 06:44:02 +08:00
|
|
|
|
|