电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

S3C44B0 LCD控制器总结

S3C44B0 LCD控制器总结

  朋友从淘宝上买了块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级了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

博主
xiaojiewen@baite-group.com
water的学习笔记
有志者事竟成,破釜沉舟,百二秦关终属楚; 苦心人天不负,卧薪尝胆,三千越甲可吞吴!
点击跳转