嵌入式学习-uboot-lesson14-LCD相关

关于LCD的相关知识在这里就不再说了,下面就直接开始对LCD进行编程分析。

一、硬件结构

根据上面两幅图可以得知,

1.LCD的VD[0:23]一共24个引脚,接在GPI[0:15],GPJ[0:7] 这24个IO口上,

2.GPJ[8:11]分别接LCD的:

GPJ8—-HSYNC:行(水平方向)同步信号

GPJ9—-VSYNC:场(垂直方向)同步信号

GPJ10—VDEN:video data enable 视频输入使能端

GPJ11—VCLK :像素之间时钟信号

因此需要对这些引脚进行配置,使之满足我们的需求。

二、编程流程

根据第一步,我们首先需要做的工作是:

1).配置引脚

同时,我们还需要对LCD的时序进行配置

2).设置LCD时序值

同时,还需要对在内存中专门开辟出来的framebuffer,进行初始化

3).帧缓存初始化

第二步和第三步的全部过程在上面两幅图中全部标了出来,下面我们只需根据上面的步骤进行编程即可

三、编程实现

1).配置引脚

根据上图需要将GPI寄存器的所有引脚配置为0b10模式

即:

#define GPICON           (*((volatile unsigned long*)0x7F008100)) //端口I 配置寄存器 GPICON = 0xaaaaaaaa;    //16个引脚都配置为0b10

根据上面两幅图,可知需要将GPJ[0:15] 和GPJ[16:23]都设置为ob10

即:

#define GPJCON           (*((volatile unsigned long*)0x7F008120)) //端口J 配置寄存器
GPJCON = 0xaaaaaa;

2).设置LCD时序值和帧缓存初始化

1.MIFPCON 的第三位SEL_BYPASS为0(正常模式)

根据前面的步骤流程图可知,需要将其第三位设为0即可

#define MOFPCON          (*((volatile unsigned long*)0x7410800C)) //调制解调器接口控制寄存器
MOFPCON = 0<<3;

2.SPCON的LCD_SEL[1:0]位设置为01,表示使用 RGB I/F 类型

根据上面的步骤流程图,需要将SPCON的[1:0]位设置为0b01即可

#define SPCON            (*((volatile unsigned long*)0x7F0081A0)) //特殊端口控制寄存器
    SPCON  &= ~(0x3);
    SPCON  |= 0x01;

3.VIDCON0:配置视频输出格式和显示使能/禁止

#define VIDCON0          (*((volatile unsigned long*)0x77100000)) //视频控制0 寄存器
VIDCON0 &= ~((0x3<<26)| (0x3<<17) | (0x1<<16) | (0x3<<2)|(0<<5));

其中时钟源选择HCLK为133MHZ

VCLK=视频时钟源/(CLKVAL+1) 其中。根据4.3寸屏的手册,VCLK的典型值为9MHZ,经过计算,得CLKVAL大约等于14

VIDCON0 |= ((14<<6) | (1<<4)|(3<<0));

4VIDCON1 RGB控制信号

根据时序图,在VCLK的下降沿得到数据

#define VIDCON1          (*((volatile unsigned long*)0x77100004)) //视频控制1 寄存器
    VIDCON1 &= ~(1<<7);
    VIDCON1 |= ((1<<6) | (1<<5));  

5VIDTCONx视频时序控制寄存器

根据上面的几幅图,可以得出时序图:

5.1 VSPW

vspw+1=tvp=10 vspw=9

#define VSPW      9

5.2 VBPD

vbpd+1=tvb=2 vbpd=1

#define VBPD      1

5.3 LINEVAL

一共有272行,272-1=271

#define LINEVAL   272-1
5.4 VFPD

vfpd+1=tvf=2 vfpd=1

#define VFPD      1

5.5 HSPW

hspw+1=thp=41 hspw=40

#define HSPW      40

5.6 HBPD

hbpd+1=thb=2 hbpd=1

#define HBPD      1

5.7 HOZVAL

480-1=479

#define HOZVAL    480-1

5.8 HFPD

hfpd+1=thf=2 hfpd=1

#define HFPD      1

综合上面,即:

#define VSPW      9
#define VBPD      1
#define LINEVAL   272-1
#define VFPD      1
#define HSPW      40
#define HBPD      1
#define HOZVAL    480-1
#define HFPD      1

#define VIDTCON0         (*((volatile unsigned long*)0x77100010)) //视频时序控制0寄存器
#define VIDTCON1         (*((volatile unsigned long*)0x77100014)) //视频时序控制1寄存器
#define VIDTCON2         (*((volatile unsigned long*)0x77100018)) //视频时序控制2寄存器
    VIDTCON0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);
    VIDTCON1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);
    VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);

6WINCON0 窗口0控制寄存器

#define WINCON0          (*((volatile unsigned long*)0x77100020)) //窗口0 控制寄存器   WINCON0 &= ~(0xf << 2);
    WINCON0 |= (0xb<<2);
    WINCON0 = (1<<16)|(0xb<<2)|(1<<0);

7

VIDOSD0A:窗口 0 位置控制 A 寄存器

左上角X,Y坐标

VIDOSD0B:窗口 0 位置控制 B 寄存器

右下角XY坐标

VIDOSD0C:窗口 0 位置控制 C 寄存器

行数列数(1个像素24位,但是占据32位,即4个字节)

同时,单位为word 所以为272*480

#define VIDOSD0A         (*((volatile unsigned long*)0x77100040)) //视频窗口0 的位置控制寄存器
#define VIDOSD0B         (*((volatile unsigned long*)0x77100044)) //视频窗口0 的位置控制寄存器
#define VIDOSD0C         (*((volatile unsigned long*)0x77100048)) //视频窗口0 的位置控制寄存器
#define LeftTopX 0
#define LeftTopY 0
#define RightBotX 479
#define RigntBotY 271
VIDOSD0A = (LeftTopX<<11) |(LeftTopY<<0);
    VIDOSD0B = (RightBotX<<11)|(RigntBotY<<0);
    VIDOSD0C = (LINEVAL+1)*(HOZVAL+1);

8

VIDW00ADD0B0 窗口 0 的缓冲区开始地址控制寄存器,缓冲区 0

存放FRAME_BUFFER的基地址

VIDW00ADD0B1 窗口 0 的缓冲区开始地址控制寄存器,缓冲区 1

VBASEL=VBASEU+(PAGEWIDTH+OFFSIZE)*(LINEVAL+1)=0+(480*4+0)*272

OFFSIZE:偏移值 从0开始

#define FRAME_BUFFER   0x54000000
#define VIDW00ADD0B0     (*((volatile unsigned long*)0x771000A0)) //窗口 0 的缓冲区开始地址控制寄存器,缓冲区 0
#define VIDW00ADD1B0     (*((volatile unsigned long*)0x771000D0)) //窗口 0 的缓冲区开始地址控制寄存器,缓冲区 1
VIDW00ADD0B0 = FRAME_BUFFER;
VIDW00ADD1B0 = (FRAME_BUFFER+((HOZVAL+1)*4+0)*(LINEVAL+1))&(0xffffff);  

通过以上步骤即可实现了LCD的初始化,下面将对其进行测试,观察是否出现正确的图像。

四、测试

这次主要的测试是通过在显示屏上显示一副图片来完成的,

在显示图片之前,需要先将屏幕清一下(可不做)

void lcd_clear()
{
    int x,y,color;

    for(x=0;x<272;x++)
        for(y=0;y<480;y++)
            point(x,y,0xFFFfff);
    //WIN0MAP = (1<<24)|(color&0xffffff);
}

然后可以在屏幕上进行划线,或者将某个区域填充为纯色,具体代码如下

        //划横线 -> 描第201行,第y列
    for(y=100;y<380;y++)
        point(210,y,0xFF0000);  

随后,便可以将图片显示在LCD上

//x0,y0,x(高度),y(宽度) 272*480
Paint_Bmp(0,0,272,480,bmp);

void Paint_Bmp(U16 x0,U16 y0,U16 x,U16 y,const unsigned char gImage_bmp[])
{
    int i, j;
    unsigned char *p = (unsigned char *)gImage_bmp;
    int blue, green, red;
    int color;

    // 图片大小200x200像素
    for (i = x0 ; i < x0 +x; i++)
        for (j = y0; j < y0 + y; j++)
        {
            blue  = *p++;
            green = *p++;
            red   = *p++;

            // D[23:16] = Red data, D[15:8] = Green data,D[7:0] = Blue data

            color = (red << 16)| (green << 8)|( blue << 0);
            point(i, j, color);
        }
}

贴上图片:

稍后

贴上主要代码:

/********************************************
*file name: lcd.c
*author   : stone
*date     : 2016.7.11
*function : lcd的初始化及测试
*********************************************/

#define GPICON           (*((volatile unsigned long*)0x7F008100)) //端口I 配置寄存器
#define GPJCON           (*((volatile unsigned long*)0x7F008120)) //端口J 配置寄存器
#define MOFPCON          (*((volatile unsigned long*)0x7410800C)) //调制解调器接口控制寄存器
#define SPCON            (*((volatile unsigned long*)0x7F0081A0)) //特殊端口控制寄存器
#define VIDCON0          (*((volatile unsigned long*)0x77100000)) //视频控制0寄存器
#define VIDCON1          (*((volatile unsigned long*)0x77100004)) //视频控制1寄存器
#define VIDTCON0         (*((volatile unsigned long*)0x77100010)) //视频时序控制0寄存器
#define VIDTCON1         (*((volatile unsigned long*)0x77100014)) //视频时序控制1寄存器
#define VIDTCON2         (*((volatile unsigned long*)0x77100018)) //视频时序控制2寄存器
#define WINCON0          (*((volatile unsigned long*)0x77100020)) //窗口0 控制寄存器
#define VIDOSD0A         (*((volatile unsigned long*)0x77100040)) //视频窗口0 的位置控制寄存器
#define VIDOSD0B         (*((volatile unsigned long*)0x77100044)) //视频窗口0 的位置控制寄存器
#define VIDOSD0C         (*((volatile unsigned long*)0x77100048)) //视频窗口0 的位置控制寄存器
#define VIDW00ADD0B0     (*((volatile unsigned long*)0x771000A0)) //窗口 0 的缓冲区开始地址控制寄存器,缓冲区 0
#define VIDW00ADD1B0     (*((volatile unsigned long*)0x771000D0)) //窗口 0 的缓冲区开始地址控制寄存器,缓冲区 1

#define WIN0MAP     (*((volatile unsigned long*)0x77100180))

#define VSPW      9
#define VBPD      1
#define LINEVAL   272-1
#define VFPD      1
#define HSPW      40
#define HBPD      1
#define HOZVAL    480-1
#define HFPD      1

#define LeftTopX 0
#define LeftTopY 0
#define RightBotX 479
#define RigntBotY 271

#define FRAME_BUFFER   0x54000000
extern unsigned char bmp[391680];
typedef unsigned short U16;

void lcd_port_init()
{
    GPICON = 0xaaaaaaaa;  //16个引脚都配置为0b10
    GPJCON = 0xaaaaaa;
}

void lcd_config_init()
{
    MOFPCON = 0<<3;

    SPCON  &= ~(0x3);
    SPCON  |= 0x01;

    VIDCON0 &= ~((0x3<<26)| (0x3<<17) | (0x1<<16) | (0x3<<2)|(0<<5));
    VIDCON0 |= ((14<<6) | (1<<4)|(3<<0));

    VIDCON1 &= ~(1<<7);
    VIDCON1 |= ((1<<6) | (1<<5));  

    VIDTCON0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);
    VIDTCON1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);
    VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);

    WINCON0 &= ~(0xf << 2);
    WINCON0 |= (0xb<<2);
    WINCON0 = (1<<16)|(0xb<<2)|(1<<0);

    VIDOSD0A = (LeftTopX<<11) |(LeftTopY<<0);
    VIDOSD0B = (RightBotX<<11)|(RigntBotY<<0);
    VIDOSD0C = (LINEVAL+1)*(HOZVAL+1);  

    VIDW00ADD0B0 = FRAME_BUFFER;
    VIDW00ADD1B0 = (FRAME_BUFFER+((HOZVAL+1)*4+0)*(LINEVAL+1))&(0xffffff);
}

void point(int row, int col, int color)
{

    unsigned long *point = (unsigned long*)FRAME_BUFFER;
    *(point + row*480 + col) = color;
}

void lcd_clear()
{
    int x,y,color;

    for(x=0;x<272;x++)
        for(y=0;y<480;y++)
            point(x,y,0xFFFfff);
    //WIN0MAP = (1<<24)|(color&0xffffff);

}
void Paint_Bmp(U16 x0,U16 y0,U16 x,U16 y,const unsigned char gImage_bmp[])
{
    int i, j;
    unsigned char *p = (unsigned char *)gImage_bmp;
    int blue, green, red;
    int color;

    // 图片大小200x200像素
    for (i = x0 ; i < x0 +x; i++)
        for (j = y0; j < y0 + y; j++)
        {
            blue  = *p++;
            green = *p++;
            red   = *p++;

            // D[23:16] = Red data, D[15:8] = Green data,D[7:0] = Blue data

            color = (red << 16)| (green << 8)|( blue << 0);
            point(i, j, color);
        }
}

/*void Paint_txt(U16 x0,U16 y0,U16 x,U16 y,const unsigned char gImage_bmp[])
{
    int i, j;
    unsigned char *p = (unsigned char *)gImage_bmp;
    int blue, green, red;
    int color;

    // 图片大小200x200像素
    for (i = x0 ; i < x0 +x; i++)
        for (j = y0; j < y0 + y; j++)
        {
            //blue  = *p++;
            //green = *p++;
            //red   = *p++;

            // D[23:16] = Red data, D[15:8] = Green data,D[7:0] = Blue data

            //color = (red << 16)| (green << 8)|( blue << 0);
            color = *p;
            point(i, j, color);
        }
}*/

void lcd_init()
{
    lcd_port_init();
    lcd_config_init();
}

void lcd_test()
{
    int y;

    lcd_clear();

        //划横线 -> 描第150行,第y列
    for(y=100;y<380;y++)
        point(210,y,0xFF0000);  

        //x0,y0,x(高度),y(宽度) 272*480
        Paint_Bmp(0,0,272,480,bmp);

        //Paint_txt(0,0,224,56,zi);

}

菜鸟一枚,如有错误,多多指教。。。

时间: 2024-11-04 13:50:56

嵌入式学习-uboot-lesson14-LCD相关的相关文章

以软件推动工业进步 -嵌入式学习网站

http://www.cnblogs.com/cubean/archive/2010/04/26/1721035.html 以下内容转自:http://bbs.msembed.com/showtopic-1238.aspx 嵌入式入门篇:什么是嵌入式系统                        http://www.helloarm.com/Embedded-Learn/58.htm嵌 入式资深工程师白话说“嵌入式”        http://www.helloarm.com/Embed

嵌入式学习汇总

[转载]嵌入式学习网学习资料下载 (2010-07-23 15:50:15) 转载▼ 标签: 转载   网络资源 原文地址:嵌入式学习网学习资料下载作者:潇楚一生 刚才发现一个论坛上贴的一个帖子,有很多学习资料可以下载,特转发. 学习经验 1.嵌入式Linux操作系统学习规划 http://www.embedstudy.com/?action-viewnews-itemid-342 2.学习ARM嵌入式Linux开发的学习过程 http://www.embedstudy.com/?action-

嵌入式学习笔记103-uboot_1.1.6移植(3)

经过之前对uboot的整体flow分析,现在开始针对2440移植,需要注意的是移植的code可能包含支持部分的2410code 不过并没有在s3c2410板子实测过. 主要概括:第一阶段的汇编code尽量短小,能用C实现的就用C,由于2440的board和头文件是从2410 copy过来的 里面会有很多信息或者宏关于2410,并且很多.c文件的头文件由于include的是2410,所以新增的一些关于2440的结构体也会一并放在2410.h,移植的思想与前文类似, 根据code的执行流程来移植.

嵌入式学习基本

嵌入式工程师需要掌握的内容非常广泛,主要包括嵌入式软件.嵌入式硬件.以及相关行业.产品的专业知识.作为嵌入式初学者,我们不可能,也没有那么多精力把所有的知识到搞的很精通,我们要学会抓住重点,学会取舍,达到一通百通,事半功倍的学习效果. 首先嵌入式技术主要分为嵌入式软件和嵌入式硬件2大方向. 嵌入式硬件方向 嵌入式硬件工程师主要工作职责是为产品设计硬件电路原理图,设计硬件PCB板,选择合适的元器件,焊接调试硬件电路板,保证硬件电路板的可靠性.稳定性和抗干扰能力.因为现在集成电路发展迅速,大部分集成

物联网嵌入式学习路线

嵌入式技术学习路线 ? 嵌入式技术是各种电子产品的核心技术,也是工业4.0.远程医疗.3D打印等新兴产业的核心技术,具有广阔的发展前景.很多计算机.电子信息类专业的学生都想把嵌入式开发作为自己的职业目标,但是因为嵌入式涉及的知识太多,太杂,太广,很多嵌入式初学者陷入嵌入式知识的海洋中,东学一点,西学一点,找不到学习的方向. 作为过来人,给大家谈谈正确的嵌入式学习路线,供各位嵌入式初学者参考,希望对大家有所帮助. 嵌入式工程师需要掌握的内容非常广泛,主要包括嵌入式软件.嵌入式硬件.以及相关行业.产

嵌入式学习笔记101-uboot_1.1.6移植(1)

根据前篇博文(嵌入式学习笔记100-uboot1.1.6初体验)最后的结论,现在开始将其实现: a. 修改makefile的CROSS_COMPILE指定编译器 arm-linux-gcc -v –> gcc version 3.4.5 CROSS_COMPILE = /opt/EmbedSky/crosstools_3.4.5_softfloat/gcc-3.4.5-glibc-2.3.6/arm-linux/bin/arm-linux- chmod -R 777 u-boot-1.1.6/

嵌入式学习(转)

嵌入式系统无疑是当前最热门最有发展前途的IT应用领域之一.嵌入式系统用在一些特定专用设备上,通常这些设备的硬件资源(如处理器.存储器等)非常有限,并且对成本很敏感,有时对实时响应要求很高等.特别是随着消费家电的智能化,嵌入式更显重要.像我们平常常见到的手机.PDA.电子字典.可视电话.VCD/DVD/MP3 Player.数字相机(DC).数字摄像机(DV).U-Disk.机顶盒(Set Top Box).高清电视(HDTV).游戏机.智能玩具.交换机.路由器.数控设备或仪表.汽车电子.家电控制

u-boot支持LCD显示(基于TQ2440)

平台简介 Linux版本:Linux-3.14 u-boot版本:u-boot-2015.04 硬件:TQ2440(内存:64MB  NandFlash:256MB) 作者:彭东林 邮箱:[email protected] 摘要 这个版本的u-boot支持LCD很容易,期间,参考了tq2440官方u-boot中的LCD驱动.我们只需要在配置文件中配置相应的宏,实现LCD的初始化和使能函数即可. 代码我已经上传到CSDN上了,[email protected]:pengdonglin137/u-b

嵌入式学习笔记201-Linux kernel动起来

在前篇博文<嵌入式学习笔记200-Linux kernel初体验>在已经确保环境编译是ok的,接下来让kernel能够最基本的动起来,起码可以看到基本的启动打印! 修改外部输入时钟频率, 修改 linux-2.6.30.4\arch\arm\mach-s3c2440\mach-smdk2440.c 在大概163行将16934400改成12000000. static void __init smdk2440_map_io(void) { s3c24xx_init_io(smdk2440_iod

嵌入式学习笔记104-uboot_1.1.6移植(4)

前面的4篇uboot博文基本概括了uboot的整体flow,现在使能支持启动linux,至此之前请先阅读<嵌入式学习笔记200-Linux kernel初体验>和<嵌入式学习笔记201-Linux kernel动起来>.准备kernel的镜像文件才可以立马检测uboot是否能够启动kernel.在u-boot-1.1.6\include\configs\tq2440.h 最后添加如下几行code: /****************** boot kernel setup ****