LCD原理
LCD屏介绍,800×480 ,液晶显示,采用液晶显示像素点。通过点亮这个液晶屏,
LCD屏的连接次序,LCD使用排线连接底板,底板通过插针连接核心板。
通过电子枪改变偏振,之后通过引线连接到芯片上,之后传入frambuffer中,再传到lcd控制器中,我们的屏使用的是RBG的方式,一个颜色占用8位,但是我。们的机器是32位的,所以我们为了方便读取数值,所以给里面加8位的傀儡值
电子枪的移动:有一条VCLK时钟线与LCD相连,每发出一次CLK(高低电平),电子枪就移动一个像素。
电子枪怎么到下一行的:有一条HSYNC信号线与LCD相连,每发出一次脉冲(高低电平),电子枪就跳到下一行。
电子枪如何得知应回到原点:有一条VSYNC信号线与LCD相连,每发出一次脉冲(高低电平),电子枪就跳到原点
总结最终控制的时序引脚是VCLK HSYNC VSYNC,需要去底板原理图去寻找数据引脚和时序引脚
我们可以看见在HS开始的时候输出低电频做准备,保证了周期
我们看图可以看见打点时钟DCLK在上上升沿信号出现的时候,将数值放到了屏幕上,所以上升沿有效
HS当HYNC高电平的时候有效,DE是高电平有效
上图是一个列周期,VS垂直同步信号是高电平有效
我们需要的水平打在外面的点和垂直打在屏前和屏后的点,这里面都给了我们推荐数值,我们后面要在寄存器上去设置他们
GPIO的配置
我们通过三根核心线的找到了LCD对应的引脚
下面我们对他来初始化,将他的28个引脚都改为LCD模式
void gpio_init(void)
{
GPF0CON = 0x22222222;
GPF1CON = 0x22222222;
GPF2CON = 0x22222222;
GPF3CON &= ~0xffff;
GPF3CON |= 0x2222;
}
LCD寄存器的配置
这里对VIDCON0进行配置,我们需要修改他的【28-26】为RGB的方式,还有【18】位为0,使用并行的方式
这里我们需要对时钟进行配置我们要的打点频率为33.3hz,通过上面的公式可以求得,就是我们前面提到的一根核心的时钟线来控制打点的移动
我们可以看到他是通过SCLK MPLL_USER_T这个接口连接到时钟,并通过DIV分频输入到SCLK_FIMD0,我们可以再往前看看他的来源
是通过SCLK-MPPL或者晶振通过PPL放大得到的,这里我们查S70屏的数据,希望我们的输出频率为33.3hz,之后再通过旁路模式输入,我们可以得到上面
33.3 =1*100(CLKVAL_F+1)从而得到CLKVAL_F =2
下面这个2个引脚需要配置为1,让他们都有效
//选择MPLL_USER_T 800MHZ作为整个LCD的时钟来源
CLK_SRC_LCD0 &= ~0xf;
CLK_SRC_LCD0 |= 0x6;
//选择7+1分频,将MPLL_USER_T的800分成100M给LCD的打点 垂直 水平
CLK_DIV_LCD &= ~0xf;
CLK_DIV_LCD |= 0x7;
//选择旁路模式,跳过FIMD的选择值,让FIMD =1
//配置LCD控制器参数 vidcon0 0x2<<6 对100mhz进行3分频得到厂商33.3M作为打点时钟
//0-1位是LCD控制器的总开关,留在最后配置,最后启动LCD控制器
VIDCON0 &=~(0xff<<6);
VIDCON0 |=0x2<<6;
//选择旁路模式,跳过FIMD的选择值,让FIMD =1
LCDBLK_CFG |= 1 << 1;
通过前面的分析我们应该将第9位配我1让他一直运行,第7位配1为高电平有效,再第6位为1,第五位VYNC极性反转,因为我们对比我的说明书发现和出场的相反,可参考下图
//根据厂商说明书,对比三星的手册,配置各个关键信号的极性
//VIDCON1 9-10 0X1//保持所有周期一直打点时钟 7 0X1
//配置打点时钟上升沿有效 6 0x1 翻转HYNC极性5 0x1 翻转SYNC垂直同步信号极性
VIDCON1 = (1<<9)|(1<<7)|(1<<6)|(1<<5);
//设置打点的行前数据和行后数据
//根据厂商说明书,对比三星手册,配置LCD输入输入的垂直信号时序。两者一致才能显示
// VDITCON0 配置 VBPD+1 = TVB - TVPW = 23-10 = 13 VBPD = 13-1 = 12 12<<16
// VFPD+1 = 厂商的 tvfp =22 VFPD = 22-1 21 21<<8
// VSPW+1 = 厂商的TVPW = 10 VSPW = 10-1 = 9 9<<0
VIDTCON0 = (12 << 16) | (21 << 8) | (9 << 0);
//水平信号时序
//VDITCON1 HBPD+1 = THB - HPW(厂商) = 46-20= 26 HBPD = 26-1 = 25 25<<16
// HFPD+1 = thfp = 210 HFPD = 210 -1 = 209 209 << 8
// HSPW+1 = THPW(厂商) = 20 HSPW = 20-1=19 19<<0
VIDTCON1 = (25 << 16) | (209 << 8) | (19 << 0); //
//VIDTCON2 配置LCD大小尺寸 hd700 800*1280 1280 = val+1 val = 1279 << 11 水平 val=799 799 << 0
VIDTCON2 = (479 << 11) | (799 << 0);//S700 479<<11 | 799<<0
//win0窗口配置
win0_init();
窗口寄存器的配置
/*设置按字交换,显示数据的格式为BPP888, 使能显示*/
WINCON0 = (1 << 15) | (0xb << 2) | (1 << 0);
//信道0选择窗口,窗口选择信道
WINCHMAP2 &= ~(0x7 << 16);
WINCHMAP2 |= (0x1 << 16);
WINCHMAP2 &= ~0x7;
WINCHMAP2 |= 0x1 << 0;
//开启通道0
SHADOWCON &= ~(1 << 5);
SHADOWCON |= 1;
/*设置LCD要显示的左上角坐标和右下角坐标*/
VIDOSD0A = (0<<11)|(0<<0);
VIDOSD0B = (799 << 11) | (479 << 0);
VIDOSD0C = 480*800; /*设置显示区域的数据大小,单位为字*/
最后将面板点亮,选择一个颜色,通过main函数调用,最基本的点亮完成
void win1_draw_point(int x, int y, int col)
{
unsigned int *p = (void *)WIN1FRAMBUFFER_0;
*(p + y * 800 + x) = col;
}
void win0_cls(int col)
{
int i,j;
for(i = 0; i < 480; i++){
for(j = 0; j < 800; j++){
win0_draw_point(j,i,col);
}
}
}
关键色的配置
/*W1KEYCON0: win1关键色及混杂模式配置寄存器
[26] 1 混杂开关 [25] 关键色开关 [24] 关键色指向前背景控制 0 作用于背景 1 作用于前景 [23 -0 ] 关键色的色值*/
W1KEYCON0 |= (0x1 << 26) | (0x1 << 25) | (0x0 << 24) | (col << 0);
/*W1KEYCON1:指定透明效果的关键色的值*/
W1KEYCON1 &=~ 0xffffff;
W1KEYCON1 |= (col << 0);