我使用的软件平台是MDK,工程当中需要添加 S3C2440A.s ;2440lib.c;main.c;lcd.c;sunflower_240x320.c 这五个程序。
其中sunflower_240x320.c 是一幅BMP格式向日葵图片的 *.c文件,在此不再列出,若没有这个文件,可以用转换工具如 bmp2h.exe 把bmp格式的图片转换成64K色的数组数据(*.c文件);
下面分别列出 main.c;lcd.c 这两个程序。
主程序:
/*********************************************************************************************
* File name: main.c
* Author: ZXL
* Description: 1.显示三基色(红、绿、蓝)到LCD显示屏 2.显示一幅向日葵的图片到LCD显示屏
* History: 2013.5.11
*********************************************************************************************/
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
void init()
{
U32 i;
U8 key;
U32 mpll_val=0;
i = 2 ;
switch ( i ) //设置2440的时钟频率
{
case 0: //200
key = 12;
mpll_val = (92<<12)|(4<<4)|(1);
break;
case 1: //300
key = 13;
mpll_val = (67<<12)|(1<<4)|(1);
break;
case 2: //400
key = 14;
mpll_val = (92<<12)|(1<<4)|(1);
break;
case 3: //440!!!
key = 14;
mpll_val = (102<<12)|(1<<4)|(1);
break;
default:
key = 14;
mpll_val = (92<<12)|(1<<4)|(1);
break;
}
//MDIV=92,PDIV=1,SDIV=1 通过配置MPLLCON,MPLL确定,即FCLK=400MHZ确定
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(key, 12); //FCLK:HCLK:PCLK = 1:1/4:1/8 =400M:100M:50M
Port_Init();
Uart_Init(0,115200);
Uart_Select(0);
Uart_Printf("\n LCD Test Begin!!!\n");
}
int main(int argc, char **argv)
{
init(); //系统频率、GPIO引脚、串口初始化
LCD_Init(); //LCD初始化
while(1)
{
TFT_LCD_Show(); //显示图片
}
}
lcd.c程序:
/*********************************************************************************************
* File name: lcd.c
* Author: ZXL
* Description: 1.显示三基色(红、绿、蓝)到LCD显示屏2.显示一幅向日葵的图片到LCD显示屏
* History: 2013.5.11
*********************************************************************************************/
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#define LCD_X35 //NEC 256K色240*320/3.5英寸TFT真彩液晶屏,每一条水平线上包含240个像素点,共有320条这样的线
#if defined(LCD_X35)
#define LCD_WIDTH 240
#define LCD_HEIGHT 320
#define LCD_PIXCLOCK 4
#define LCD_RIGHT_MARGIN 39
#define LCD_LEFT_MARGIN 16
#define LCD_HSYNC_LEN 5
#define LCD_UPPER_MARGIN 1
#define LCD_LOWER_MARGIN 5
#define LCD_VSYNC_LEN 1
#endif
#define LCD_XSIZE LCD_WIDTH
#define LCD_YSIZE LCD_HEIGHT
#define SCR_XSIZE LCD_WIDTH
#define SCR_YSIZE LCD_HEIGHT
extern U8 sunflower_240x320[]; //导入一幅向日葵图片
volatile static U16 LCD_BUFFER[SCR_YSIZE][SCR_XSIZE]; //定义320行,240列的数组,用于存放显示数据
#define M5D(n)((n)&0x1fffff)
#define LCD_ADDR ((U32)LCD_BUFFER)
static void delay(int times)
{
int i,j;
for(i=0;i<times;i++)
for(j=0;j<400;j++);
}
void Lcd_ClearScr( U16 c) /*填充全屏为某个单一颜色*/
{
U32 x,y ;
for( y = 0 ; y < SCR_YSIZE ; y++ )
{
for( x = 0 ; x < SCR_XSIZE ; x++ )
{
LCD_BUFFER[y][x] = c ;
}
}
}
void print_Bmp(int x0,int y0,int h,int l,const U8 *bmp)/*在屏幕上画图*/
{
int x,y;
U32 c;
int p = 0;
for( y = 0 ; y < l ; y++ )
{
for( x = 0 ; x < h ; x++ )
{
c = bmp[p+1] | (bmp[p]<<8) ;
if ( ( (x0+x) < SCR_XSIZE) && ( (y0+y) < SCR_YSIZE) )
LCD_BUFFER[y0+y][x0+x] = c ;
p = p + 2 ;
}
}
}
void Lcd_OnOff(int onoff) /*LCD开关*/
{
if(onoff==1) rLCDCON1 |= 1; //使能LCD
else rLCDCON1 =rLCDCON1 & 0x3fffe; //关闭LCD
}
void Lcd_Port_Init() /*端口初始化*/
{
rGPCUP=0xffffffff; //禁止上拉电阻
rGPCCON=0xaaaa02a8; //初始化 VD[7:0],VM,VFRAME,VLINE,VCLK
rGPDUP=0xffffffff; //禁止上拉电阻
rGPDCON=0xaaaaaaaa; //初始化 VD[15:8]
}
void LCD_Init() /*LCD初始化*/
{
Lcd_Port_Init();/*端口初始化*/
/*显示模式初始化*/
rLCDCON1=(LCD_PIXCLOCK<<8)|(3<<5)|(12<<1);//CLKVAL=4, 使用TFT LCD,设置为16bpp.
rLCDCON2=(LCD_UPPER_MARGIN<<24)|((LCD_HEIGHT-1)<<14)|(LCD_LOWER_MARGIN<<6)|(LCD_VSYNC_LEN<<0);//VBPD=1,行数=320-1,VFPD=5,VSPW=1
rLCDCON3=(LCD_RIGHT_MARGIN<<19)|((LCD_WIDTH-1)<<8)|(LCD_LEFT_MARGIN<<0);//HBPD=36,列数=240-1,HFPD=19
rLCDCON4=(13<<8)|(LCD_HSYNC_LEN<<0); //MVAL=13(只有当LCDCON1的bit[7]MMODE=1才有效),HSPW=5
rLCDCON5=(1<<11)|(1<<9)|(1<<8)|(1<<3)|(1<<0);//TFT为5:6:5格式,VLINE/HSYNC的脉冲极性反转,VFRAME/VSYNC也反转,使能PWERN信号,选用半字交换
/*
LCDBANK: 视频帧缓冲区内存地址 30-22位
LCDBASEU: 视频帧缓冲区的开始地址 21-1位
LCDBASEL: 视频帧缓冲区的结束地址 21-1位
PAGEWIDTH:虚拟屏幕一行的字节数,如果不使用虚拟屏幕,设置为实际屏幕的行字节数
OFFSIZE:虚拟屏幕左侧偏移的字节数,如果不使用虚拟屏幕,设置为0
*/
/*帧缓冲地址初始化*/
rLCDSADDR1 = ((LCD_ADDR >> 22) << 21) | ((M5D(LCD_ADDR >> 1)) << 0);
rLCDSADDR2 = M5D((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2) >> 1);
rLCDSADDR3 = LCD_WIDTH;
rLCDINTMSK |= 3; //LCD帧同步中断屏蔽。LCD的FIFO中断屏蔽
rTCONSEL &= (~7); //屏蔽LPC3600相关中断
rTCONSEL &= ~((1<<4) | 1);/*禁止LPC3600/LCC3600模式*/
rTPAL = 0x0;/*disable调色板*/
Lcd_OnOff(1);/*打开LCD*/
}
void TFT_LCD_Show()
{
/*红(255:0:0);绿(0:255:0);蓝(0:0:255);黑(0:0:0);白(255,255,255)*/
/*在屏幕上显示三基色*/
Lcd_ClearScr((0x00<<11) | (0x00<<5) | (0x00)); //全屏为黑
delay(10000);
Lcd_ClearScr((0x1f<<11) | (0x00<<5) | (0x00)); //全屏为红
delay(10000);
Lcd_ClearScr((0x00<<11) | (0x3f<<5) | (0x00)); //全屏为绿
delay(10000);
Lcd_ClearScr((0x00<<11) | (0x00<<5) | (0x1f)); //全屏为蓝
delay(10000);
Lcd_ClearScr((0x1f<<11) | (0x3f<<5) | (0x1f)); //全屏为白
delay(10000);
print_Bmp(0, 0, 240, 320, sunflower_240x320); /*显示一副向日葵图片在屏幕上*/
delay(10000);
}