s3c2440 LCD控制器

本文详细介绍了S3C2440 ARM SoC的LCD控制器配置过程,包括LCD系统结构、控制时序、配置寄存器设置、初始化程序以及完整代码实现。主要内容涵盖LCD控制器的引脚配置、时序参数设置、显示缓存地址设定、初始化函数实现等关键步骤,适用于对S3C2440 LCD控制感兴趣的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、LCD系统结构图

对于ARM的SOC(片上系统),它的ARM芯片一般会集成LCD控制器,它主要就是用于产生控制LCD显示所必须的控制时序和控制逻辑。本文主要就是讲述如何配置S3C2440的LCD控制器。一个完整的LCD系统结构图如下:

 

显示缓存    :用于存放要在LCD屏幕上显示的数据,一般缓存大小是根据LCD的分辨率来设置。
LCD控制器:产生LCD显示所必须的时序和控制逻辑信号。
LCD驱动器:将控制LCD的逻辑信号转换为该型号LCD能识别的电压值,使该型号的LCD工作。通常LCD驱动器会以COF/COG的形式与LCD 基板制做在一起。
LCD控制器和LCD驱动器的区别?
答:例如S3C2440的LCD控制器的引脚输出LCD_PWR为高电平时表示打开LCD的电源,这只是一个打开LCD的信号,但是不同的LCD打开电源的驱动电压可能不相同,A型号的LCD可能驱动电压为12V,B型号的LCD驱动电压可能为15V。正是由于这个原因,每个不同的LCD总是和它们的驱动器集成在一起。但是不同的LCD的控制逻辑和控制时序却是相同的。这个控制逻辑就由集成到LCD控制器来完成。所以本文主要介绍S3C2440的配置。

二、S3C2440 LCD控制时序

s3c2440 LCD控制时序图如下:


VSYNC (Vertical Synchronous):帧同步信号
HSYNC (Horizontal Synchronous):行同步信号
VDEN(Video Display enable):数据有效信号
VCLK(Video Clock):像素时钟,一个时钟周期显示一个像素。(需用户配置)
VD(Video Data):像素数据,一般2个字节或者3个字节表示一个像素的值。
LEND(Line End):行结束信号。
HOZVAL(Horizontal Value):LCD屏幕的列数。(需用户配置)
LINEVAL(Line Value):LCD屏幕的行数。(需用户配置)
VSPW(Vertical Sync Pulse Width):VSYNC信号的宽度。(需用户配置)
VBPD(Vertical Back Porch Delay):VSYNC同步信号下降沿后无效行数。(需用户配置)
VFPD(Vertical Front Porch Delay):VSYNC同步信号上升沿前无效行数。(需用户配置)
HSPW(Horizontal Sync Pulse Width):HSYNC信号的宽度。(需用户配置)
HBPD(Horizontal Back Porch Delay):HSYNC同步信号下降沿后无效像素点个数。(需用户配置)
HFPD(Horizontal Front Porch Delay):HSYNC同步信号上升沿前无效像素点个数。(需用户配置)

LCD控制器的时序如下:

1.VSYNC信号从低变高,表示一帧数据的开始。
2.VSYNC信号高电平保持(VSPW+1)个HSYNC信号周期,这段时间内行数据无效。
3.VSYNC信号从高变低后还要经过(VBPD+1)个HSYNC信号周期,这段时间内行数据无效。
4.随后发出(LINEVAL+1)个有效行数据。
5.最后在VSYNC从低变高前经过(VFPD+1)个HSYNC信号周期,这段时间内行数据无效。
这就是一帧数据的显示过程,随后将再次发送一个VSYNC有效信号开始新的一帧数据的传送。

现在深入到一行中像素数据的传输过程
1.HSYNC信号从低变高,表示一行数据的开始。
2.HSYNC信号高电平保持(HSPW+1)个VCLK信号周期,这段时间内像素数据无效。
3.HSYNC信号从高变低后还要经过(HBPW+1)个VCLK信号周期,这段时间内像素数据无效。
4.随后即连续发出(HOZVAL+1)个像素的有效数据。
5.最后在HSYNC从低变高前经过(HFPD+1)个VLCK信号周期,这段时间内像素数据无效。
这就是一行数据的显示过程,随后将再次发送一个HSYNC有效信号开始新的一行数据的传送。直到传送完(LINEVAL+1)行为止

注1:这些需要用户配置的数据请查阅相关的LCD显示器手册。
注2:(VSPW+VFPD+VBFD)为帧消隐时间,(HSPW+HFPD+HBFD)为行消隐时间,主要是为保护LCD显示器

三、S3C2440 LCD控制器配置

要使LCD控制器工作必须配置这些寄存器:LCDCON1,LCDCON2,LCDCON3,LCDCON4,LCDCON5,LCDSADDR1,LCDSADDR2,LCDSADDR3。其中很多的配置都是根据LCD手册,本人使用的LCD用户手册如下:


3.1 LCDCON1寄存器

LCDCON1=(CLKVAL<<8) | (PNRMODE<<5) | (BBPMODE<<1) | ENVID;
CLKVAL=0x4,PNRMODE=0x3;BBPMODE=0x0c;ENVID=0;
LCD手册Dclk=9MHz~15MHz, HCLK=100MHz, Dclk=VCLK=HCLK/[(CLKVAL+1)x2]=100/((4+1)*2)=10MHz

3.2 LCDCON2寄存器


LCDCON2 = (VBPD_480272<<24) | (LINEVAL_TFT_480272<<14) | (VFPD_480272<<6) | (VSPW_480272);
根据LCD手册有VBPD_480272=(2-1),LINEVAL_TFT_480272=(272-1),VFPD_480272=(2-1),VSPW_480272=(10-1)

3.3 LCDCON3寄存器


LCDCON3 = (HBPD_480272<<19) | (HOZVAL_TFT_480272<<8) | (HFPD_480272);
根据LCD手册有HBPD_480272=(2-1),HOZVAL_TFT_480272=(480-1),HFPD_480272=(2-1)

3.4 LCDCON4寄存器


LCDCON4 = HSPW_480272;
根据LCD用户手册HSPW_480272=(41-1)

3.5 LCDCON5寄存器



LCDCON5 = (FORMAT8BPP_565<<11) | (HSYNC_INV<<9) | (VSYNC_INV<<8) | (HWSWP<<1);
根据LCD手册FORMAT8BPP_565=1,HSYNC_INV=1,VSYNC_INV=1,HWSWP=1

以上主要是根据LCD手册设置了LCD控制器的时序,下面我们要设置LCD的显示缓存地址

3.6 LCDSADDR1寄存器


#define LOWER21BITS(n)  ((n) & 0x1fffff)
#define LCDFRAMEBUFFER 0x30400000
LCDSADDR1 = ((LCDFRAMEBUFFER>>22)<<21) | LOWER21BITS(LCDFRAMEBUFFER>>1);

3.7 LCDSADDR2寄存器


LCDSADDR2 = LOWER21BITS((LCDFRAMEBUFFER+ (LINEVAL_TFT_480272+1)*(HOZVAL_TFT_480272+1)*2)>>1);
其中LINEVAL_TFT_480272=(272-1),HOZVAL_TFT_480272=(480-1)

3.8 LCDSADDR3寄存器


LCDSADDR3 = (0<<11) | (LCD_XSIZE_TFT_480272*2/2);

四、LCD初始化程序

/*初始化用于LCD的引脚*/
void Lcd_Port_Init(void)
{
    GPCUP   = 0xffffffff;   // 禁止内部上拉
    GPCCON  = 0xaaaaaaaa;   // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND 
    GPDUP   = 0xffffffff;   // 禁止内部上拉
    GPDCON  = 0xaaaaaaaa;   // GPIO管脚用于VD[23:8]
  	GPBCON &= ~(GPB0_MSK);  // Power enable pin
    GPBCON |= GPB0_out;
    GPBDAT &= ~(1<<0);			// Power off
}
/*初始化LCD控制器*/
void Tft_Lcd_Init(void)
{
        /* 
         * 设置LCD控制器的控制寄存器LCDCON1~5
         * 1. LCDCON1:
         *    设置VCLK的频率:VCLK(Hz) = HCLK/[(CLKVAL+1)x2]
         *    选择LCD类型: TFT LCD   
         *    设置显示模式: 16BPP
         *    先禁止LCD信号输出
         * 2. LCDCON2/3/4:
         *    设置控制信号的时间参数
         *    设置分辨率,即行数及列数
         * 现在,可以根据公式计算出显示器的频率:
         * 当HCLK=100MHz时,
         * Frame Rate = 1/[{(VSPW+1)+(VBPD+1)+(LIINEVAL+1)+(VFPD+1)}x
         *              {(HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)}x
         *              {2x(CLKVAL+1)/(HCLK)}]
         *            = 60Hz
         * 3. LCDCON5:
         *    设置显示模式为16BPP时的数据格式: 5:6:5
         *    设置HSYNC、VSYNC脉冲的极性(这需要参考具体LCD的接口信号): 反转
         *    半字(2字节)交换使能
         */
        LCDCON1 = (CLKVAL_TFT_480272<<8) | (LCDTYPE_TFT<<5) | \
                  (BPPMODE_16BPP<<1) | (ENVID_DISABLE<<0);
        LCDCON2 = (VBPD_480272<<24) | (LINEVAL_TFT_480272<<14) | \
                  (VFPD_480272<<6) | (VSPW_480272);
        LCDCON3 = (HBPD_480272<<19) | (HOZVAL_TFT_480272<<8) | (HFPD_480272);
        LCDCON4 = HSPW_480272;
        LCDCON5 = (FORMAT8BPP_565<<11) | (HSYNC_INV<<9) | (VSYNC_INV<<8) | \
                  (HWSWP<<1);

        /*
         * 设置LCD控制器的地址寄存器LCDSADDR1~3
         * 帧内存与视口(view point)完全吻合,
         * 图像数据格式如下:
         *         |----PAGEWIDTH----|
         *    y/x  0   1   2       479
         *     0   rgb rgb rgb ... rgb
         *     1   rgb rgb rgb ... rgb
         * 1. LCDSADDR1:
         *    设置LCDBANK、LCDBASEU
         * 2. LCDSADDR2:
         *    设置LCDBASEL: 帧缓冲区的结束地址A[21:1]
         * 3. LCDSADDR3:
         *    OFFSIZE等于0,PAGEWIDTH等于(480*2/2)
         */
        LCDSADDR1 = ((LCDFRAMEBUFFER>>22)<<21) | LOWER21BITS(LCDFRAMEBUFFER>>1);
        LCDSADDR2 = LOWER21BITS((LCDFRAMEBUFFER+ \
                    (LINEVAL_TFT_480272+1)*(HOZVAL_TFT_480272+1)*2)>>1);
        LCDSADDR3 = (0<<11) | (LCD_XSIZE_TFT_480272*2/2);

        /* 禁止临时调色板寄存器 */
        TPAL = 0;

        fb_base_addr = LCDFRAMEBUFFER;
        bpp = 16;
        xsize = 480;
        ysize = 272;
}

void Lcd_PowerEnable(int invpwren, int pwren)
{
    GPGCON = (GPGCON & (~(3<<8))) | (3<<8);   // GPG4用作LCD_PWREN
    GPGUP  = (GPGUP & (~(1<<4))) | (1<<4);    // 禁止内部上拉    
        
    LCDCON5 = (LCDCON5 & (~(1<<5))) | (invpwren<<5);  // 设置LCD_PWREN的极性: 正常/反转
    LCDCON5 = (LCDCON5 & (~(1<<3))) | (pwren<<3);     // 设置是否输出LCD_PWREN
} 
/*
 * 设置LCD控制器是否输出信号
 * 输入参数:
 * onoff: 0 : 关闭 1 : 打开
 */
void Lcd_EnvidOnOff(int onoff)
{
    if (onoff == 1)
    {
        LCDCON1 |= 1;         // ENVID ON
    }
    else
    {
        LCDCON1 &= 0x3fffe;  // ENVID Off
    }
}    
#include "lcddrv.h"
#include "framebuffer.h"
int main()
{  
    Lcd_Port_Init();                     // 设置LCD引脚
    Tft_Lcd_Init();                      // 初始化LCD控制器
    Lcd_PowerEnable(0, 1);               // 设置LCD_PWREN有效,它用于打开LCD的电源
    Lcd_EnvidOnOff(1);                   // 使能LCD控制器输出信号
    Lcd_Palette8Bit_Init();              // 初始化调色板
    ClearScr(0x0);   
     
    while (1){;} 
    return 0;
}

五、完整程序代码

可在tq2440板子上运行

功能:按PC键盘上的1,2,3,4显示4张不同的图片

源码链接:http://download.youkuaiyun.com/detail/hongwazi_2010/5749017

LCD控制时序http://hi.baidu.com/trical/item/15372a08d5cdf3eb359902f4


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值