S5PV210 LCD控制器

来源:互联网 发布:ifashion淘宝怎么认证 编辑:程序博客网 时间:2024/06/06 09:05

LCD简介

LCD(Liquid Crystal Display) ,即液晶显示屏,是一种采用了液晶控制透光度技术来实现色彩的显示器,LCD 有很多种类型,常见的有 :

  1. STN(超扭曲向列),它的特点是功耗低,但亮度不足,响应时间长;(1602那种类型的)
  2. TFT(薄膜晶体管),它的特点是响应时间短,画面清晰,但功耗稍高,(自己实验用的应该是这个类型的,这个类型当作计算机液晶显示设备)。
  3. LTPS(低温多晶硅),各方面性能优越,但技术要求高;
  4. OLED(有机发光二极管),各方面性能优越,但技术要求高。

S5PV210 LCD 控制器


S5PV210 的 LCD 控制器由一个逻辑单元组成,它的作用是:把 LCD 图像数据从一个位于系统内存的 video buffer 传送到一个外部的 LCD 驱动器接口
LCD驱动接口支持 3 种接口:
  •    RGB 接口:(自己用的使这种)
  •   indirect-i80 接口
  •   UV 接口
S5PV210 的 LCD 控制器支持多种颜色格式,例如 

  • RGB (1BPP 到 24BPP)
  • YCbCr 4:4:4 (只有本地总线) 

LCD 控制器可以通过编程满足不同的需求, 即满足水平、垂直方向的像素数目,满足数据接口的数据线宽度、接口时序和刷新速率

S5PV210 LCD 关键特性介绍

总线接口 : AMBA  AXI  64 位主模式 /AHB  32 位从模式,本地视频总线
(YCbCr/RGB).
视频输出接口:RGB 接口(并行 24 位,串行 8 位) ,Indirect i80 接口,YUV
接口.
  • 支持 i80/RGB 双输出模式
  • 支持 8/16/24 多种 BPP 模式
  • 4/8/16 位的可编程 DMA
  • 支持 256 x 32 位的调色板
  • 支持最大为 16MB 的虚拟屏幕 

信号类型

  • VSYNC:垂直同步信号,每个 VSYNC 信号表示一帧数据的开始.
  •  HSYNC: 水平同步信号,每个 HSYNC 信号表示一行数据的开始.
  •  VCLK:  像素时钟信号,每个 VCLK 信号表示一个像素数据.
  •  VDEN:  数据使能信号.
  •  VD:  Video Data,数据信号. 

S5PV210 LCD 控制器子模块概述

LCD 控制器模块由 VSFR,VDMA,VPRCS,VTIME 以及 video clock 组成。为了配置 LCD 显示控制模块,VSFR 有 121 个可编程寄存器集,一个 gamma LUT 寄存器集(64 个寄存器),一个 i80 命令寄存器集(12 个寄存器)和 5 个 256 x 32调色板内存。


VDMA 是一个专用的显示 DMA 通道,用于才能够 frame 内存里传输视频数据到VPRCS。利用特殊的 DMA,用户可以在没有 CPU 干涉的情况下传输视频数据到屏幕上示。

VPRCS 从 VDMA 中接收视频数据并在转换视频数据为合适的数据格式后(例如:8BPP 或 16BPP 模式) 通过 RGB_VD 或 SYS_VD 端口传送到显示设备上(如: LCD)

VTIME 由可编程逻辑模块组成,在不同的 LCD 驱动下支持各种接口时序和波特率。 VTIME 模块产生 RGB_VSYNC, RGB_HSYNC, RGB_VCLK, RGB_VDEN SYS_CS0,SYS_CS1,SYS_WE 等等信号。

信号时序图分析


210手册(1207页)
  • VSYNC 的有效启动脉冲是高电平有效
  • VSYNC 脉冲宽度为(VSPW+1)个 HSYNC 信号周期,在这个周期内数据无效
  • VSYNC 有效启动脉冲后还要经过(VBPD+1)个 HSYNC 信号周期,有效的数据才会出现
  • 跟随着连续发出(LINEVAL+1)行的有效数据
  • 最后经过(VFPD+1)个无效行,完整的一帧数据就传输结束,紧接着下一次VSYNC 启动脉冲才能发出.

  • HSYNC 的有效启动脉冲是高电平有效.
  • HSYNC 脉冲宽度为(HSPW+1)个 VCLK 信号周期,在这个周期内像素数据无效.
  • HSYNC 有效启动脉冲后还要经过(HBPD+1)个 VLCK 信号周期,有效的像素数据才会出现.
  • 跟随着连续发出(HOZVAL+1)个的有效像素数据.
  • 最后经过(HFPD+1)个无效数据,完整的一行数据就传输结束,紧接着下一次HSYNC 启动脉冲才能发出.
基本模式是类似的。

参数的计算

查找数据手册:S70-AT070TN92.pdf,13和14页



根据表格和图计算相应参数





垂直信号参数

tvpw 可取 typ.值为 10(中间值) ,而 tvpw 的值就是 VSYNC 的脉冲宽度,也就是说 VSPW + 1 = 10,所以 VSPW = 9

tvb 可取 typ.值为 23,而 tvb 的值是 VSYNC 前面经过(VSPW + 1 )+(VBPD + 1)

tvfp 可取 typ.值为 22,而 tvfp 的值是后面经过(VFPD + 1)的无效行,也就是说 tvfp = VFPD + 1= 22,所以 VFPD = 21

tvd 可取 typ.值为 480, 而 tvd 的值就是 (LINEVAL+1) ,其实就是 y 轴的 LCD分辨率,也就说 tvd = (LINEVAL+1)= 480,所以 LINEVAL = 479的无效行,也就是说 tvb =

 (VSPW + 1 )+(VBPD + 1) = 23,相当于 10 + VBPD + 1 = 23,所以 VBPD = 12

水平信号参数

thpw 可取 typ.值为 20(中间值),而 thpw 的值就是 HSYNC 的脉冲宽度,也就是说 HSPW + 1 = 20,所以 VSPW = 19.

thb 可取 typ.值为 46,而 tvb 的值是 VSYNC 前面经过(HSPW + 1 )+(HBPD + 1)的无效行,也就是说 thb= (HSPW + 1 )+(HBPD + 1) =  46,相当于 20 + VBPD + 1 = 46,所以 HBPD = 25.

thfp 可取 typ.值为 210,而 thfp 的值是后面经过(HFPD + 1)的无效行,也就是说 thfp = HFPD + 1= 210,所以 VFPD = 209。

时钟频率计算

RGB_VCLK (Hz) = HCLK / (CLKVAL+1), CLKVAL >= 1


Frame Rate = 1/ [ { (VSPW+1) + (VBPD+1) + (LIINEVAL + 1) + (VFPD+1) } x 
{(HSPW+1) + (HBPD +1)  + (HFPD+1) + (HOZVAL + 1) } x { ( CLKVAL+1 ) / 
( HCLK ) } ]

数据格式

14BPP和24BPP,数据存储的地址方式不同,具体查手册。

硬件端口功能


该液晶屏接口有 45Pin,其中 VD0~VD23 是数据信号线引脚,VDEN 是数据信号使能引脚,VSYNC 是垂直同步信号引脚,HSYNC 是水平同步信号引脚,VCLK 是像素时钟信

号引脚,Xi2SCL2,Xi2SDA2 分别是 I2C 的 SCL、SDA 引脚,在电容屏的触摸中会用到。 XENIT14、 XEINT15 引脚是外部中断引脚。



程序的编写

根据210手册1218页,OVERVIEW OF PROGRAMMER’S MODEL里面提到了23个寄存器的作用,根据这个来编写程序。

一共9步,在程序里体现。
#define  GPF0CON( *(volatile unsigned int *)0xE0200120 )#define  GPF1CON( *(volatile unsigned int *)0xE0200140 )#define  GPF2CON( *(volatile unsigned int *)0xE0200160 )#define  GPF3CON( *(volatile unsigned int *)0xE0200180 )#define  GPD0CON( *(volatile unsigned int *)0xE02000A0 )#define  GPD0DAT( *(volatile unsigned int *)0xE02000A4 )#define  CLK_SRC1( *(volatile unsigned int *)0xe0100204 )#define  CLK_DIV1( *(volatile unsigned int *)0xe0100304 )#define  DISPLAY_CONTROL( *(volatile unsigned int *)0xe0107008 )/* LCD Controler Pins */#define  VIDCON0( *(volatile unsigned int *)0xF8000000 )#define  VIDCON1( *(volatile unsigned int *)0xF8000004 )#define  VIDTCON2 ( *(volatile unsigned int *)0xF8000018 )#define  VIDTCON3( *(volatile unsigned int *)0xF800001c )#define  WINCON0 ( *(volatile unsigned int *)0xF8000020 )#define  WINCON2 ( *(volatile unsigned int *)0xF8000028 )#define  SHADOWCON ( *(volatile unsigned int *)0xF8000034 )#define  VIDOSD0A ( *(volatile unsigned int *)0xF8000040 )#define  VIDOSD0B ( *(volatile unsigned int *)0xF8000044 )#define  VIDOSD0C ( *(volatile unsigned int *)0xF8000048 )#define  VIDW00ADD0B0 ( *(volatile unsigned int *)0xF80000A0 )#define  VIDW00ADD1B0 ( *(volatile unsigned int *)0xF80000D0 )#define  VIDW00ADD2   ( *(volatile unsigned int *)0xF8000100 )#define  VIDTCON0 ( *(volatile unsigned int *)0xF8000010 )#define  VIDTCON1 ( *(volatile unsigned int *)0xF8000014 )/*垂直信号*/#define VSPW       9  //tvpw=VSPW+1的值是VSYNC的脉冲宽度,现根据表确定tvpw#define VBPD       12 //tvb = (VSPW + 1 )+(VBPD + 1),tvb 的值前面(VSPW + 1 )+(VBPD + 1)的无效行,先根据表确定tvb#define LINEVAL    479//tvd =  (LINEVAL+1)= 480,根据表确定tvd的值,表示y轴大小#define VFPD       21 //tvfp 的值是后面经过(VFPD + 1)的无效行,现根据表确定tvfp/*水平信号*/#define HSPW       19 //thpw =HSPW + 1 = 20,现根据表确定thpw#define HBPD       25 //thb= (HSPW + 1 )+(HBPD + 1) = 46, thb 的值是 VSYNC 前面经过(HSPW + 1 )+(HBPD + 1)的无效行,根据表先确定thb#define HOZVAL     799//thd=HOZVAL +1,表示的x轴大小#define HFPD       209//thfp = HFPD + 1= 210, thfp 的值是后面经过(HFPD + 1)的无效行,先根据表确定thfp/****描述上下左右定点的位置*/#define LeftTopX     0#define LeftTopY     0#define RightBotX   799#define RightBotY   479/**SCR_YSIZE_TFT  = 480,SCR_XSIZE_TFT  = 800,描述行和列的大小*/#define SCR_XSIZE_TFT (800)#define SCR_YSIZE_TFT (480)volatile unsigned int LCD_BUFFER[SCR_YSIZE_TFT][SCR_XSIZE_TFT];void lcd_init(void);void lcd_draw_pixel(int row, int col, int color);void lcd_clear_screen(unsigned long color);void Glib_Rectangle(int x1,int y1,int x2,int y2,int color);

void lcd_init(void){/** 1.设置相关GPIO引脚用于LCD */GPF0CON = 0x22222222;// GPF0[7:0]  LCD_VD[0-23]GPF1CON = 0x22222222;// GPF1[7:0]GPF2CON = 0x22222222;// GPF2[7:0]GPF3CON = 0x22222222;// GPF3[7:0]/** **2.显示路径的选择 * 0b10: RGB=FIMD I80=FIMD ITU=FIMD */DISPLAY_CONTROL = 2<<0;/**3.打开背光,见原理图不再核心板上*/GPD0CON |= 1<<4;GPD0DAT |= 1<<1;/**4.VIDCONx,设置接口类型、时钟、极性和使能LCD控制器等*/    /* 4.1:设置VIDCON0 -->CLKVAL_F[13:6]:该值需要根据LCD手册做相应的修改 *   HCLKD=166.75MHz,DCLK(min) = 20ns(50MHz) *   VCLK = 166.75 / (4+1) = 33.35MHz * (手册P14页可知DCLK频率的经典为33.3MHz) * CLKDIR  [4]:1 = 由CLKVAL_F分频 * ENVID   [1]:1 = 使能视频输出 * ENVID_F [0]:1 = 在当前帧结束的情况下使能视频输出 */VIDCON0 &= ~((3<<26) | (1<<18) | (0xff<<6)  | (1<<2));VIDCON0 |= ((4<<6) | (1<<4) );VIDCON0  |= 0x3; /* 开启总控制器 *//*4.2设置VINC0N1---->. 设置极性(该值需要根据LCD手册做相应的修改) * IVDEN [4]:0 = 正常 * IVSYNC[5]:1 = 反极性 * IHSYNC[6]:1 = 反极性 * IVCLK [7]:0 = Video data is fetched at VCLK falling edge */ /*.设置极性相反的原因:     S70-AT070TN92(p13页):VSYNC 和 HSYNC 都是低脉冲    S5PV210 芯片手册(p1207) 时序图:VSYNC 和 HSYNC 都是高脉冲有效,所以需要反转。*/VIDCON1 &= ~(1<<7);   /* 在vclk的下降沿获取数据 */VIDCON1 |= ((1<<6) | (1<<5));   /* HSYNC极性反转, VSYNC极性反转 *//**5.VIDTCONx,设置时序和长宽等 ,所用参数前面已经提到*/VIDTCON0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);/*时序*/VIDTCON1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);/* 设置长宽LINEVAL[21:11]:多少行   = 480,HOZVAL [10:0] :水平大小 = 800*/VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);/** 6.配置WINCON0,设置window0的数据格式      Swap使能),很关键的一位,能够解决掉重影问题  BPPMODE_F[5:2]:1011 = 24 BPP  ENWIN_F  [0]:  1    = 使能视频输出及视频控制信号 /WINCON0 &= ~(0xf << 2);WINCON0 |= (1<<15)|(0xB<<2);WINCON0 |= 1;       /* 开启窗口0 *//**7. 配置VIDOSD0A/B/C,设置window0的坐标系 *//* 窗口0,右下角的位置(800,480) */VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1);/*Window Shadow Control Register*/    /**8.配置VIDW00ADD0B0和VIDW00ADD1B0,设置framebuffer的地址*/VIDW00ADD0B0 = LCD_BUFFER;/* VBASEL = VBASEU + (LINEWIDTH+OFFSIZE) x (LINEVAL+1) *        = 0 + (800*4 + 0) * 479 *        = */VIDW00ADD1B0 =  (((HOZVAL + 1)*4 + 0) * (LINEVAL + 1)) & (0xffffff);/**配置SHADOWCON,使能dma通道0;*/SHADOWCON = 0x1; /* 使能通道0 */}/* 画一个像素点 */void PutPixel(unsigned long x,unsigned long y, unsigned long c ){if ( (x < SCR_XSIZE_TFT) && (y < SCR_YSIZE_TFT) )LCD_BUFFER[(y)][(x)] = c;}/* 清屏 *//***先扫描行,行里面描像素。lcd_clear_screen 函数就是利用这个原理,外循环表示一行一行的扫,内循环表示一行里面一个一个像素描。总共有 480 行,每行里面有 800 个像素点。这就是 Webee210 液晶屏的分辨率 800*480.*/void lcd_clear_screen( unsigned long c){unsigned int x,y ;for( y = 0 ; y < SCR_YSIZE_TFT ; y++ ){for( x = 0 ; x < SCR_XSIZE_TFT ; x++ ){LCD_BUFFER[y][x] = c ;}}}/* 用于画直线:横线和竖线 */void Glib_Line(int x1,int y1,int x2,int y2,int color){int dx,dy,e;dx=x2-x1;dy=y2-y1;if(dx>=0){if(dy >= 0) // dy>=0{if(dx>=dy) // 1/8 octant{e=dy-dx/2;while(x1<=x2){PutPixel(x1,y1,color);if(e>0){y1+=1;e-=dx;}x1+=1;e+=dy;}}else// 2/8 octant{e=dx-dy/2;while(y1<=y2){PutPixel(x1,y1,color);if(e>0){x1+=1;e-=dy;}y1+=1;e+=dx;}}}else   // dy<0{dy=-dy;   // dy=abs(dy)if(dx>=dy) // 8/8 octant{e=dy-dx/2;while(x1<=x2){PutPixel(x1,y1,color);if(e>0){y1-=1;e-=dx;}x1+=1;e+=dy;}}else// 7/8 octant{e=dx-dy/2;while(y1>=y2){PutPixel(x1,y1,color);if(e>0){x1+=1;e-=dy;}y1-=1;e+=dx;}}}}else //dx<0{dx=-dx;//dx=abs(dx)if(dy >= 0) // dy>=0{if(dx>=dy) // 4/8 octant{e=dy-dx/2;while(x1>=x2){PutPixel(x1,y1,color);if(e>0){y1+=1;e-=dx;}x1-=1;e+=dy;}}else// 3/8 octant{e=dx-dy/2;while(y1<=y2){PutPixel(x1,y1,color);if(e>0){x1-=1;e-=dy;}y1+=1;e+=dx;}}}else   // dy<0{dy=-dy;   // dy=abs(dy)if(dx>=dy) // 5/8 octant{e=dy-dx/2;while(x1>=x2){PutPixel(x1,y1,color);if(e>0){y1-=1;e-=dx;}x1-=1;e+=dy;}}else// 6/8 octant{e=dx-dy/2;while(y1>=y2){PutPixel(x1,y1,color);if(e>0){x1-=1;e-=dy;}y1-=1;e+=dx;}}}}}/* 用于画方框 */void Glib_Rectangle(int x1,int y1,int x2,int y2,int color){    Glib_Line(x1,y1,x2,y1,color);//矩形的上边长    Glib_Line(x2,y1,x2,y2,color);//矩形的右边长    Glib_Line(x1,y2,x2,y2,color);//矩形的下边长    Glib_Line(x1,y1,x1,y2,color);//矩形的左边长}









0 0
原创粉丝点击