历史上的今天
返回首页

历史上的今天

今天是:2025年02月03日(星期一)

2020年02月03日 | S5PV210的LCD控制器详解

2020-02-03 来源:eefocus

1、FIMD结构框图

(1)Samsung的s5pv210的LCD控制器叫做FIMD(也叫显示控制器)。Display controller(显示控制器)包括用于将图像数据从相机接口控制器的本地总线或位于系统存储器(例如:显存)中的视频缓冲器传送到外部LCD驱动器接口的逻辑。 LCD驱动接口支持三种接口,即RGB接口,I80接口和YUV接口。显示控制器使用多达五个覆盖图像窗口(也就是虚拟窗口win0-win4),其支持各种颜色格式,如RGB、YUV。

FIMD在内部与AHB总线等相连接,在外部提供RGB接口、I80接口、YUV接口与外部相连接,我们实际使用的是RGB接口。这个接口就是我在上一篇博文中说的LCD控制器的数据输出接口。RGB接口传输的是RGB编码的颜色数据,同理YUV接口传输的就是YUV编码的颜色数据,至于I80我不了解。本文讨论也是RGB接口。

(2)RGB接口信号

LCD_HSYNC :水平同步信号

LCD_VSYNC:垂直同步信号

LCD_VCLK:像素时钟,LCD工作时需要主板控制器给LCD模组一个工作时钟信号,就是VCLK

LCD_VDEN:数据有效标志,时序信号,和HSYNC、VSYNC结合使用。

LCD_VD[23:0]:24根数据线,用来传输图像信息。可见LCD是并行接口,速率才够快。

 

2、LCD显示一帧图像的过程

(1)LCD显示单位:帧(frame)

显示器上一整个画面的内容成为一个帧(frame),整个显示器工作时是一帧一帧的在显示。

帧内数据:一帧分为多行,一行分为多像素,因此一帧图像其实就是多个像素组成的矩阵。

帧外数据:整个视频由很多个帧构成,最终播放视频时逐个播放各个图像帧即可。

(2)显示一帧图像

首先把帧分为行,然后再把行分为像素,然后逐个像素去显示。(显示像素:其实就是LCD驱动器按照接收到的LCD控制器给的显示数据,驱动一个像素的液晶分子旋转,让这个像素显示出相应的颜色值的过程)。

关键点:LCD控制器和驱动器之间一次只能传一个像素点的显示数据。所以一帧图像在屏幕上其实是串行的依次被显示上去的,不是同一时间显示出来的。

(3)为了向前兼容出现的六个时序参数

HSPW 水平同步信号脉宽

HBPD 水平同步信号前肩
HFPD 水平同步信号后肩
VSPW 垂直同步信号脉宽
VBPD 垂直同步信号前肩
VFPD 垂直同步信号后肩

 

 

(3.1)一行的通信过程是这样的:LCD控制器先发送一个HSYNC高电平脉冲(脉冲宽度是HSPW ),脉冲告诉驱动器下面的信息是一行信息。然后开始这一行信息,这一行信息包括3部 分:HBPD+有效行信息+HFPD。其中前肩和后肩都属于时序信息(和LCD屏幕具体有关), 有效行信息就是横向分辨率。所以你可以认为一行总共包含4部分:HSPW+HBPD+有效行信 息+HFPD。
(3.2)一帧图像其实就是一列,一列图像由多个行组成,每行都是上面讲的这个时序。
(3.3)一帧图像的通信过程是这样的:整个帧图像信号分为4部分:VSPW+VBPD+帧有效信号 
+VFPD。VSPW是帧同步信号宽度,用来告诉驱动器一帧图像要开始了;VBPD和VFPD分别是 
垂直同步信号前后肩。
(3.4)必须说明:这6个参数对于LCD显示器其实本来是没用的,这些信号其实是老式的CRT 
显示器才需要的,LCD本身不需要,但是出于历史兼容性要求,LCD选择了兼容CRT显示器 
的这些时序要求,所以理解LCD显示器时序和编程时,用CRT的方式来理解不会错。
(3.5)要注意,这几个时序参数本身是LCD屏幕本身的参数,与LCD控制器无关。所以同一个 主板如果接的屏幕不一样则时序参数设置也会不同。这些参数的来源一般是:第一,厂家会直接给出,一般以实例代码的形式给出;第二,来自于LCD的数据手册。

 

2、虚拟屏幕叠加

(1)虚拟屏幕的意思是,我们平时看到的屏幕上显示出来的场景实际是很多个屏幕显示叠加在一起的效果(譬如新闻图像、电视台台标、下方飘动的字幕新闻)。

(2)像S5PV210的LCD控制器中有5个虚拟屏幕Window0到Window4,虚拟屏幕不存在于真实而存在于内存中。(之前讲过,LCd显示时实际是显示的是对应的内存中的显存区域的数值)虚拟屏幕其实就是一个内存中的显存区域,有几个显存区域就有几个虚拟屏幕,但是这些虚拟屏幕都被映射到一个真实的显示屏上面,所以将来真实的现实效果实际是这几个虚拟屏幕的显示内容的叠加。(叠加时要注意上面一层会覆盖下面一层,所以要注意谁在前谁在后,设置寄存器时有这个选项)。

(3)使用虚拟屏幕而不是整个LCD使用一个显存是有一定好处的:第一,可以保证不污染源图像,方便程序处理;第二,可以减少屏幕刷新,提高显示效率,减少CPU工作量。

 

3、虚拟显示

(1)如何实现在小分辨率的屏幕上(真实)显示大分辨率的图像?

细节上,我们需要屏幕上看到不同图像时,需要对显存区域进行刷新。即使我们只需要屏幕显示移动一点点,整个屏幕对应的显存空间也需要整个重新刷新,工作量和完全重新显示一幅图像是一样的。这个显然不好,这样CPU刷新屏幕的工作量太大了,效率很低。如何能够在显示一个大图片的不同区域时让CPU刷新屏幕工作量减少?有,方法就是虚拟显示。具体做法就是在内存中建立显示缓存的时候实际建立一个很大的区域,然后让LCD去对应其中的一部分区域作为有效的显示区域。将来要显示大图像时,直接将大图像全部一次性加载入显示缓存区,然后通过移动有效显示区域就可以显示大图像的不同区域了。

 

4、LCD控制器的主要寄存器

LCD相关寄存器寄存器介绍:因为这里面的寄存器实在太多了,我们的一个原则就是能够 

让LCD工作就行了,所以很多寄存器我们都没有涉及到,同一个寄存器中有些位也是没有 
涉及到的,所以需要用到的位我们就设置,不需要我们暂且不管,如果以后做方面相关 
的时候再去好好研究。

(1)VIDCON0:

bit[0]: 当前帧结束后是否使能视频输出控制器,也就是一帧画面显示结束后是否使能 
LCD控制器,1使能 0禁止
bit[1]: 使能视频输出控制器(指的是当前) 1使能 0禁止
bit[2]: 时钟源选择 0=HCLK_DSYS 1=SCLK_FIMD
bit[13:6]: 时钟源分频器分频系数设置 本LCd控制器时钟不超过100MHZ,最终的时钟频 
率是需要考虑LCD控制器和LCD驱动器两个方面,要低于两个中的最小值。
bit[4]: 时钟控制,使用分频器设置后的时钟还是源时钟,0是源时钟 1是分频器设置 
后 的时钟。
bit[18]: 选择显示的模式,0是RGB并行模式 1是RGB串行模式
bit[28:26]: 选择视频输出格式,000=RGB接口 010=I80接口 011=I80接口...

 

(2)VIDCON1:
bit[4]: VSYNC信号反转控制,要跟LCd驱动器的电平要一致
bit[5]: HSYNC信号反转控制,要跟LCD驱动器的电平要一致

 

(3)VIDTCON0:
bit[7:0]: VSPW设置,意思在上面已经说过
bit[15:8]: VFPD设置
bit[23:16]: VBPD设置

 

(4)VIDTCON1:
bit[7:0]: HSPW设置
bit[15:8]: HFPD设置
bit[23:16]: HBPD设置

 

(5)VIDTCON2:
bit[10:0]: 显示水平大小设置,水平分辨率
bit[21:11]: 显示垂直大小设置,垂直分辨率

 

(6)WINCON0,WINCON1,WINCON2,WINCON3,WINCON4:
分别设置5个虚拟显示,对应分配的5个显存
bit[0]: 使能位,0禁止当前显存 1使能当前显存
bit[5:2]: 选择像素深度(bpp)
0000=1bpp 0001=2bpp 0010=4bpp.....1011=24bpp(R:8 G:8 B:8)
bit[15]: 像素交换使能控制位,像素交换就是 24位数据怎么分布的问题,是RGB还是 
BGR
0禁止 1使能交换

 

(7)VIDOSD0A,VIDOSD1A,VIDOSD2A,VIDOSD3A....
用来设置虚拟显存的位置相关的
bit[10:0]: 指定左上像素的垂直坐标
bit[21:11]: 指定左上像素的水平坐标

 

(8)VIDOSD0B................
bit[10:0]: 指定右下角像素的垂直坐标
bit[21:11]: 指定右下角像素的水平坐标

 

(9)VIDOSD0C....... 设置显存的大小、注意显存的大小可以大于LCD实际的一帧数据的大 
小的,这是需要理解的。
bit[23:0]: 注意这里设置其实是以像素为单位的,也就是说这里设置的是我们的显存 

 

(10)VIDW00ADD0B0(分为5组)分别对应我们的5个虚拟显存
bit[31:0]: 显存的内存地址设置 , 将地址值写入这个寄存器

 

VIDW00ADD1B0(分为5组)分别对应我们的5个虚拟显存
bit[31:0]: 显存的大小,以字节为单位

 

SHADOWCON:用来设置我们的5个虚拟显存使能控制位和叠加方式寄存器,如果我们显示 
的图片是需要叠加的话是需要好好看看这里的。
bit[0]: win0显存使能控制开关 0禁止 1使能 所以由此可知我们的每一个虚拟显存 
的使能开关有两个一个就是在各自的寄存器上,另一个就是在这里集中的控制 
,当然我们还有总的视频控制输出开关,之前说过了。
....

/*************************************************************************************/

附上裸机下操作LCD控制器的代码:(基于:S5PV210平台)

  1 #define HSPW             (40)                // 1~40 DCLK

  2 #define HBPD            (10 - 1)            // 46

  3 #define HFPD             (240 - 1)            // 16 210 354

  4 #define VSPW            (20)                // 1~20 DCLK

  5 #define VBPD             (10 - 1)            // 23

  6 #define VFPD             (30 - 1)            // 7 22 147

  7 

  8 #define FB_ADDR            (0x23000000)

  9 #define ROW                (600)

 10 #define COL                (1024)

 11 #define HOZVAL            (COL-1)

 12 #define LINEVAL            (ROW-1)

 13 

 14 #define XSIZE            COL

 15 #define YSIZE            ROW

 16 

 17 #define LeftTopX     0

 18 #define LeftTopY     0

 19 #define RightBotX   1023

 20 #define RightBotY   599

 21 

 22 #define  GPF0CON   (*(volatile unsigned int *)0xE0200120)

 23 #define  GPF1CON   (*(volatile unsigned int *)0xE0200140)

 24 #define  GPF2CON   (*(volatile unsigned int *)0xE0200160)

 25 #define  GPF3CON   (*(volatile unsigned int *)0xE0200180)

 26 

 27 #define  GPD0CON   (*(volatile unsigned int *)0xE02000A0)

 28 #define  GPD0DAT   (*(volatile unsigned int *)0xE02000A4)

 29 

 30 #define  DISPLAY_CONTROL   (*(volatile unsigned int *)0xE0107008)

 31 

 32 #define  VIDCON0   (*(volatile unsigned int *)0xF8000000) 

 33 #define  VIDCON1   (*(volatile unsigned int *)0xF8000004)

 34 

 35 #define  VIDTCON0  (*(volatile unsigned int *)0xF8000010)

 36 #define  VIDTCON1  (*(volatile unsigned int *)0xF8000014)

 37 #define  VIDTCON2  (*(volatile unsigned int *)0xF8000018)

 38 #define  VIDOSD0A  (*(volatile unsigned long *)0xF8000040)

 39 #define  VIDOSD0B  (*(volatile unsigned long *)0xF8000044)

 40 #define  VIDOSD0C  (*(volatile unsigned long *)0xF8000048)

 41 #define  VIDW00ADD0B0     (*(volatile unsigned long *)0xF80000A0)

 42 #define  VIDW00ADD1B0     (*(volatile unsigned long *)0xF80000D0)

 43 #define  WINCON0         (*(volatile unsigned long *)0xF8000020)

 44 #define  SHADOWCON         (*(volatile unsigned long *)0xF8000034)

 45 

 46 

 47 typedef unsigned int u32;

 48 typedef unsigned short u16;

 49 

 50 

 51 /*填充像素点*/

 52 static inline void lcd_draw_pixel(u32 x, u32 y, u32 color)

 53 {

 54     *(u32 *)(FB_ADDR + (COL*x + y)*4) = color;

 55 }

 56 

 57 /*填充LCD背景*/

 58 void lcd_draw_background(const u32 color)

 59 {

 60      u32 i = 0;

 61      u32 j = 0;

 62      

 63      for (i = 1; i <= ROW; ++i)

 64      {

 65          for (j = 0; j <= COL; ++j)

 66              lcd_draw_pixel(i, j, color);

 67      }

 68 } 

 69 

 70 /*在LCd上绘制水平线*/

 71 void lcd_draw_lline(const u32 x, const u32 y, const u32 length,

 72                      const u32 width, const u32 color)              

 73 {

 74     volatile u32 i = 0;

 75     volatile u32 j = 0;

 76     

 77     for (i = x; i < width+x; i++)

 78     {

 79         for (j = y; j < length+y; j++)

 80         {

 81             lcd_draw_pixel(i, j, color);

 82         }

 83     }    

 84 }

 85 

 86 /*在LCd上绘制垂直线*/

 87 void lcd_draw_vline(const u32 x, const u32 y, const u32 length,

 88                      const u32 width, const u32 color)

 89 {

 90     volatile u32 i = 0;

 91     volatile u32 j = 0;

 92     

 93     for (i = x; i < length+x; i++)

 94     {

 95         for (j = y; j < width+y; j++)

 96         {

 97             lcd_draw_pixel(i, j, color);

 98         }

 99     }

100 }

101 

102 // glib库中的画线函数,可以画斜线,线两端分别是(x1, y1)和(x2, y2)

103 void glib_line(unsigned int x1, unsigned int y1, 

104                   unsigned int x2, unsigned int y2, unsigned int color)

105 {

106     int dx,dy,e;

107     dx=x2-x1; 

推荐阅读

史海拾趣

Alliance Memory公司的发展小趣事

Alliance Memory是一家专注于存储器产品的公司,以下是其发展历程的五个相关故事:

  1. 成立与发展初期: Alliance Memory成立于2006年,总部位于美国南卡罗来纳州。公司专注于提供DRAM(动态随机存取存储器)和SRAM(静态随机存取存储器)解决方案。在成立之初,公司致力于与全球供应链建立紧密的合作关系,以确保产品的质量和可靠性。通过与先进制造厂商合作,Alliance Memory能够提供高品质的存储器产品,满足客户的需求。

  2. 扩大产品线: 随着市场需求的增长,Alliance Memory不断扩大其产品线,涵盖各种容量和类型的DRAM和SRAM产品。公司不断改进和优化其制造工艺,并与全球领先的技术合作伙伴密切合作,以确保产品的性能和稳定性。通过不断提供新的存储器解决方案,Alliance Memory成功吸引了更多的客户,并在行业中树立了良好的声誉。

  3. 全球市场拓展: Alliance Memory的产品销售遍布全球各个地区,包括美国、欧洲、亚洲等市场。公司与全球各地的分销商和代理商建立了稳固的合作关系,以扩大其产品的市场份额。通过在全球范围内提供及时和高效的客户服务,Alliance Memory不断增强了其在国际市场上的竞争力。

  4. 技术创新与研发投入: 作为一家技术驱动型公司,Alliance Memory不断投入研发和创新,以提供最先进的存储器产品。公司的研发团队与业界领先的技术合作伙伴密切合作,不断推出具有竞争优势的新产品。通过持续的技术创新,Alliance Memory得以不断满足客户不断增长的需求,并保持在行业中的领先地位。

  5. 可持续发展与社会责任: 除了致力于业务发展,Alliance Memory还积极履行企业社会责任,关注环境保护和社会公益事业。公司采取了一系列可持续发展的举措,包括节能减排、资源循环利用等,努力降低对环境的影响。此外,Alliance Memory还参与各种公益活动,支持教育、环保和社区发展等领域的项目,为社会做出积极贡献。

得倍(DBIC)公司的发展小趣事

倍(DBIC)公司自创立之初,就致力于在电子行业中进行技术创新。公司投入大量资源进行研发,成功推出了一系列具有革命性的产品,如高效能芯片和智能传感器。这些产品不仅提高了生产效率,还满足了市场对智能化、高效能电子产品的需求。随着技术的不断进步,倍(DBIC)公司逐渐在行业中树立了技术领先的形象,吸引了众多合作伙伴和客户。

Electromagnetic Industries Llp公司的发展小趣事

进入21世纪,随着科技的不断进步,电子行业对产品的性能和质量要求越来越高。EMI公司意识到,只有不断创新才能在激烈的市场竞争中立于不败之地。因此,公司加大了对研发的投入,引进了一批高端技术人才,并建立了完善的研发体系。经过几年的努力,EMI公司成功研发出了一系列具有自主知识产权的电磁产品,这些产品在性能和质量上均达到了国际先进水平,赢得了客户的广泛赞誉。

Deutsch公司的发展小趣事

在竞争激烈的电子行业中,品质控制和品牌建设至关重要。Deutsch公司深知这一点,因此始终将品质控制和品牌建设作为公司的重要任务。公司建立了严格的质量管理体系,确保产品的每一个细节都符合高标准。同时,通过精心策划的品牌推广活动,Deutsch公司的品牌形象逐渐深入人心。这些努力不仅提升了公司的市场地位,也增强了客户对公司的忠诚度。

宁波晨翔电子(CONNFLY)公司的发展小趣事

宁波晨翔电子有限公司(CONNFLY)成立于1998年(前身宁波正青电子有限公司),初创时期主要致力于连接器及线材产品的研发与生产。在创始团队的共同努力下,公司逐渐在电子连接器市场找到了自己的定位,通过不断的技术创新和品质提升,逐渐获得了市场的认可。

Hei Inc Optoelectronic Division公司的发展小趣事
通过电子元件实现精确控制,可以更加灵活地调整加热时间、温度等参数,以适应不同材料和工艺的需求。

问答坊 | AI 解惑

新手学习嵌入式从那里入手好呢??

我是学习电气自动化的应届毕业生,想在毕业后在嵌入式方向发展,但是我在学校只学过80c51单片机和c语言,请各位高手指教一下!我应该从那里入手学习嵌入式呢,谢谢…

查看全部问答>

数控直流稳压设计

本帖最后由 paulhyde 于 2014-9-15 09:19 编辑 数控直流稳压设计  …

查看全部问答>

光电检测试验资料

本帖最后由 paulhyde 于 2014-9-15 09:14 编辑 光电测量技术实验指导书  …

查看全部问答>

cc1101 + 单片机 还是cc2430

cc1101 + 单片机 的成本要低于 cc2430不少 请问,我是要在10米内隔几分钟发送一个数字 这两种方案,哪个更好?…

查看全部问答>

在today界面显示标签

我想在today界面的上面部分,就是在显示电量、信号量的地方,添加一个label控件,用于显示当前的温度,怎么才能做到? 谢谢各位的指教…

查看全部问答>

wince快捷方式

正在搞一个放在SD卡上面的AP,每次路径访问很麻烦,能否搞一个快捷方式从桌面上面直接启动? 我查了下网上写的,18#/windows/**.exe的方法,但是系统一直报SD卡的路径不对,各位有没有搞过一个快捷方式能直接启动放在SD上的程序? 多谢多谢!…

查看全部问答>

关于uc/OSII的调试?用什么编译器!

关于uc/OSII的调试?用什么编译器! ___最近在学uc/OSII,要用到BC4.52,但很难下载到,下到的不是IDE,不习惯用命令行方式,请问各位,还有其它更好的编译器可用来调试uc/OSII吗?谢谢!…

查看全部问答>

9263WINCE5.0下SD卡驱动的问题

9263板跑WINCE5,使用SD卡时,时常从串口输出: WaitForSingleObject == WAIT_TIMEOUT (1000) StatusMask = 0x20 status 0xc0c5 这串数据重复输出,并且SD卡读写速度变得非常之慢。 查程序发现是PLATFOM\\COMMON\\SRC\\ARM\\ATMEL\\AT91SAM926 ...…

查看全部问答>