S3C44B0 LCD控制器总结<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
朋友从淘宝上买了块2手320*240的真彩Lcd,叫我测试一下。彩屏本人还是第一次用,本人用一块恒丰的arm7,对齐进行了测试,写下一点总结。
S3C44B0控制器的一些寄存器知识就不写了,在数据手册上都写得很详细,主要写下本人遇到的一些困难和值得注意的地方。
1 查找表:
S3C44B0控制器支持的最大灰度级是16级。然而实际应用中也可以用4级。用4级的原因是因为可以大大减少存储空间的开销,因为16级灰度要用4位表示,而4级灰度只要用2位表示即可。在一些特殊的场合,虽然只用到了4级灰度,但是这4级可能不是相对16级线性缩小的。例如原本16级灰度的情况下,15级色位黑色,0级色为白色,其余颜色线性的介于这两级之间。而变成了4级灰度的情况,自己就可以根据需求非线性的配置查找表。例如可以把4级色分配成一个最亮,最暗,和普通文字色三种。根据这样的需求可以配置3级色为黑色(最暗),相当于16级中的15级色。0级色为白色(最亮),相当于16级色中的0级色。1级和2级都设置为原来16级中的11色作为普通文字色。所以说查找表是适应这种非线性要求的一种很好的方法。以上例子中只要按以上需求设置好BULELUT寄存器即可。0级灰度用BLUEVAL[3:0]的值表示,设置为0000。3级灰度用BLUEVAL[15:12]的值表示,设置位1111。1级和2级用分别对应BLUEVAL[7:4],BLUEVAL[11:8]的值,都设置为1011。
而对于8位彩色模式下,则是用8位中的高3位表示R的灰度级,接着的3位表示G的灰度级,最低2位表示B的灰度级。这就意味着R和G都有8中灰度级别,而B只有4级灰度级别。由于其都低于16级所以也要配置查找表。对应的寄存器如下:
常用是如下配置:
rREDLUT =0xfdb96420;
rGREENLUT=0xfdb96420;
rBLUELUT =0xfb40;
呵呵,如果理解了的话,自然可以得出结论16级的模式下无需配置查找表。
2抖动算法
记得曾今刚学单片机的时候做了个PWD(用来控制直流电机的),脉冲宽度调制的实验。试验中通过控制单片机输出的矩形波的占宽比(高电平和周期的比列)来调节LED的发光亮度。同样这个原理就用在了LCD的显示灰度级别上了。16级的灰度,要用4bit才能表示,但是LCD控制器只用1bit的输出就搞定了。256的彩色要用8bit才能表示,而控制器只用了RGB3bit。它的原理就是用了所谓的抖动原理。通过控制驱动每个像素点的矩波的占宽比即可控制其灰度。
下面是初始化LCD控制器一些寄存器的代码有详细注释(只有彩色模式下的)
#define ARRAY_SIZE_MONO (SCR_XSIZE/8*SCR_YSIZE)//开辟的缓存显示空间的总大小的计算:行*列*每个像素点占的位数/8
#define ARRAY_SIZE_G4 (SCR_XSIZE/4*SCR_YSIZE)//因为在用malloc()申请内存空间时,其单位是字节(8bit)
#define ARRAY_SIZE_G16 (SCR_XSIZE/2*SCR_YSIZE)
#define ARRAY_SIZE_COLOR (SCR_XSIZE/1*SCR_YSIZE)
unsigned int (*frameBuffer1)[SCR_XSIZE/32];//开辟与每一行对应的数组指针,
unsigned int (*frameBuffer4)[SCR_XSIZE/16];//每一行为一个数组,此数组的大小与行中像素点的数目有关
unsigned int (*frameBuffer16)[SCR_XSIZE/8];//大小计算:行像素点数目*每个像素点所占的位数/32
unsigned int (*frameBuffer256)[SCR_XSIZE/4];//除以32的原因是,数组中的每个元素占用4*8bit
void Lcd_Init(int depth)
{
//320x240 1bit/1pixel LCD
...............
case 256:
if((U32)frameBuffer256==0)
{
//The total frame memory should be inside 4MB.
//For example, if total memory is 8MB, the frame memory
//should be in 0xc000000~0xc3fffff or c400000~c7fffff.
//But, the following code doesn't meet this condition(4MB)
//if the code size & location is changed..
frameBuffer256=(unsigned int (*)[SCR_XSIZE/4])malloc(ARRAY_SIZE_COLOR); //开辟显存空间
}
rLCDCON1=(0)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COLOR<<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_COLOR<<12);
// enable,8B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
break;
default:
break;
}
rPDATC = ( rPDATC & (~(3<<8)) );//water add ,使能lcd
}
这块液晶的效果不是很好,但性价比还是很高哦,显示的比较清晰(山寨手机拍的),缺点就是在初始化后,液晶还要等将近2分钟才能变得清晰。当然用来给学习是足够了哦。下面是效果图,下次再把其显示图片,显示汉字,显示ascii字符的程序拿来总结。时候不早了,还要养好精神过6级了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
文章评论(0条评论)
登录后参与讨论