原创 S3C44B0 LCD控制器总结

2008-12-1 12:51 5503 4 4 分类: MCU/ 嵌入式

S3C44B0 LCD控制器总结<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


  朋友从淘宝上买了块2手320*240的真彩Lcd,叫我测试一下。彩屏本人还是第一次用,本人用一块恒丰的arm7,对齐进行了测试,写下一点总结。


S3C44B0控制器的一些寄存器知识就不写了,在数据手册上都写得很详细,主要写下本人遇到的一些困难和值得注意的地方。


查找表:


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级了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


b07a601b-cdc8-470c-80ee-0deabcca1add.jpg7f815c89-200d-4bcf-a72e-a92b03548464.jpg


0136ec5f-e502-4144-bec8-88d67419dfbf.jpgdf453684-08df-4794-8dde-594074b695ae.jpg

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条