S3C2416裸机开发系列十一_RGB屏驱动显示

发布者:Alisallll最新更新时间:2016-12-12 来源: eefocus关键字:S3C2416  裸机开发  RGB屏  驱动显示 手机看文章 扫描二维码
随时随地手机看文章

很多的嵌入式系统都需要人机交互,对于输出设备,LCD以其显示质量高、画面效果好等优点得到了极其广泛的应用。s3c2416包含了一个LCD控制器,笔者此处就s3c2416的LCD应用作一个简单的介绍。

1、LCD控制器概述

1.1. 接口

s3c2416的LCD控制器包含了一系列的逻辑单元用以支持把图像数据从系统主存储中的帧缓存传输到外部的LCD驱动接口中。LCD的驱动接口支持RGB和i80总线的显示设备。i80是intel提出的标准总线,如目前还在大量使用的8位51单片机,其存储器接口即为i8080接口。这种接口的显示屏内置LCD驱动芯片,有自己的帧缓存,能够自刷新,因此,处理器可以仅在需要修改屏幕显示时传输显示数据到LCD接口中。这种屏需解码处理器过来的命令数据,写屏速度较慢,适用于小尺寸的LCD屏。RGB显示屏显存由系统内存充当,处理器只要把显示的数据写入到相应的帧缓存中,启动显示后,LCD控制器通过专用DMA自动把显存的数据经接口传输到LCD屏中。因此,RGB屏的显示速度可以很快,常用于大尺寸的LCD屏中。笔者采用的是800*480像素点、16位RGB接口屏,因此以RGB接口屏作为讲解。

1.2. 虚拟屏幕

s3c2416 LCD控制器支持虚拟屏幕,可以设置一个较大的帧缓存,用来作为显示数据的缓冲池,屏幕大小是有限的,显示的数据也是有限的,可能只能显示帧缓存的一部分,所以将屏幕要显示的那部分内容叫做帧视口(View Port)。当需要水平或垂直滚屏时,只需更改帧视口相应的地址寄存器即可显示帧缓存中这部分的内容。例如,我们手机的地图应用,手机屏幕能看到的地图只是其中一部分,可以来回拖动看地图的相邻部分,而无需处理器在拖动时更改帧缓存的数据,提高系统性能。

图1-1. 虚拟屏幕滚动实例

1.3. 窗口混合

s3c2416 LCD控制器具有二层窗口,窗口0数据与窗口1对应数据经过alpha混合后再实际输出到屏接口中,其作用就是实现一种半透明(透明度0~1)的效果。可以选择平面混合,也可以选择像素混合,平面混合就是对窗口0与窗口1的所有像素点进行alpha混合,像素混合就是可以定义一种基色值,当窗口中的相应像素色值匹配到设定的基色时,可设定为完全透明,即直接看到背景窗口,窗口未匹配到基色的部分可以设定为原样显示。如果读者了解photoshop的话,窗口混合就像两个图层可以设置不同的透明度混合显示,或上一图层删除选区外的图像(透明基色),实现选中的物体贴合在背景图片上。这种特性可以在我们鼠标光标、不规则按钮的实现等应用中。这种特性可以减少系统总的数据速率,增强系统性能。

图1-2 alpha混合以及基色应用

2. 驱动实现

2.1. RGB驱动编写要点

LCD在使用前需要根据所用屏的参数进行初始化设置,之后上层即可正确调用模块提供的底层驱动函数,实现相应的显示。

设置信号线,RGB接口需用到RGB_HSYNC、RGB_VSYNC、RGB_VCLK、RGB_VDEN、RGB_VD[23:0],从引脚配置寄存器GPCCON、GPDCON中选择相应引脚功能。

设置RGB的数据格式,如设置屏的色深,像素在帧缓存中存放方式是高位在前还是低位在前,笔者使用的是16bpp (non-palletized, R: 5-G:6-B:5 ),像素数据在帧缓存存放方式需半字交换,在WINCON0、WINCON1中进行相应的设置。

设置数据传输时钟,LCD需要一个同步时钟来接收数据,这个参数也决定LCD屏刷新频率。通常LCD屏的刷新频率在60HZ~100HZ之间,低于60HZ,显示可能会闪烁,刷新频率过高也将造成LCD控制器数据传输率大大增加,虽然LCD控制器有LCD-DMA,数据传输时不占用cpu,但需占用系统总线,总线负载大,系统的性能受到影响。通常这个参数根据屏spec进行设置,笔者设置为33M(屏要求26.4M~46.8M)。

时序控制参数设置,根据屏的spec设定VBPD、VFPD、VSPW、HBPD、HFPD、HSPW,这些参数设置均有一定的裕度。VBPD(vertical back porch)表示在一帧图像开始时,垂直同步信号以后的无效的行数;VFBD(vertical front porch)表示在一帧图像结束后,垂直同步信号以前的无效的行数;VSPW(vertical sync pulse width)表示垂直同步脉冲的宽度,用行数计算;HBPD(horizontal back porch)表示从水平同步信号开始到一行的有效数据开始之间的VCLK的个数 ;HFPD(horizontal front porth)表示一行的有效数据结束到下一个水平同步信号开始之间的VCLK的个数;HSPW(horizontal sync pulse width)表示水平同步信号的宽度,用VCLK计算。

屏像素大小设置,屏实际水平像素点减1值(HOZVAL),垂直像素点减1值(LINEVAL)写入到VIDTCON2寄存器中。

帧缓存的地址设置,在窗口0与窗口1中相应的帧缓存地址寄存器中写入帧起启地址以及结束地址。

启用相应的显示窗口、启动LCD控制逻辑进行数据传输并开启背光。

2.2. 编程实现

LCD正确初始化完后,还需各种功能调用实现对屏的驱动显示。如最基本的画点、画线、清屏、显示字符、显示图形等功能。这些功能在各种GUI中均有实现,因此,笔者此处只给出GUI移植时最基本的设置某个像素、读取某个像素的函数实现,其余屏操作实现不再重述。在main.c测试代码中将给出双窗口显示,字体在背景中水平滚动的实例,以让读者对s3c2416 LCD控制器双窗口、alpha混合有一个了解,这种特性在一些应用中是非常有作用的。

模块lcd_rgb.c驱动实现如下:

#include"s3c2416.h"

#include "lcd_rgb.h"

 

#define     VBPD    15

#define     VFPD    5

#define     VSPW    5

#define     HBPD    25

#define     HFPD    88

#define     HSPW    20

 

static unsigned shortFrameBuffer[HSize*VSize];

 

unsigned short*GetFrameBuffer()

{

    return FrameBuffer;

}

 

void LCD_Enable(intEnable)

{

    if (Enable) {

        rVIDCON0 |= (0x03 << 0);

    } else {

        rVIDCON0 &= ~(0x03 << 0);

    }

}

 

voidLCD_BackLight(int On)

{

    rGPBCON &= ~(0x3 << 0);

    rGPBCON |= (0x1 << 0);

    if (On) {

        rGPBDAT |= (0x1 << 0);

    } else {

        rGPBDAT &= ~(0x1 << 0);

    }

}

 

 

void LCD_RGB_Init()

{  

    rGPCCON = 0xaaaa02aa; // GPC配置为RGB数据[7:0]、控制功能   

    rGPDCON = 0xaaaaaaaa; // GPD配置为RGB[23:8]

    LCD_Enable(0);

 

    // 16bpp (R5-G6-B5),第一像素在内存低地址,选择buffer0

    rWINCON0 = (5<<2) | (1<<16) |(0<<23);

    rWINCON1 = (5<<2) | (1<<16) |(1<<6);  

    // 选择HCLK=100M,3分频得到VCLK=33.3M,RGB并口格式(RGB),暂不启动控制逻辑

    rVIDCON0 = (0<<22) |(0<<13) | (0<<12) | (2<<6) |

               (1<<5) | (1<<4) | (0<<2) |(0<<0);

    // VCLK下降沿锁存数据,行场同步信号低激活,数据使能高有效

    rVIDCON1 = (0<<7) |(1<<6) | (1<<5) | (0<<4);   //设置时序控制参数

    rVIDTCON0 =((VBPD-1)<<16) | ((VFPD-1)<<8) | ((VSPW-1)<<0);

    rVIDTCON1 =((HBPD-1)<<16) | ((HFPD-1)<<8) | ((HSPW-1)<<0);

    // 设置屏幕像素尺寸

    rVIDTCON2 =((VSize-1)<<11) | ((HSize-1)<<0);

    // 设置OSD图像与屏幕尺寸一致

    rVIDOSD0A = (0<<11) |(0<<0);

    rVIDOSD0B = ((HSize-1)<<11)| ((VSize-1)<<0);  

    rVIDOSD1A =(0<<11) | (0<0);

    rVIDOSD1B = ((HSize-1)<<11) |((VSize-1)<<0);

    // alpha混合方式,基色匹配时全透明,未匹配部分完全不透明

    rVIDOSD1C = 0xfff000;

    // 设置帧缓存的地址

    rVIDW00ADD0B0 = (unsigned int)FrameBuffer;

    rVIDW00ADD1B0 = ((unsigned int)(FrameBuffer+ HSize*VSize) & 0xffffff);

    // 不使用虚拟屏幕

    rVIDW00ADD2B0 = (00<<13) |((HSize*2)<<0);

    // 窗口0使用

    rWINCON0 |= (1 << 0);

    LCD_Enable(1); 

    LCD_BackLight(1);  

}

 

voidLCD_ClearScreen(unsigned short BackColor)

{

    unsigned int i;

    for (i=0; i

        FrameBuffer[i] = BackColor;

    }  

}

 

voidLCD_SetPixel(unsigned int x, unsigned int y, unsigned short Color)

{

/*  if ((x >= HSize) || (y >= VSize)) {

        return;

    }

*/

    FrameBuffer[y*HSize+x] = Color;

}

 

unsigned shortLCD_GetPixel(unsigned int x, unsigned int y)

{

/*

    if ((x >= HSize) || (y >= VSize)) {

        return 0;

    }

*/ 

    return FrameBuffer[y*HSize+x];

}

 

在头文件lcd_rgb.h中,我们实现模块头文件的定义,如下:

#ifndef __LCD_RGB_H__

#define __LCD_RGB_H__

 

#ifdef__cplusplus

extern"C" {

#endif

 

#define HSize   800// 水平行像素点

#define     VSize   480 // 垂直像素点

 

extern voidLCD_BackLight(int On);

extern voidLCD_Enable(int Enable);

extern voidLCD_RGB_Init(void);

extern voidLCD_ClearScreen(unsigned short BackColor);

externunsigned short *GetFrameBuffer(void);

extern unsignedshort  LCD_GetPixel(unsigned int x,unsigned int y);

extern voidLCD_SetPixel(unsigned int x, unsigned int y, unsigned short Color);

   

#ifdef__cplusplus

}

#endif

#endif

 

在main.c测试代码中,我们设置窗口0显示静态背景图像,窗口1设置为基色匹配,基色为16位纯红(0xf800),400*200的”hello world”字体图像背影为基色。当窗口0与窗口1混合时,窗口1的” hello world”图像基色背景被透明,屏幕显示窗口0的图像,” hello world”字体非基色部分完全不透明显示在屏幕中,改变窗口1的帧缓存地址,实现字体的水平滚动。main.c的验证代码如下:

#include "s3c2416.h"

#include "lcd_rgb.h"

 

extern const unsigned char gImage_picture[];

extern const unsignedchar gImage_hello_world[];

// 窗口1帧缓存,2个屏幕尺寸缓存空间,以支持滚屏

static unsigned shortWin1FrameBuffer[HSize*VSize*2];

 

voidDelay_ms(unsigned int nCount)

{

//延时1ms,共延时nCount(R0) ms

    __asm__ __volatile__ (

        "Delay1:\n\t"  

        "LDR  R1, =100000\n\t"  // Arm clock为400M     

        "Delay2:\n\t"

        "SUBS R1, R1, #1\n\t"  // 一个Arm clock

        "BNE  Delay2\n\t"      // 跳转会清流水线,3个Arm clock

        "SUBS R0, R0, #1\n\t"   // 调用者确保nCount不为0

        "BNE  Delay1\n\t"

        "BX   LR\n\t"

    );

}

 

// 窗口1用作双窗口混合显示示例,给出窗口1的设置代码

void win1_set()

{

    rVIDW01ADD0 = (unsigned int)Win1FrameBuffer;

    rVIDW01ADD1 = ((unsigned int)(Win1FrameBuffer + HSize*VSize) & 0xffffff);

    rVIDW01ADD2 = (00<<13) | ((HSize*2)<<0);

    // 基色匹配使能,匹配16bpp的颜色模式

    rW1KEYCON0 = (1<<25) | (1<<26) |(0x7<<16) | (0x3<<8) | (0x7<<0);

    // 基色设置为纯红

    rW1KEYCON1 = 0xff0000;

    // 窗口1使能

    rWINCON1 |= (1 << 0);

}

 

int main()

{  

    unsigned int j;

    unsigned int i;

    unsigned short *pBuffer;

   

    LCD_RGB_Init();

    win1_set();

    // 加载窗口0的背景图像

    pBuffer = GetFrameBuffer();

    for (i=0; i

        pBuffer[i] = ((unsigned short*)gImage_picture)[i];

    }

    // 窗口1帧缓存初始化为基色(纯红),即窗口1初始化为全透明

    for (i=0;i

        Win1FrameBuffer[i] = 0xf800;

    }

    // 窗口1加载进字体图像,字体图像为400*200,加载到屏幕的右下角开始水平滚动显示

    for (i=0; i<200; i++) {

        for (j=0; j<400; j++) {

            Win1FrameBuffer[(i+280)*800+(j+400)]= ((unsigned short *)gImage_hello_world)[i*400+j];

        }

    }

    pBuffer = Win1FrameBuffer;

 

    while (1) {

        Delay_ms(10);

        rVIDW01ADD0 = (unsigned int)(pBuffer++);

        rVIDW01ADD1 = ((unsigned int)((pBuffer++)+ HSize*VSize) & 0xffffff);

    }

}

 

2.3. 工程搭建

本章节代码采用GCC下的启动代码工程,关于GCC下启动代码的工程搭建请参考笔者” GCC启动代码工程应用实例”这篇文章,下载了GCC启动代码工程,只需简单地修改Makefile加入lcd_rgb.c/lcd_rgb.h屏驱动模块、双窗口混合显示测试代码main.c、图像数据picture.c和hello_world.c即可在顶层目录中make。采用Image2Lcd把图像生成相应的像素数据c文件,MDK下下载MDK启动代码工程,同上加入以上的代码文件即可编译。

2.4. 滚动效果示意

 



3. 附录

lcd_gcc.rar,本章节GCC下RGB屏演示工程,在MDK下开发只需下载MDK启动代码工程,加入lcd_rgb.c/lcd_rgb.h、picture.c、hello_world.c、main.c即可编译。

http://pan.baidu.com/s/1c0krrVE


关键字:S3C2416  裸机开发  RGB屏  驱动显示 引用地址:S3C2416裸机开发系列十一_RGB屏驱动显示

上一篇:S3C2416裸机开发系列十二_IIC驱动实现
下一篇:S3C2416裸机开发系列九_GCC启动代码工程应用实例

推荐阅读最新更新时间:2024-03-16 15:24

串行输入输出共阴极显示驱动器MAX7219应用
MAX7219是美国MAXIM(美信)公司生产的串行输入/输出共阴极显示驱动器。它采用了3线串行接口,传送速率达10M数据,能驱动8位七段数字型LED或条形显示器或64只独立的LED。MAX7219内置BCD码译码器、多路扫描电路、段和数字驱动器和存储每一位的8*8静态RAM。能方便的用模拟或数字方法控制段电流的大小,改变显示器的数量;能进入低功耗的关断模式(仅消耗150uA电流,数据保留);能方便地进行级联。可广泛用于条形图显示、七段显示、工业控制、仪器仪表面板等领域。而且其最重要的一点是,每个显示位都能个别寻址和刷新,而不需要重写其他的显示位,这使得软件编程十分简单且灵活。MAX719后缀表示其封装方式和工作温度,如表所示:
[单片机]
串行输入输出共阴极<font color='red'>显示</font><font color='red'>驱动</font>器MAX7219应用
单片机驱动19264液晶显示汉字c程序
19264液晶是一种比12864大一点点的单色液晶,这里我给大家介绍一下用stc系列单片机驱动他显示汉字的原理 效果图 由于网页空间篇幅有限本文只列出了部分代码,完整版本请从 http://www.51hei.com/f/19264.rar 处下载 #include stc89.h #include intrins.h #define uchar unsigned char #define uint unsigned int uint ee; uchar f; sbit lcd_cs3=P1^0;//片选信号右 低有效 sbit lcd_cs2=P1^1;//片选信号中 低有效 sbit lcd_cs1=P1^
[单片机]
单片机<font color='red'>驱动</font>19264液晶<font color='red'>显示</font>汉字c程序
ARM裸机开发笔记3(ARM寄存器)
37个32位寄存器 31个通用6个状态寄存器 ARM寄存器 ARM共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器.这些寄存器不能被同时访问,但在任何时候,通用寄存器R0~R14,程序计数器PC,一个或两个状态寄存器都是可访问的. 通用寄存器 通用寄存器包括R0~R15,可以分为3类: (1)未分组寄存器R0~R7 (2)分组寄存器R8~R14 (3)程序计数器PC(R15) 这两个寄存器看到时要特别敏感 R13 通常用作椎栈指针SP R14 用作子程序连接寄存器(Link Register_LR) 也称为LR,指向函数的返回地址 异常模式才有SPSR ,SPSR实际上是CPSR的一个
[单片机]
ARM<font color='red'>裸机</font><font color='red'>开发</font>笔记3(ARM寄存器)
使用MAX6954驱动7段LED显示
   MAX6954是一个通用显示驱动器,能够通过一个串口控制多个分立、7段、14段或16段LED显示器。本篇应用笔记介绍驱动8位单色、7段LED显示器的典型应用与配置。 有关MAX6954的详细信息请参考MAX6954的数据资料。   应用笔记"使用MAX6954驱动16段LED显示器" 和"使用MAX6954驱动14段LED显示器" 与本文类似,分别介绍了如何配置MAX6954驱动16段和14段显示器。?                         图1. MAX6954驱动7段显示器电路   MAX6954的一个常见应用是驱动多达16位的7段单色LED。本篇应用笔记指导用户如何连接MAX6954与7段显示器,以及如
[电源管理]
S3C2416裸机开发系列二一_Yaffs的移植
Nand作为市面上最主要的非易失性闪存技术之一,应用在各种固态大容量存储解决方案中。由于Nand flash自身的特点,Nand存储器往往需要一款专用的Nand文件系统进行管理。开源的Yaffs文件系统由于其优异的性能,在Nand flash中受到广泛的应用,笔者此处就Yaffs的移植作一个简单的介绍。 1. Yaffs概述 Yaffs是由Aleph One公司所发展出来的Nand flash文件系统,专门为Nand flash存储器设计,适用于大容量的存储设备。在GPL协议下发布,可在其官网上免费获得源码。 Yaffs是基于日志的文件系统,提供了坏块管理、磨损平衡和掉电恢复的健壮性,保证数据在系统对文件系统修改的过程中发生意外
[单片机]
基于C51单片机的I/O并行口直接驱动LED显示电路图
如图 13 所示,利用 AT89S51 单片机的 P0 端口的 P0.0 - P0.7 连接到一个共阴码管的 a - h 的笔段上,数码管的公共端接地。在数码管上循环显示 0 - 9 数字时间间隔 0.2 秒。   把 “ 单片机系统 ” 区域中的 P0.0/AD0 - P0.7/AD7 端口用 8 芯排线连接到 “ 四路静态数码显示模块 ” 区域中的任一个数码管的 a - h 端口上;要求: P0.0/AD0 与a 相连, P0.1/AD1 与 b 相连,P0.2/AD2 与 c 相连, …… , P0.7/AD7 与 h 相连。
[模拟电子]
基于C51单片机的I/O并行口直接<font color='red'>驱动</font>LED<font color='red'>显示</font>电路图
数码管显示驱动和键盘扫描控制器CH451及其应用
摘要:介绍一种新型的键盘显示驱动芯片CH451的性能特点和工作原理,给出了CH451键盘显示驱动芯片与MCS-51单片机的接口方法与相应的软件驱动程序。 关键词:键盘显示控制;单片机;CH451 单片机在开发过程中,常常会因为资源不足而不得不大量扩展接口芯片以满足应用系统的需要,其中原因之一是人机界面中的键盘显示占用了系统太多资源,从而造成系统庞大,同时降低了系统的可靠性。在单片机应用系统中,键盘显示通常可采用以下几种方式: (1)采用并行接口的键盘显示专用芯片8279。但8279所需外围元件多(显示驱动、译码等)、占用电路板面积大、综合成本高,在中小系统中常常大材小用; (2)采用通用并行I/O芯片扩展(如用8155等
[单片机]
[初级教程]搭建arm-linux裸机开发的环境
1.前言 在上一遍的文章中,我介绍了如何设置芯片的启动模式,根据三星的官方主推的IROM模式,介绍了如何从IROM模式启动,并从Nand中加载我们的引导程序,有了一些前面的知识铺垫后,这一篇文章,我将进一步深入,教你如何实现你的引导程序,并搭建一个调试引导程序的实验环境。这里我介绍两种方式,这两种方式各有前提条件,具体如下: 2.开发环境的搭建 开发环境其实大同小异,总结一下用到的几个: windows主机 vmware虚拟机 在vmware虚拟机中安装ubuntu桌面操作系统或者redhat或者debain或者centOS均可,看你自己习惯 调试工具(H-JTAG或者J-link) H-JTAG和J-link的调试搭建环
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved