您的位置:首页 > 编程语言

基于mini2440简单计算器的实现(裸机代码)

2012-11-28 11:55 330 查看
基于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;//参与
4000
运算两个数
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=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;
}
}

[b]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)

c872
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文件.



用到的界面图片如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  arm C