#define GLOBAL_CLK 1
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "profile.h"
#define LCD_WIDTH 320 //屏幕宽度
#define LCD_HEIGHT 240 //屏幕高度
#define CLKVAL 4 //时钟信号
//垂直同步信号的脉宽、后肩和前肩
#define VSPW (2-1)
#define VBPD (11-1)
#define VFPD (5-1)
//水平同步信号的脉宽、后肩和前肩
#define HSPW (2-1)
#define HBPD (69-1)
#define HFPD (5-1)
//显示尺寸
#define HOZVAL (LCD_WIDTH-1)
#define LINEVAL (LCD_HEIGHT-1)
#define LED1_on rGPBDAT = ((0xf<<5)^(1<<5)) //GPB5=0
#define LED4_on rGPBDAT = ((0xf<<5)^(1<<8)) //GPB8=0
#define LED_off rGPBDAT = (0xf<<5) //GPB5=1,GPB6=1,GPB7=1,GPB8=1
//定义显示缓存,volatile声明编译不对此进行优化,直接读取原始地址
volatile static U16 LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];
//声明为静态函数,仅在本文件可见,其他文件不能使用该函数
static void LCD_IO_init(void);
static void LCD_init(void);
static void LCD_POWER(void);
void CLK_init(void);
void LCD_on(void);
void LCD_off(void);
void LCD_clear(U16 n);
void BMP_display(int x0,int y0,int x1,int y1,const U8 *bmp);
extern unsigned char gImage_1[]; //extern声明引用外部数组
extern unsigned char gImage_2[];
extern unsigned char gImage_3[];
extern unsigned char gImage_4[];
extern unsigned char gImage_5[];
extern unsigned char gImage_6[];
extern unsigned char gImage_7[];
extern unsigned char gImage_8[];
/**********************************
*主函数
**********************************/
void Main(void)
{
U16 n;
//保存各张图片的尺寸
U16 num[8][2]={320,240,320,240,320,240,320,240
,320,240,320,240,320,240,320,240};
U8 *photo[8]={
gImage_1,gImage_2,
gImage_3,gImage_4,
gImage_5,gImage_6,
gImage_7,gImage_8,
};
rGPBCON=(01<<00);//关闭蜂鸣器
rGPBDAT=0x00;
rGPGCON=((0<<1)|(0<<11)); //GPG0,GPG5为输入,即按键KEY1和KEY3输入
rGPBCON = ((1<<16)|(1<<14)|(1<<12)|(1<<10)); //GPB5~8设为输出
LED_off;
CLK_init();
LCD_POWER();
LCD_IO_init();
LCD_init();
LCD_on();
LCD_clear((0x1f<<11)|(0x3f<<5)|(0x1f) ) ; //清屏显示白色
BMP_display(0, 0, num[0][0], num[0][1], photo[0]); //显示第一张图片
n=0;
while(1)
{
/*利用轮询对按键实行扫描,外加goto调转实现去抖,
可以利用中断对按键检测则去抖问题即可解决*/
m:
if(!(rGPGDAT&(1<<0))) //当KEY1按下
{
LED1_on;
n++;
BMP_display(0, 0, num[n][0], num[n][1], photo[n]);
if(n>7) n=0; //未超出数组范围n自加
if(!(rGPGDAT&(1<<0))) //若按键未放开则进入goto等待按键放开
{
loop1:
if(rGPGDAT&(1<<0)) goto m; //若按键放开再次进入
else //goto返回等待下一次按下
goto loop1;
}
}
else
k:
if(!(rGPGDAT&(1<<5))) //当KEY3按下
{
LED4_on;
if(n==0) n=7; //未超出数组范围n自减
n--;
BMP_display(0, 0, num[n][0], num[n][1], photo[n]);
if(!(rGPGDAT&(1<<5)))
{
loop2:
if(rGPGDAT&(1<<5)) goto k;
else
goto loop2;
}
}
}
}
/**********************************
*时钟初始化
**********************************/
void CLK_init(void)
{
rMPLLCON &= ~0xFFFFF;
rMPLLCON |= (127<<12)|(2<<4)|1; //初始化FCLK为405M
rCLKDIVN = (2<<1)|1; //HCLK = FCLK/4 =100M,PCLK = HCLK/2 = 50M
}
/**********************************
*LCD端口初始化
**********************************/
static void LCD_IO_init(void)
{
rGPCUP=0xff; //GPC口上拉电阻不可用
rGPCCON=0xaaaa02aa;//GPC8-15设置为VD, VM,VFRAME,VLINE,VCLK,LEND
rGPDUP=0xff; //GPD口上拉电阻不可用
rGPDCON=0xaaaaaaaa; //GPD0-15设置为VD
}
/**********************************
*LCD电源管理
**********************************/
static void LCD_POWER(void)
{
rGPGUP=(1<<4);
rGPGCON=(3<<8); //GPG4设置为LCD_PWREN
rLCDCON5=(1<<3); //Enable PWREN signal
}
/**********************************
*LCD初始化
**********************************/
static void LCD_init(void)
{
rLCDCON1=(CLKVAL<<8)|(3<<5)|(12<<1)|(0<<0); //VCLK=10M,TFT LCD,16bpp
rLCDCON2=(VBPD<<24)|(LINEVAL<<14)|(VFPD<<6)|(VSPW);
rLCDCON3=(HBPD<<19)|(HOZVAL<<8)|(HFPD);
rLCDCON4=HSPW;
/*5:6:5Format,Enable PWREN signal,Swap Enable*/
rLCDCON5=(1<<11)|(1<<9)|(1<<8)|(1<<3)|1;
/*显存起始地址[30:22]保存到LCDSADDR1[29:21],显存始地址[21:1]位
保存到LCDSADDR1[20:0],显存结束地址[21:1]保存到LCDSADDR2[20:0]*/
rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|(((U32)LCD_BUFFER&0x3fffff)>>1);
rLCDSADDR2=(((U32)LCD_BUFFER+LCD_WIDTH*LCD_HEIGHT*2)>>1)&0x1fffff;
rLCDSADDR3=LCD_WIDTH; //设置虚拟屏设置为屏幕宽度,没有可以不设置
rTPAL=0; //临时调色板不可用
rLCDINTMSK |=3; //屏蔽 LCD 中断
rTCONSEL &=~(0x17); //LCC3600,LPC3600不可用
}
/**********************************
*LCD开启
**********************************/
void LCD_on(void)
{
rLCDCON1 |=1; //利用LCDCON1控制相关参数实现开启LCD
}
/**********************************
*LCD关闭
**********************************/
void LCD_off(void)
{
rLCDCON1 &=~1; //利用LCDCON1控制相关参数实现关闭LCD
}
/**********************************
*刷新背景颜色
**********************************/
void LCD_clear(U16 n)
{
U32 x,y;
for(y=0;y<LCD_HEIGHT;y++)
{
for(x=0;x<LCD_WIDTH;x++)
{
LCD_BUFFER[y][x]=n;
}
}
}
/**********************************
*BMP数组图片显示
**********************************/
void BMP_display(int x0,int y0,int x1,int y1,const U8 *bmp)
{
int x,y,p=0;
U32 data;
for(y=0;y<y1;y++)
{
for(x=0;x<x1;x++)
{
data=(bmp[p]<<8|bmp[p+1]);
if((x0+x)<LCD_WIDTH && (y0+y)<LCD_HEIGHT)
LCD_BUFFER[y0+y][x0+x]=data;
p=p+2;
}
}
}