基于mini2440简易计算器使用的是数组实现,并非逆波兰式,因此功能不够强大,仅供驱动学习,以及C语言基础编程学习之用.有时间读者可以用逆波兰式来实现强大功能计算器,原理也很简单,建议读《c程序设计第二版》里面有算法的代码.读者自行研究.此程序基于电子相册的改进,触摸屏,LCD,字符现实,数字输入等等
mini2440 索尼X35 LCD液晶屏
主函数部分:
- #include "def.h"
- #include "option.h"
- #include "2440addr.h"
- #include "profile.h"
- #include "mmu.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, 240,320, gImage); //显示计算器界面 240×320屏
- while(1)
- {
- Tc_calibrate();
- input();
- }
- }
计算器的输入及其计算部分,结合触摸屏,利用数组实现字符和数字的存储等:
pasting
- #include "def.h"
- #include "2440addr.h"
- #define touch_p (X>0&&X<42&&Y>0&&Y<80) //定义触摸屏按键区域
- #define touch_0 (X>0&&X<42&&Y>80&&Y<160)
- #define touch_e (X>0&&X<42&&Y>160&&Y<240)
- #define touch_a (X>0&&X<42&&Y>240&&Y<320)
- #define touch_1 (X>42&&X<84&&Y>0&&Y<80)
- #define touch_2 (X>42&&X<84&&Y>80&&Y<160)
- #define touch_3 (X>42&&X<84&&Y>160&&Y<240)
- #define touch_s (X>42&&X<84&&Y>240&&Y<320)
- #define touch_4 (X>84&&X<126&&Y>0&&Y<80)
- #define touch_5 (X>84&&X<126&&Y>80&&Y<160)
- #define touch_6 (X>84&&X<126&&Y>160&&Y<240)
- #define touch_m (X>84&&X<126&&Y>240&&Y<320)
- #define touch_7 (X>126&&X<168&&Y>0&&Y<80)
- #define touch_8 (X>126&&X<168&&Y>80&&Y<160)
- #define touch_9 (X>126&&X<168&&Y>160&&Y<240)
- #define touch_d (X>126&&X<168&&Y>240&&Y<320)
- #define touch_c (X>168&&X<196&&Y>240&&Y<320)
- #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'; //用于屏幕显示图像 0
- num1[i]=0; //用于计算
- i++;
- n1++;
- Draw_REC(0,80,42,160,white);
- B_on; //按下'0'键,蜂鸣器响一声
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_1)
- {
- num[i]='1';
- num1[i]=1;
- i++;
- n1++;
- Uart_Printf("n1=%4d ",n1);
- Draw_REC(42,0,84,80,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_2)
- {
- num[i]='2';
- num1[i]=2;
- i++;
- n1++;
- Draw_REC(42,80,84,160,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_3)
- {
- num[i]='3';
- num1[i]=3;
- i++;
- n1++;
- Draw_REC(42,160,84,240,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_4)
- {
- num[i]='4';
- num1[i]=4;
- i++;
- n1++;
- Draw_REC(84,0,126,80,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_5)
- {
- num[i]='5';
- num1[i]=5;
- i++;
- n1++;
- Draw_REC(84,80,126,160,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_6)
- {
- num[i]='6';
- num1[i]=6;
- i++;
- n1++;
- Draw_REC(84,160,126,240,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_7)
- {
- num[i]='7';
- num1[i]=7;
- i++;
- n1++;
- Draw_REC(126,0,168,80,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_8)
- {
- num[i]='8';
- num1[i]=8;
- i++;
- n1++;
- Draw_REC(126,80,168,160,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_9)
- {
- num[i]='9';
- num1[i]=9;
- i++;
- n1++;
- Draw_REC(126,160,168,240,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- }
- else //加减乘除,以及第二个运算数字
- {
- if(touch_0)
- {
- num[i]='0';
- num2[j]=0;
- i++;
- j++;
- n2++;
- Draw_REC(0,80,42,160,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_1)
- {
- num[i]='1';
- num2[j]=1;
- i++;
- j++;
- n2++;
- Draw_REC(42,0,84,80,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_2)
- {
- num[i]='2';
- num2[j]=2;
- i++;
- j++;
- n2++;
- Draw_REC(42,80,84,160,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_3)
- {
- num[i]='3';
- num2[j]=3;
- i++;
- j++;
- n2++;
- Draw_REC(42,160,84,240,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_4)
- {
- num[i]='4';
- num2[j]=4;
- i++;
- j++;
- n2++;
- Draw_REC(84,0,126,80,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_5)
- {
- num[i]='5';
- num2[j]=5;
- i++;
- j++;
- n2++;
- Draw_REC(84,80,126,160,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_6)
- {
- num[i]='6';
- num2[j]=6;
- i++;
- j++;
- n2++;
- Draw_REC(84,160,126,240,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_7)
- {
- num[i]='7';
- num2[j]=7;
- i++;
- j++;
- n2++;
- Draw_REC(126,0,168,80,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_8)
- {
- num[i]='8';
- num2[j]=8;
- i++;
- j++;
- n2++;
- Draw_REC(126,80,168,160,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(126,80,168,160,gImage);
- }
- else if(touch_9)
- {
- num[i]='9';
- num2[j]=9;
- i++;
- j++;
- n2++;
- Draw_REC(126,160,168,240,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- }
- if(touch_p)
- {
- op='.';
- num[i]='.';
- i++;
- Draw_REC(0,0,42,80,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_e)
- {
- opf='=';
- //num[i]='=';
- //i++;
- Draw_REC(0,160,42,240,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_a)
- {
- op='+';
- num[i]='+';
- i++;
- Draw_REC(0,240,42,320,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);;
- }
- else if(touch_s)
- {
- op='-';
- num[i]='-';
- i++;
- Draw_REC(42,240,84,320,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_m)
- {
- op='*';
- num[i]='*';
- i++;
- Draw_REC(84,240,126,320,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_d)
- {
- op='/';
- num[i]='/';
- i++;
- Draw_REC(126,240,168,320,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,gImage);
- }
- else if(touch_c)
- {
- Draw_REC(168,240,196,320,white);
- B_on;
- delay(1000);
- B_off;
- BMP_display(0,0,240,320,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(210,2,num); //在LCD屏幕上显示算式
- X=0;
- Y=0;
- if(opf=='=') //如果按下等号
- {
- Calc(&Num1,&Num2,&F1); //进行运算
- num[i]='='; //在屏幕显示等号
- F2=F1;
- while(F2>0)
- {
- t[a++]=F2%10; //把答案中个各位数字提取出来,放到数组中
- F2=F2/10;
- len++;
- }
- len1=len;
- a=0;
- while(len1--)
- {
- n[len1]=t[a++]; //答案中各位转移到数组n中
- }
- 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(210,2,num); //在屏幕上显示运算后的算式与答案
- Uart_Printf("Num1=%4d, Num2=%4d,F1=%4d ",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 240 //屏幕宽度
- #define LCD_HEIGHT 320 //屏幕高度
- #define CLKVAL 8 //时钟信号 索尼X35 LCD屏
- //垂直同步信号的脉宽、后肩和前肩
- #define VSPW (9-1)
- #define VBPD (2-1)
- #define VFPD (5-1)
- //水平同步信号的脉宽、后肩和前肩
- #define HSPW (5-1)
- #define HBPD (26-1)
- #define HFPD (1-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 |= (92<<12)|(1<<4)|1; //初始化FCLK为400M
- rCLKDIVN = (2<<1)|1; //HCLK = FCLK/4 = 100M, PCLK = HCLK/2 = 50M
- FCLK = 400000000; //400MHz
- HCLK = 100000000; //100MHz
- PCLK = 50000000; //50MHz
- UCLK = 48000000; //48MHz
- rGPHCON = 0xa0; //TXD[0]端口输出 RXD[0]端口接收
- rGPHUP = 0x7ff; //禁止上拉电阻
- Uart_Init(0,115200);
- Uart_Select(0);
- }
- /**********************************
- *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);
- rLCDCON2 = (VBPD<<24) | (LINEVAL<<14) | (VFPD<<6) | (VSPW);
- rLCDCON3 = (HBPD<<19) | (HOZVAL<<8) | (HFPD);
- rLCDCON4 = HSPW;
- rLCDCON5 = (1<<11) | (1<<9) | (1<<8) | (1<<6) | (1<<3)|(0<<1)|(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 240 //屏幕宽度
- #define LCD_HEIGHT 320 //屏幕高度
- //定义显示缓存,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[])
- { //ch[]为16个元素中,第一个元素的地址
- unsigned short int i,j;
- unsigned char mask,buffer;
- for(i=0;i<16;i++) //__ASCII中连续16个元素组成一个字符图像
- {
- mask=0x80;
- buffer=ch[i]; //16个元素其中的一个
- for(j=0;j<8;j++) //每一个元素占8位
- {
- if(buffer&mask)
- {
- PutPixel(x-i,y+j,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]!=' ')
- {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,y+j,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;
- }
- }
- }
- void Draw_X(int x,int y,U32 color)
- {
- Draw_Line(x-20,y,x+20,y,color);
- Draw_Line(x,y-20,x,y+20,color);
- }
触摸屏的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(" Xdata=%04d, Ydata=%04d ", 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 K = -281780, A = -0.293846, B = 0.000568, C = 271.255585, D = 0.007808, E = 0.400951, F = -54.646889;
- //读取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 ",X,Y);
- inte=0;
- }
- }
Font_libs.h http://download.csdn.net/detail/lc123yx/8322405