基于mini2440简单计算器的实现(裸机代码)
2012-11-28 11:55
330 查看
基于mini2440简易计算器使用的是数组实现,并非逆波兰式,因此功能不够强大,仅供驱动学习,以及C语言基础编程学习之用.有时间读者可以用逆波兰式来实现强大功能计算器,原理也很简单,建议读《c程序设计第二版》里面有算法的代码.读者自行研究.此程序基于电子相册的改进,触摸屏,LCD,字符现实,数字输入等等.
主函数部分:
[b]LCD驱动部分:
GUI部分,字符,图片处理函数等:
触摸屏的ADC驱动部分:
触摸屏矫正及其计算部分(三点矫正):
注:字库文件"Font_libs.h",和图片的取模读者自行制作.每个部分为独立C文件.
用到的界面图片如下:
主函数部分:
#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文件.
用到的界面图片如下:
相关文章推荐
- 基于mini2440流水灯(裸机代码)
- 基于mini2440轮询控制LED(裸机代码)
- 基于mini2440按键控制电子相册(裸机代码)
- 基于mini2440触摸屏版电子相册(裸机代码)
- 基于mini2440的按键中断控制LED(裸机代码)
- 基于内容的图像检索(颜色,直方图相交法,)java实现代码
- 基于jQuery的输入框无值自动显示指定数据的实现代码
- cnblogs TagCloud基于jquery的实现代码
- java基于jedisLock―redis分布式锁实现示例代码
- 基于jQuery实现滚动新闻代码下载
- 基于python的汉字转GBK码实现代码
- [技术学习]基于MSXML实现DOM操作的VC++代码
- JAVA实现基于可视化的代码,可以实现商品总计,很方便。
- 基于C++实现的线程休眠代码
- 基于php&mysql实现聊天室功能的代码实例分享
- 一个基于python3+PyQt5实现的简单计算器程序
- 基于jquery的一行代码轻松实现拖动效果
- 基于Python实现的扫雷游戏实例代码
- SRGAN基于keras实现代码框架