tiny6410裸机实验第9章--------------LCD(原理及源代码)

时间:2021-12-11 14:48:32

【说明】

            这一章我们来介绍一个很好玩的东西,那就是LCD,也就是我们开发板上的显示屏了,这个要理清一个概念,那就是LCD和触摸屏是完全没关系的两个设备,只不过他们一般都做在一起而已,我们这节只介绍LCD,没有触摸屏的内容。由于我用得是友善的TINY6410,而友善公司把触摸屏和LCD背光都做成了1线的,也就是一般的背光控制和触摸屏原理都不适用于这个6410。所以我们无视背光控制,单纯学习LCD的显示部分。

 

 

【控制器】

             S3C6410自带有LCD控制器,所以操作LCD的事就交给他吧,当然,在让它控制LCD前我们需要设置控制器,比如分辨率,时序参数等等,当都设置好了之后,我们还需要分配一块内存给他当做显存,它就从里面取数据然后用LCD显然。

 

【硬件原理】

             LCD的显然过程可以想象成有一把电子枪,从一行的第一个像素开始一个像素一个像素把颜色打到屏幕上,如果一行打完了,就到下一行,如果所有行打完了,就回到第一行继续打,   由于速度很快,所以人眼看起来就好像图像是一直存在的,其实是一个像素一个像素打出来的。

 

【原理图】

               tiny6410裸机实验第9章--------------LCD(原理及源代码)

               1)VD都是数据线,用来传输像素,一个像素用24位表示

               2)HSYNC是当电子枪打到一行的最后面的时候,用来让电子枪回到最左边用的同步信号。

               3)VSYNC是当电子枪打完最后一行后,用来让电子枪回到最上边的同步信号。

               4)VDEN 是数据有效信号,当其有效的时候枪口才是打像素,但是不影响电子枪移动。

               5)VCLK 时钟信号,来一个信号,打一个像素

 

【怎么写】

               1】设置LCD控制器

                           1)分辨率

                           2)时间参数

                           3)极性(下面就知道是什么了)

               2】分配显存

                          1)告诉LCD控制器

               3】设置像素

                          1)颜色格式

 

【详细设置】

                  6410手册里面给出了初始化控制器的步骤如下

                 tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   

                 设置GPIO

                       在进行上面的设置之前我们要设置一下GPIO管脚配置成LCD功能。

                       由主板图知道,我们需要配置GPI和GPJ,关于GPIO的配置我想就不用再多说了吧。。。。。。

                       下面就按上图来

       1】固定值

                       第1步骤就是往寄存器里设置固定的值,我们就按它的要求设置就可以了

                       tiny6410裸机实验第9章--------------LCD(原理及源代码)

                       tiny6410裸机实验第9章--------------LCD(原理及源代码)

    2】像素模式

                       我们要使用RGB模式。。所以应该设置成01

                    tiny6410裸机实验第9章--------------LCD(原理及源代码)

                      tiny6410裸机实验第9章--------------LCD(原理及源代码)

                     tiny6410裸机实验第9章--------------LCD(原理及源代码)

    3】配置VIDCON0寄存器

                      这个寄存器东西比较多,我们一个一个来理解 

                     tiny6410裸机实验第9章--------------LCD(原理及源代码)

                  1)使能,显然要设置成11

                      tiny6410裸机实验第9章--------------LCD(原理及源代码)

                    2)选择时钟源,我们使用HCLK

                     tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   3)时钟分频,HCLK是133MHZ不符合我们的LCD要求,所以我们需要用CLKVAL来分频,所以要设置下面这些位

                       分频系数应该为多少下面会说的

                   tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   分频为多少呢

                    看LCD数据手册,里面要求得时钟频率如下,所以我们分频系数可以设置为3,即133 / (3 + 1) =  33.3

                    tiny6410裸机实验第9章--------------LCD(原理及源代码)

                 4)设置RGB的顺序,我们的是按R-G-B的顺序来的

                  tiny6410裸机实验第9章--------------LCD(原理及源代码)

                    tiny6410裸机实验第9章--------------LCD(原理及源代码)

         

        4】配置VIDCON1寄存器

                    在这个寄存器中,我们需要设置一下同步信号的极性

                    tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   那我们怎么知道要不要设置为1呢,也就是要不要反转极性呢,看下面2张图

                   在6410手册中的时序图是高脉冲

                   tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   而在LCD数据手册中却是低脉冲,所以要反转

                   tiny6410裸机实验第9章--------------LCD(原理及源代码)

 

             5】配置VIDTCON0寄存器和VIDTCON1寄存器,以及VIDTCON2寄存器

                     由于我们是用RGB模式,所以手册中第5,6两个步骤中的寄存器我们不用设置的,我们直接设置VIDTCON0寄存器

                     以及VIDTCON1寄存器,这两个寄存器都是用来设置时序的,VIDTCON2设置屏幕长宽

                     tiny6410裸机实验第9章--------------LCD(原理及源代码)

                     tiny6410裸机实验第9章--------------LCD(原理及源代码)

                    tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   我们现在来分析一下其中要设置为多少

                    首先看下上面各个参数在S3C6410手册提供的时序图中的意思

                    tiny6410裸机实验第9章--------------LCD(原理及源代码)

                   对比一下LCD提供的时序

                   tiny6410裸机实验第9章--------------LCD(原理及源代码)

                         tiny6410裸机实验第9章--------------LCD(原理及源代码)

                         然后再看看LCD数据手册给我们的各个参数的数据

                        tiny6410裸机实验第9章--------------LCD(原理及源代码)

                        显然各个参数就可以一一对上号了。

                        1)HSPW = thpw

                        2)HBPD = thb - thpw

                        3)HFPD = thfp

                        4)VSPW = tvpw

                        5)VBPD = tvb

                        6)VFPD = tvfp

 

                        现在来设置一下屏幕的长宽

                       tiny6410裸机实验第9章--------------LCD(原理及源代码)

                       上面的数据图中已经给出了,应该是480和800

                   

           6】设置WINCON0寄存器

                       LCD控制器支持5个窗口,我们只用第一个窗口所以我们只要设置WINCON0就可以了

                       tiny6410裸机实验第9章--------------LCD(原理及源代码)

                       首先我们要使能,然后选择R8-G8-B8格式的像素

                       tiny6410裸机实验第9章--------------LCD(原理及源代码)

 

               7】设置VIDOSD0A,VIDOSD0B,VIDOSD0C

                        其实就是设置一下四个角的坐标而已,另外就是设置一下窗口大小,也就是有多少像素

                        tiny6410裸机实验第9章--------------LCD(原理及源代码)

                        tiny6410裸机实验第9章--------------LCD(原理及源代码)

                       tiny6410裸机实验第9章--------------LCD(原理及源代码)

                

               8】设置显存

                       终于到达最后一步了,也就是给一个显存给控制器,因为是裸机所以我们就直接给它一块不用得内存就可以了

                       tiny6410裸机实验第9章--------------LCD(原理及源代码)

                        tiny6410裸机实验第9章--------------LCD(原理及源代码)

 

【初始化源代码】

                      人生最蛋疼的事,就是尼玛分析了半天,,,结果代码写出来就一点点。。。

// 初始化LCD
void lcd_init(void)
{
// 配置GPIO用于LCD相关的功能
GPICON = 0xAAAAAAAA;
GPJCON = 0x00AAAAAA;

// normal mode
MIFPCON &= ~(1<<3);

// RGB I/F
SPCON = (SPCON & ~(0x3)) | 1;

// 配置VIDCONx,设置接口类型、时钟、极性和使能LCD控制器等
VIDCON0 = (0<<26)|(0<<17)|(0<<16)|(3<<6)|(0<<5)|(1<<4)|(0<<2)|(3<<0);
VIDCON1 |= 1<<5 | 1<<6;

// 配置VIDTCONx,设置时序和长宽等
// 设置时序
VIDTCON0 = VBPD<<16 | VFPD<<8 | VSPW<<0;
VIDTCON1 = HBPD<<16 | HFPD<<8 | HSPW<<0;
// 设置长宽
VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);


// 配置WINCON0,设置window0的数据格式
WINCON0 |= 1<<0;
WINCON0 &= ~(0xf << 2);
WINCON0 |= 0xB<<2;

// 配置VIDOSD0A/B/C,设置window0的坐标系
#define LeftTopX 0
#define LeftTopY 0
#define RightBotX 800
#define RightBotY 480
VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);
VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);
VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1);

// 置VIDW00ADD0B0和VIDW00ADD1B0,设置framebuffer的地址
VIDW00ADD0B0 = FRAME_BUFFER;
VIDW00ADD1B0 = FRAME_BUFFER + (((HOZVAL + 1)*4 + 0) * (LINEVAL + 1)) & (0xffffff);
}


 

【控制像素】

                在任意一点画一个像素的函数

          

// 描点
void lcd_draw_pixel(int row, int col, int color)
{
unsigned long * pixel = (unsigned long *)FRAME_BUFFER;

*(pixel + row * COL + col) = color;

}