基于mini2440按键控制电子相册(裸机代码)

#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

你可能感兴趣的:(C语言,arm,嵌入式,我的学习笔记)