移植UCGUI 调试笔记

移植UCGUI 调试笔记


刘志军 QQ259094936


在所有工作开始前首先得确认使用的显示屏与44B0 的连接是否正确。其次是设
置44B0 LCD 控制器的输出引脚。注意如果是256 色或是4 位双扫描的灰度液晶。
44B0 的PC 相应的端口应该设置成第三功能。也就是LCD 数据输出VD4—VD7 ,否则会出现显示图像会出现蓝白相间(本人移植的是256 色的西铁城K3247)。
对于256 色的LCD 来说一个象素就是8 位(一个字节的数据宽度)对应一个
象素,而44B0 是通过写显示缓冲区来实现在LCD 屏上显示图象的,也就是显示
缓冲区映射的是LCD 屏幕上的每一点!这一点很重要,接下来看一下程序中相关
的参量的意义:
#define LCD_CONTROLLER 0
指定lcd 自己不带控制器,输入到主显示区需要 ISR 或者硬件提供刷新
如: #define LCD_CONTROLLER 6963 表示 lcdslin(GUI 驱动名称)
使用的是6963 控制器.
#define LCD_BITSPERPIXEL 8
指定每个像素点的的位数为8 位(256 色的液晶3 位红色3 位绿色2 位蓝色
即332 模式.)
#define SCR_XSIZE (640)
#define SCR_YSIZE (480)// 屏幕的宽度(X)和高度(Y)
#define LCD_XSIZE (320)
#define LCD_YSIZE (240)// 实际屏幕宽度(X)和高度(Y)
#define M5D(n) ((n) & 0x1fffff)
//这里定义的M5D(n)是为有后面的Rlcdcon2 取后21 位进行频率微调(VLINE).
#if (LCD_TYPE==LCDCOLOR)
//这里的LCDCOLOR 是256 色的西铁城K3247
#define ARRAY_SIZE_COLOR (SCR_XSIZE/1*SCR_YSIZE)
//这实际是定义的虚拟屏幕的宽度(X)和高度(Y),就是说用 320X240 的屏
可以显示480X640 的图象的一部分,当然也可以定义的更大一些来显示更大的
图象。
#define ARRAY_SIZE_COLOR (SCR_XSIZE/1*SCR_YSIZE)
//这里将ARRAY_SIZE_COLOR 的大小定义为SCR_XSIZE/1*SCR_YSIZE,也就是48
0*640/1,因为ARRAY_SIZE_COLOR 是以BYTE(字节)存储的,按照前面说的LCD 的
显示规则,要想在256 色屏上完整显示大小为480X640 的图象,至少要有480X6
40 BYTE(字节)的显示缓冲才能对应480X640 个点,BYTE(字节)的数据宽度是8
位,因此只需要480X640/1 个字节型的数据就可以了。
unsigned int (*frameBuffer256)[SCR_XSIZE/4];
//在这里定义了显示缓冲区,它的大小是SCR_XSIZE/4,也就是640/4,在这里
frameBuffer256 是一个指针,它指向的是包含SCR_XSIZE/4 个于unsigned int
(32 位)类型的元素的数组;这时,SCR_XSIZE/4 的意义就显而易见了,因为数组类型是32 位的,只要有SCR_XSIZE/4 个元素即可以实现输出640 个象素的目的!
当然640 个象素只是480X640 图象大小的1/480,也就是虚拟屏幕上的一行,即
(一行的显示缓冲区);要对应480X640 大小的图象,至少需要480X640 大小显示
缓冲区,所以我们接着往下看,
void Lcd_Init(int depth)
//来到真正LCD 初始化的地方,在这里要着重理解的是其中分配内存的一句,其
他的很容易理解,就略去了。
if((U32)frameBuffer256==0)
//这一句是在检查是否已经为显示缓冲区.
frameBuffer256=(unsigned int (*)[SCR_XSIZE/4])malloc(ARRAY_SIZE_COL
OR)
//由于刚才已经定义了一个指针frameBuffer256,而且知道要显示640X480 的
图象至少需有640X480/1 字节大小的显示缓冲,通过malloc(ARRAY_SIZE_COLOR)
在内存中分出一块大小为ARRAY_SIZE_COLOR 字节,也就是刚好可以满足640X48
0 显示需要的显示缓存,也许有人要问了,刚才不是定义过frameBuffer256 了
吗?为什么现在又定义一次?第1 次定义了frameBuffer256 这个指针,是指向
数组类型的指针,而第2 次是将frameBuffer16 指向一个实际的内存区域,也就
是通过malloc(ARRAY_SIZE_COLOR)分配的,注意ARRAY_SIZE_COLOR 的大小是6
40X4800/1 个字节,(unsigned int (*)[SCR_XSIZE/4)是强制类转换;我理解这里在(*)后加一个[SCR_XSIZE/8]的用意,其实只是把

malloc(ARRAY_SIZE_COLOR)
分配的显示缓存分成大小为SCR_XSIZE/4 的块(并没有实际的意义,为了便于理
解可以这么考虑),也就是说frameBuffer256 每进行一次‘+1’的操作,实际
上是地址增加[SCR_XSIZE/4]个字,指针frameBuffer256 仍然是32 位的,这样
的话就共有(ARRAY_SIZE_COLOR /4(换算成U32 类型的))/(SCR_XSIZE/4)=
(640X480/4)/(480/4)=640 块,这说明什么呢?要是换个理解方式,用2 维
数组的概念来理解的话,也就是说frameBuffer256 指向的是一块[640][480/4]
的2 维空间。


有了以上的理解,可以看一个最基本的象素输出函数:
void _PutPixel256(U32 x,U32 y,U8 c)
{
if(x<SCR_XSIZE && y<SCR_YSIZE)
frameBuffer256[(y)][(x)/4]=( frameBuffer256[(y)][x/4] & ~(0xc000000
0>>((x)%8)*4) )
| ( (c)<<((8-1-((x)%4))*4) );
}
为了更方便形象地对应屏幕上指定位置(X,Y)的点,可以看到_PutPixel256
这个函数即是通过frameBuffer256[(y)][(x)/4],以2 维数组的形式来写显示
缓冲区的。
有了这些理解,对于其它图形函数的理解应该会更轻松了!第一步.配置UCGUI
下面看一下完整的LCD 控制器初始化程序。
#ifdef LCDCOLOR
if((U32)frameBuffer256==0)
{
frameBuffer256=(unsigned int (*)[SCR_XSIZE/4])malloc(ARRAY_SI
ZE_COLOR);
}
rLCDCON1=(0)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COL
OR<<12);
// disable,8B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
rLCDCON2=(LINEVAL)|(HOZVAL_COLOR<<10)|(10<<21);
//LINEBLANK=10 (without any calculation)
rLCDSADDR1= (0x3<<27) | ( ((U32)frameBuffer256>>22)<<21 ) | M5D
((U32)frameBuffer256>>1);
// 256-color, LCDBANK, LCDBASEU
rLCDSADDR2= M5D((((U32)frameBuffer256+(SCR_XSIZE*LCD_YSIZE))>>1))
| (MVAL<<21);
rLCDSADDR3= (LCD_XSIZE/2) | ( ((SCR_XSIZE-LCD_XSIZE)/2)<<9 );
//The following value has to be changed for better display.
//以下是颜色查表寄存器赋值//
rREDLUT =0xfdb96420; //红色
rGREENLUT=0xfdb96420; //绿色
rBLUELUT =0xfb40; //蓝色
//以下是给抖动模式寄存器赋值
rDITHMODE=0x0;
rDP1_2 =0xa5a5;
rDP4_7 =0xba5da65;
rDP3_5 =0xa5a5f;
rDP2_3 =0xd6b;
rDP5_7 =0xeb7b5ed;
rDP3_4 =0x7dbe;
rDP4_5 =0x7ebdf;
rDP6_7 =0x7fdfbfe;
//使能显示
rLCDCON1=(1)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COL
OR<<12);
// enable,8B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
#endif
}
在移植还得注意的是显示开关的控制权交给了GUI 所以不同厂家的板子还要
根据电路原理图改一下控制I/O 端口。本例代码中使用的端口是PC8 端口。
//显示关
void LCD_Off (void) {
Delay(100);
rPDATC = ( rPDATC | (1<<8) );
Delay(100);
刘志军 QQ259094936 E-mail:[email protected] 创建时间:2006-11-6 8:35:00
}
显示开
void LCD_On (void) {
Delay(100);
rPDATC = ( rPDATC & (~(1<<8)) );
Delay(100);
以上是本人在移植UCGUI 过程中遇到的一些问题,在网上搜索了相关的资
料,发现一些论坛上对于这个问题的讨论也不少,但都没有太详细的解答,参考
了相关的书和各种资料和大家的讨论后的结果。我想把我的一点心得写出来和大
家分享,希望对初学者有一点帮助有什么不对的地方,欢迎大家一起讨论!我是
学硬件出生的。GUI 上层的软件API 调用涵数请查找相关资料。

你可能感兴趣的:(api,qq,存储,byte,图形,delay)