1. 程式人生 > >基於mini2440簡單計算器的實現(裸機程式碼)

基於mini2440簡單計算器的實現(裸機程式碼)

基於mini2440簡易計算器使用的是陣列實現,並非逆波蘭式,因此功能不夠強大,僅供驅動學習,以及C語言基礎程式設計學習之用.有時間讀者可以用逆波蘭式來實現強大功能計算器,原理也很簡單,建議讀《c程式設計第二版》裡面有演算法的程式碼.讀者自行研究.此程式基於電子相簿的改進,觸控式螢幕,LCD,字元現實,數字輸入等等.

主函式部分:

#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "profile.h"


extern U32 X,Y;

extern void BMP_display(int x0,int y0,int x1,int y1,const U8 *bmp);

extern void CLK_init(void);
extern void LCD_IO_init(void);
extern void LCD_POWER(void);
extern void LCD_init(void);
extern void LCD_on(void);
extern void LCD_off(void);
extern void Tc_calibrate(void);
extern void input(void);
extern void Touch_Init(void);
extern void word(int x,int y,char* string);

extern unsigned char gImage[];	//extern宣告引用外部陣列

void Main(void)
{

    rGPBCON=(1<<0);
    rGPBDAT=(0<<0);//關閉蜂鳴器

    CLK_init();
	LCD_POWER();
    LCD_IO_init();
    LCD_init();
    LCD_on();
	Touch_Init();
	MMU_Init();	//初始化MMU,解決中斷向量表入口地址與記憶體地址之間不一致問題,進行地址的重對映
	
    BMP_display(0, 0, 320,240, gImage);	//顯示圖片
	
    while(1)
    { 
	    Tc_calibrate();
		input();
    }
	
}
計算器的輸入及其計算部分,結合觸控式螢幕,利用陣列實現字元和數字的儲存等:
#include "def.h"
#include "2440addr.h"

#define touch_p  (X>0&&X<80&&Y>198&&Y<240)
#define touch_0  (X>80&&X<160&&Y>198&&Y<240)
#define touch_e  (X>160&&X<240&&Y>198&&Y<240)
#define touch_a  (X>240&&X<320&&Y>198&&Y<240)

#define touch_1  (X>0&&X<80&&Y>156&&Y<198)
#define touch_2  (X>80&&X<160&&Y>156&&Y<198)
#define touch_3  (X>160&&X<240&&Y>156&&Y<198)
#define touch_s  (X>240&&X<320&&Y>156&&Y<198)

#define touch_4  (X>0&&X<80&&Y>113&&Y<156)
#define touch_5  (X>80&&X<160&&Y>113&&Y<156)
#define touch_6  (X>160&&X<240&&Y>113&&Y<156)
#define touch_m  (X>240&&X<320&&Y>113&&Y<156)

#define touch_7  (X>0&&X<80&&Y>72&&Y<113)
#define touch_8  (X>80&&X<160&&Y>72&&Y<113)
#define touch_9  (X>160&&X<240&&Y>72&&Y<113)
#define touch_d  (X>240&&X<320&&Y>72&&Y<113)

#define touch_c  (X>241&&X<320&&Y>44&&Y<73)

#define white 0xffffff
#define B_off rGPBDAT=(0<<0) //關閉蜂鳴器
#define B_on  rGPBDAT=(1<<0) //開啟蜂鳴器

extern U32 X,Y;
extern unsigned char gImage[];	//extern宣告引用外部陣列

extern Draw_REC(int x,int y,int x1,int y1,U32 color);
extern void BMP_display(int x0,int y0,int x1,int y1,const U8 *bmp);
extern void Draw_ASCII(U32 x,U32 y,U32 color,const unsigned char ch[]);
extern void word(int x,int y,char* string);
extern void Main(void);

char op,opf;//用於何種元算的分揀操作符
int Num1,Num2;//參與運算兩個數
int F1,F2;//答案
char num[10000];//用於顯示的字元陣列
int num1[100],num2[100];//儲存輸入數字的陣列
int n[100],t[100]; //提取答案的各個位
int n1=0,n2=0;//用於輸入數字分揀操作符
int len=0,len1=0;//用於計算答案的位數
int i=0,j=0,k=0,a=0;

/********************************** 
*清除各個標誌函式
**********************************/
void Clear_f(void)
{
	int b=0,c=0;
	
	for(c=0;c<10000;c++)
	{
		num[c]=' ';
	}
	for(b=0;b<100;b++)
	{
		num1[b]=0;
		num2[b]=0;
		n[b]=0;
		t[b]=0;
	}
	op=0;opf=0;
	Num1=0;Num2=0;
	F1=0;F2=0;
	n1=0;n2=0;
	len=0;len1=0;
	i=0;j=0;k=0;a=0;
}
/********************************** 
*四則運算函式
**********************************/
void Calc(int *Num_1,int *Num_2,int *f)
{
	switch(op)	//分揀操作符
	{
	case'n':	//無運算或等號
		*f = *f;
		break;
	case '+':	//加
		*f = *Num_1+*Num_2;
		break;
	case '-':	//減
		*f = *Num_1-*Num_2;
		break;
	case '*':	//乘
		*f =*Num_1*(*Num_2);
		break;
	case '/':		//除
		*f = *Num_1/(*Num_2);
		break;
	}	
}

/********************************** 
*延遲函式
**********************************/
void delay(int times)
{
    int i;
    for(;times>0;times--)
	for(i=0;i<400;i++);
}

/********************************** 
*介面輸入函式
**********************************/
void input(void)
{
	int flag=0;
	
	int numb[10]={0,1,2,3,4,5,6,7,8,9};
	char nums[10]={'0','1','2','3','4','5','6','7','8','9'};	
	
	if(op=='+'||op=='-'||op=='*'||op=='/') flag=1;
	else flag=0;
	if(flag==0)//無操作符
	{
		if(touch_0) 
		{
			num[i]='0';
			num1[i]=0;
			i++;
			n1++;
			Draw_REC(80,198,160,239,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_1)
		{
			num[i]='1';
			num1[i]=1;
			i++;
			n1++;
			Uart_Printf("n1=%4d\n",n1);
			Draw_REC(0,156,80,198,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_2) 
		{
			num[i]='2';
			num1[i]=2;
			i++;
			n1++;
			Draw_REC(80,156,160,198,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_3) 
		{
			num[i]='3';
			num1[i]=3;
			i++;
			n1++;
			Draw_REC(160,156,240,198,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_4)
		{
			num[i]='4';
			num1[i]=4;
			i++;
			n1++;
			Draw_REC(0,113,80,156,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_5)
		{
			num[i]='5';
			num1[i]=5;
			i++;
			n1++;
			Draw_REC(80,113,160,156,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_6) 
		{
			num[i]='6';
			num1[i]=6;
			i++;
			n1++;
			Draw_REC(160,113,240,156,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_7)
		{
			num[i]='7';
			num1[i]=7;
			i++;
			n1++;
			Draw_REC(0,72,80,113,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_8) 
		{
			num[i]='8';
			num1[i]=8;
			i++;
			n1++;
			Draw_REC(80,72,160,113,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_9)
		{
			num[i]='9';
			num1[i]=9;
			i++;
			n1++;
			Draw_REC(160,72,240,113,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		
	}
	else
	{
		if(touch_0) 
		{
			num[i]='0';
			num2[j]=0;
			i++;
			j++;
			n2++;
			Draw_REC(80,198,160,239,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_1)
		{
			num[i]='1';
			num2[j]=1;
			i++;
			j++;
			n2++;
			Draw_REC(0,156,80,198,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_2) 
		{
			num[i]='2';
			num2[j]=2;
			i++;
			j++;
			n2++;
			Draw_REC(80,156,160,198,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_3) 
		{
			num[i]='3';
			num2[j]=3;
			i++;
			j++;
			n2++;
			Draw_REC(160,156,240,198,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_4)
		{
			num[i]='4';
			num2[j]=4;
			i++;
			j++;
			n2++;
			Draw_REC(0,113,80,156,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_5)
		{
			num[i]='5';
			num2[j]=5;
			i++;
			j++;
			n2++;
			Draw_REC(80,113,160,156,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_6) 
		{
			num[i]='6';
			num2[j]=6;
			i++;
			j++;
			n2++;
			Draw_REC(160,113,240,156,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_7)
		{
			num[i]='7';
			num2[j]=7;
			i++;
			j++;
			n2++;
			Draw_REC(0,72,80,113,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_8) 
		{
			num[i]='8';
			num2[j]=8;
			i++;
			j++;
			n2++;
			Draw_REC(80,72,160,113,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
		else if(touch_9)
		{
			num[i]='9';
			num2[j]=9;
			i++;
			j++;
			n2++;
			Draw_REC(160,72,240,113,white);
			B_on;
			delay(1000);
			B_off;
			BMP_display(0,0,320,240,gImage);
		}
	}
	
	if(touch_p) 
	{
		op='.';
		num[i]='.';
		i++;
		Draw_REC(0,198,80,239,white);
		B_on;
		delay(1000);
		B_off;
		BMP_display(0,0,320,240,gImage);
	}
	else if(touch_e)
	{
		opf='=';
		//num[i]='=';
		//i++;
		Draw_REC(160,198,240,239,white);
		B_on;
		delay(1000);
		B_off;
		BMP_display(0,0,320,240,gImage);
	}
	else if(touch_a)
	{
		op='+';
		num[i]='+';
		i++;
		Draw_REC(240,198,319,239,white);
		B_on;
		delay(1000);
		B_off;
		BMP_display(0,0, 320,240,gImage);
	}
	else if(touch_s)
	{
		op='-';
		num[i]='-';
		i++;
		Draw_REC(240,156,319,198,white);
		B_on;
		delay(1000);
		B_off;
		BMP_display(0,0,320,240,gImage);
	}
	else if(touch_m)
	{
		op='*';
		num[i]='*';
		i++;
		Draw_REC(240,113,319,156,white);
		B_on;
		delay(1000);
		B_off;
		BMP_display(0,0,320,240,gImage);
	}
	else if(touch_d)
	{
		op='/';
		num[i]='/';
		i++;
		Draw_REC(240,72,319,113,white);
		B_on;
		delay(1000);
		B_off;
		BMP_display(0,0,320,240,gImage);
	}
	else if(touch_c)
	{
		Draw_REC(241,44,319,73,white);
		B_on;
		delay(1000);
		B_off;
		BMP_display(0,0,320,240,gImage);
		Clear_f();
	}
	
	switch(n1)
	{
	case 1:Num1=num1[0];break;
	case 2:Num1=num1[0]*10+num1[1];break;
	case 3:Num1=num1[0]*100+num1[1]*10+num1[2];break;
	case 4:Num1=num1[0]*1000+num1[1]*100+num1[2]*10+num1[3];break;
	case 5:Num1=num1[0]*10000+num1[1]*1000+num1[2]*100+num1[3]*10+num1[4];break;
	case 6:Num1=num1[0]*100000+num1[1]*10000+num1[2]*1000+num1[3]*100+num1[4]*10+num1[5];break;
	}
	
	switch(n2)
	{
	case 1:Num2=num2[0];break;
	case 2:Num2=num2[0]*10+num2[1];break;
	case 3:Num2=num2[0]*100+num2[1]*10+num2[2];break;
	case 4:Num2=num2[0]*1000+num2[1]*100+num2[2]*10+num2[3];break;
	case 5:Num2=num2[0]*10000+num2[1]*1000+num2[2]*100+num2[3]*10+num2[4];break;
	case 6:Num2=num2[0]*100000+num2[1]*10000+num2[2]*1000+num2[3]*100+num2[4]*10+num2[5];break;
	}
	
	word(0,28,num);
	X=0;
	Y=0;
	
	if(opf=='=')
	{
		Calc(&Num1,&Num2,&F1);
		F2=F1;
		while(F2>0)
		{ 
			t[a++]=F2%10;
			F2=F2/10;
			len++;
		}
		len1=len;
		a=0;
		while(len1--)
		{
			n[len1]=t[a++];
		}
		
		switch(len)
		{
		case 1:
			{
				for(k=0;k<10;k++)
				{if(numb[k]==n[0]) num[i+1]=nums[k];};break;
			}
		case 2:
			{
				for(k=0;k<10;k++)
				{if(numb[k]==n[0]) num[i+1]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[1]) num[i+2]=nums[k];};break;
			}
		case 3:
			{
				for(k=0;k<10;k++)
				{if(numb[k]==n[0]) num[i+1]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[1]) num[i+2]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[2]) num[i+3]=nums[k];};break;
			}
		case 4:
			{
				for(k=0;k<10;k++)
				{if(numb[k]==n[0]) num[i+1]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[1]) num[i+2]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[2]) num[i+3]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[3]) num[i+4]=nums[k];};break;
			}
		case 5:
			{
				for(k=0;k<10;k++)
				{if(numb[k]==n[0]) num[i+1]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[1]) num[i+2]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[2]) num[i+3]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[3]) num[i+4]=nums[k];}
				for(k=0;k<10;k++)
				{if(numb[k]==n[4]) num[i+5]=nums[k];};break;
			}
		}
		word(0,28,num);
		Uart_Printf("Num1=%4d, Num2=%4d,F1=%4d\n",Num1,Num2,F1);
		op=0;
		opf=0;
	}
}

LCD驅動部分:
#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)

//定義顯示快取,volatile宣告編譯不對此進行優化,直接讀取原始地址
volatile unsigned short LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];	

//宣告為靜態函式,僅在本檔案可見,其他檔案不能使用該函式

/********************************** 
*時鐘初始化
**********************************/
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埠初始化
**********************************/
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電源管理
**********************************/
void LCD_POWER(void)
{
rGPGUP=(1<<4);
rGPGCON=(3<<8);		//GPG4設定為LCD_PWREN
rLCDCON5=(1<<3);	//Enable PWREN signal
}

/********************************** 
*LCD開啟
**********************************/
void LCD_on(void)
{
    rLCDCON1 |=1;	//利用LCDCON1控制相關引數實現開啟LCD
}

/********************************** 
*LCD關閉
**********************************/
void LCD_off(void)
{
    rLCDCON1 &=~1;	//利用LCDCON1控制相關引數實現關閉LCD
}

/********************************** 
*LCD初始化
**********************************/
void LCD_init(void)
{
    CLK_init();
	LCD_POWER();
    LCD_IO_init();
    LCD_on();
	
	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不可用
}

GUI部分,字元,圖片處理函式等:
#include "def.h"
#include "Font_libs.h" 

#define LCD_WIDTH 320	//螢幕寬度
#define LCD_HEIGHT 240	//螢幕高度

//定義顯示快取,volatile宣告編譯不對此進行優化,直接讀取原始地址
extern volatile unsigned short LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];

/********************************** 
*重新整理背景顏色
**********************************/
void LCD_clear(U32 color)
{
    U32 x,y;
    for(y=0;y<LCD_HEIGHT;y++)
    {
        for(x=0;x<LCD_WIDTH;x++)
        {
            LCD_BUFFER[y][x]=color;
        }
    }
}

/********************************** 
*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;
        }
    }
}

/********************************** 
*繪製畫素點
**********************************/
void PutPixel(U32 x,U32 y,U32 c )
{
	LCD_BUFFER[y][x]=c;
}

/********************************** 
*繪製大小為16×16的中文字元
**********************************/
void Draw_Text16(U32 x,U32 y,U32 color,const unsigned char ch[])
{
	unsigned short int i,j;
	unsigned char mask,buffer;
	for(i=0;i<16;i++)
	{
		mask=0x80;                  //掩碼
		buffer=ch[i*2];             //提取一行的第一個位元組
		for(j=0;j<8;j++)
		{                  
			if(buffer&mask)
			{
				PutPixel(x+j,y+i,color);        //為筆畫上色
			}
			mask=mask>>1;                  
		}
		
		mask=0x80;                  //掩碼復位
		buffer=ch[i*2+1];         //提取一行的第二個位元組
		for(j=0;j<8;j++)
		{                  
			if(buffer&mask)
			{
				PutPixel(x+j+8,y+i,color);           //為筆畫上色
			}
			mask=mask>>1;                  
		}
	}
}

/********************************** 
*繪製大小為8×16的ASCII碼
**********************************/
void Draw_ASCII(U32 x,U32 y,U32 color,const unsigned char ch[])
{
	unsigned short int i,j;
	unsigned char mask,buffer;
	for(i=0;i<16;i++)
	{
		mask=0x80;
		buffer=ch[i];
		for(j=0;j<8;j++)
		{                  
			if(buffer&mask)
			{
				PutPixel(x+j,y+i,color);
			}
			mask=mask>>1;                  
		}
	}
}

/********************************** 
*繪製中文字元或ASCII
**********************************/
void word(int x,int y,char* string)
{
	int i,j=0;
	unsigned char qh,wh;
	const unsigned char *mould;
	int length=0;
	
	while(string[length]!='\0')
	{length++;}
	
	for(i=0;i<=length-1;i++)
		{
			if(string[i]&0x80)        //中文字元
			{
				qh=string[i]-0xa0;            //區號
				wh=string[i+1]-0xa0;          //位號
				mould=& __CHS[((qh-1)*94+wh-1)*32 ];
				Draw_Text16(x+j,y,0xffffff,mould);
				j+=16;//每寫完一個右移16個畫素
				i++;
			}
			else  //ASCII碼字元
			{
				mould=&__ASCII[string[i]*16];
				Draw_ASCII(x+j,y,0xffffff,mould);
				j+=8;//每寫完一個右移8個畫素
			}
		}
}

/********************************** 
*畫直線
**********************************/
void Draw_Line(int x1,int y1,int x2,int y2,U32 color)
{
	int dx,dy,e;
	dx=x2-x1; 
	dy=y2-y1;
    
	if(dx>=0)
	{
		if(dy >= 0) // dy>=0
		{
			if(dx>=dy) // 1/8 octant
			{
				e=dy-dx/2;
				while(x1<=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1+=1;e-=dx;}	
					x1+=1;
					e+=dy;
				}
			}
			else		// 2/8 octant
			{
				e=dx-dy/2;
				while(y1<=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1+=1;e-=dy;}	
					y1+=1;
					e+=dx;
				}
			}
		}
		else		   // dy<0
		{
			dy=-dy;   // dy=abs(dy)

			if(dx>=dy) // 8/8 octant
			{
				e=dy-dx/2;
				while(x1<=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1-=1;e-=dx;}	
					x1+=1;
					e+=dy;
				}
			}
			else		// 7/8 octant
			{
				e=dx-dy/2;
				while(y1>=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1+=1;e-=dy;}	
					y1-=1;
					e+=dx;
				}
			}
		}	
	}
	else //dx<0
	{
		dx=-dx;		//dx=abs(dx)
		if(dy >= 0) // dy>=0
		{
			if(dx>=dy) // 4/8 octant
			{
				e=dy-dx/2;
				while(x1>=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1+=1;e-=dx;}	
					x1-=1;
					e+=dy;
				}
			}
			else		// 3/8 octant
			{
				e=dx-dy/2;
				while(y1<=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1-=1;e-=dy;}	
					y1+=1;
					e+=dx;
				}
			}
		}
		else		   // dy<0
		{
			dy=-dy;   // dy=abs(dy)

			if(dx>=dy) // 5/8 octant
			{
				e=dy-dx/2;
				while(x1>=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1-=1;e-=dx;}	
					x1-=1;
					e+=dy;
				}
			}
			else		// 6/8 octant
			{
				e=dx-dy/2;
				while(y1>=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1-=1;e-=dy;}	
					y1-=1;
					e+=dx;
				}
			}
		}	
	}
}

/**************************************************************
在LCD螢幕上畫一個矩形
**************************************************************/
void Draw_REC(int x1,int y1,int x2,int y2,U32 color)
{
	Draw_Line(x1,y1,x2,y1,color);
	Draw_Line(x2,y1,x2,y2,color);
	Draw_Line(x1,y2,x2,y2,color);
	Draw_Line(x1,y1,x1,y2,color);
}

/********************************** 
*畫圓函式
**********************************/
void Draw_Circular(U32 c)
{
	int x,y ;
	int tempX,tempY;
	int radius=80;
	int SquareOfR=radius*radius;
	
    for( y=0;y<LCD_WIDTH;y++ )
    {
		for( x=0; x<LCD_HEIGHT;x++ )
		{
			if(y<=120&&x<=160)
			{
				tempY=120-y;
				tempX=160-x;                        
			}
			else if(y<=120&&x>=160)
			{
				tempY=120-y;
				tempX=x-160;                        
			}
			else if(y>=120&& x<=160)
			{
				tempY=y-120;
				tempX=160-x;
			}
			else
			{
				tempY=y-120;
				tempX=x-160;
			}
			
			if ((tempY*tempY+tempX*tempX)<=SquareOfR)
				LCD_BUFFER[y][x] =c;
		}
    }
}

觸控式螢幕的ADC驅動部分:
#include "def.h"
#include "mmu.h"
#include "2440addr.h"
#include "2440lib.h"

#define PRSCVL 9

volatile int xdata, ydata;

int inte=1;

void __irq Adc_Tc_Handler(void);

void Touch_Init(void)
{
    rADCCON=((1<<14)|(PRSCVL<<6));    //A/D分頻時鐘有效,其值為9
	rADCTSC=0xd3;  //游標按下中斷訊號,YM有效,YP無效,XM有效,XP無效,XP上拉電阻,普通ADC轉換,等待中斷模式
	rADCDLY=50000; //正常轉換模式轉換延時大約為(1/3.6864M)*50000=13.56ms
	
	rINTSUBMSK &=~(1<<9);//TC中斷使能
	rINTMSK &=~(1<<31);//ADC總中斷使能
	
	pISR_ADC=(int)Adc_Tc_Handler;//指向中斷向量表
	
}

void __irq Adc_Tc_Handler(void)
{

	rADCTSC|=(1<<3)|(1<<2); //XP上拉電阻無效, 自動連續測量X座標和Y座標.
	rADCCON|=(1<<0);//ADC轉換開始

	while(rADCCON&(1<<0));//檢測ADC轉換是否開始且ADCCON[0]自動清0
	while(!(rADCCON&(1<<15))); //檢測ADCCON[15]是否為1,ADC轉換是否結束,(必須)
	while(!(rINTPND&(1<<31)));//檢測ADC中斷是否已請求
	
	xdata=rADCDAT0&0x3ff;//讀x座標
	ydata=rADCDAT1&0x3ff;//讀y座標
	
	Uart_Printf("\nXdata=%04d, Ydata=%04d\n", xdata, ydata);

	rSUBSRCPND|=(1<<9);
	rSRCPND|=(1<<31);
	rINTPND|=(1<<31);
	
	rADCTSC =0xd3;     //ADC等待中斷模式	
	rADCTSC|=(1<<8);  //ADCTSC[8]=1,設定擡起中斷訊號
	
	while(!(rSUBSRCPND&(1<<9)));	//檢測觸屏擡起中斷是否已請求	

	rADCTSC &=~(1<<8);//ADCTSC[8]=0游標按下中斷訊號
	rSUBSRCPND|=(1<<9);
	rSRCPND|=(1<<31);
	rINTPND|=(1<<31);
	inte=1;
}

觸控式螢幕矯正及其計算部分(三點矯正):

#include "def.h"
#include "2440addr.h"
#include "2440lib.h"

#define LCD_CALIBRATE 0  //1時開啟觸控式螢幕校驗
#define BLACK (0x000000)  //黑色
#define WHITE (0xffffff)  //白色
#define YdataClear ydata=0
#define XdataClear xdata=0

extern volatile int xdata, ydata;
extern int inte;

extern void LCD_clear(U32 n);
extern void Draw_X(int x,int y,U32 color);
extern void CLK_init(void);
extern void LCD_IO_init(void);
extern void LCD_POWER(void);
extern void LCD_init(void);
extern void LCD_on(void);
extern void LCD_off(void);
extern void Touch_Init(void);

U32 X,Y;
float x0,y0,x1,y1,x2,y2;
float xt,yt;
float A=-0.363030314,B=-0.00609157188,C=349.596954,D=-0.00253245141,E=0.312928855,F=-38.1721191,K=292207;

//讀取TC座標
void Touch_GetAdXY(float *x,float *y)
{
	*x=xdata;
	*y=ydata;
}

//矯正引數A,B,C,D,E,F,K的計算
void Calculate_P(float xt0,float yt0,float xt1,float yt1,float xt2,float yt2)
{
    float xd0=160,yd0=40,xd1=40,yd1=180,xd2=260,yd2=200;
	K=(xt0-xt2)*(yt1-yt2)-(xt1-xt2)*(yt0-yt2);
	A=((xd0-xd2)*(yt1-yt2)-(xd1-xd2)*(yt0-yt2))/K;
	B=((xt0-xt2)*(xd1-xd2)-(xd0-xd2)*(xt1-xt2))/K;
	C=(yt0*(xt2*xd1-xt1*xd2)+yt1*(xt0*xd2-xt2*xd0)+yt2*(xt1*xd0-xt0*xd1))/K;
	D=((yd0-yd2)*(yt1-yt2)-(yd1-yd2)*(yt0-yt2))/K;
	E=((xt0-xt2)*(yd1-yd2)-(yd0-yd2)*(xt1-xt2))/K;
	F=(yt0*(xt2*yd1-xt1*yd2)+yt1*(xt0*yd2-xt2*yd0)+yt2*(xt1*yd0-xt0*yd1))/K;
}

//資料的矯正
void Tc_Correct(float xt,float yt)
{
    X=(U32)(A*xt+B*yt+C);
	Y=(U32)(D*xt+E*yt+F);
}

//觸控式螢幕矯正函式
void Tc_calibrate(void)
{
#if LCD_CALIBRATE==1

    CLK_init();
	LCD_POWER();
    LCD_IO_init();
    LCD_init();
    LCD_on();
	Touch_Init();
	
    LCD_clear(BLACK);//全屏顯示黑色

	//位置1
	Draw_X(160,40,WHITE);
	YdataClear;
	XdataClear;
	while(1)
	{	
		Touch_GetAdXY(&x0,&y0);//讀取座標位置
		if((252<y0)&&(y0<256))//按鍵按下
		{
			Draw_X(160,40,BLACK);
			break;
		}
	}
	
	//位置2
	Draw_X(40,180,WHITE);
	YdataClear;
	XdataClear;
	while(1)
	{
		Touch_GetAdXY(&x1,&y1);//讀取座標位置
		if((702<y1)&&(y1<706))//按鍵按下
		{
		Draw_X(40,180,BLACK);
			break;
		}
	}
	
	//位置3
	Draw_X(260,200,WHITE);
	YdataClear;
	XdataClear;
	while(1)
	{
		Touch_GetAdXY(&x2,&y2);//讀取座標位置
		if((762<y2)&&(y2<764))//按鍵按下
		{
		Draw_X(260,200,BLACK);
			break;
		}
	}
	
	Calculate_P(x0,y0,x1,y1,x2,y2);
	
#endif
		if(inte)
		{
		Touch_GetAdXY(&xt,&yt);//讀取座標位置
		Tc_Correct(xt,yt);
		Uart_Printf("X=%4d, Y=%4d\n",X,Y);
		inte=0;
		}

}

注:字型檔檔案"Font_libs.h",和圖片的取模讀者自行製作.每個部分為獨立C檔案.


用到的介面圖片如下: