移植UCGUI 调试笔记
2008-09-08 21:55
309 查看
移植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:lzj19851109@163.com 创建时间:2006-11-6 8:35:00
}
显示开
void LCD_On (void) {
Delay(100);
rPDATC = ( rPDATC & (~(1<<8)) );
Delay(100);
以上是本人在移植UCGUI 过程中遇到的一些问题,在网上搜索了相关的资
料,发现一些论坛上对于这个问题的讨论也不少,但都没有太详细的解答,参考
了相关的书和各种资料和大家的讨论后的结果。我想把我的一点心得写出来和大
家分享,希望对初学者有一点帮助有什么不对的地方,欢迎大家一起讨论!我是
学硬件出生的。GUI 上层的软件API 调用涵数请查找相关资料。
刘志军 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:lzj19851109@163.com 创建时间:2006-11-6 8:35:00
}
显示开
void LCD_On (void) {
Delay(100);
rPDATC = ( rPDATC & (~(1<<8)) );
Delay(100);
以上是本人在移植UCGUI 过程中遇到的一些问题,在网上搜索了相关的资
料,发现一些论坛上对于这个问题的讨论也不少,但都没有太详细的解答,参考
了相关的书和各种资料和大家的讨论后的结果。我想把我的一点心得写出来和大
家分享,希望对初学者有一点帮助有什么不对的地方,欢迎大家一起讨论!我是
学硬件出生的。GUI 上层的软件API 调用涵数请查找相关资料。
相关文章推荐
- STM32移植UCGUI3.90笔记
- [RK3288][Android6.0] 移植笔记 --- RK818配置不正确导致无法开机调试
- TQIMAX6q调试笔记一:lvds屏的移植
- [RK3288][Android6.0] 移植笔记 --- 固件无法下载到eMMC调试
- [IMX6Q][Android5.1]移植笔记 --- 调试串口只能输出不能输入
- STM32移植UCGUI3.90笔记
- android TP驱动移植调试笔记
- android TP驱动移植调试笔记(转)
- wifi(rtl8188eu)移植及调试笔记
- Linux-3.4.2内核移植调试笔记
- cortex_m3_stm32嵌入式学习笔记(十三):USMART调试组件移植(调试神器)
- U-Boot-2009-03移植笔记(调试篇)
- linux内核移植-内核调试工具KGBD、DDD、GDB移植笔记
- TQIMAX6q调试笔记三:EETI的egalax-i2c触摸屏移植
- linux学习笔记一:在linux编写及调试c语言
- u-boot-1.1.6移植到mini2440笔记
- 学习笔记 --- LINUX 驱动调试之使用proc
- 大数据学习笔记:编写脚本分发配置,数据分布,以及使用代码打印调试信息
- iOS开发笔记18:一些编译、开发调试、打包的细节整理
- AT91RM9200Linux移植笔记(二)-移植u-boot-1.1.6