/************************************************************制作人:火柴2011-07-14************************************************************************************************************************计算器+-×/使用说明:4×4矩阵键盘+数码管P0:矩阵键盘p1:位选P2:段选矩阵键盘示意图如下:123+456-789×清屏0=/************************************************************/#includereg52.h#includeintrins.h#defineuintunsignedint#defineucharunsignedchar/************************************************************查表************************************************************/ucharcodelab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x80,0x00,0x76,0x3e};//点暗HUucharbuffer[4];//={}ucharbufferx[4],buffery[4];uintx,y,z;/************************************************************延时函数************************************************************/voiddelay(uintz)//延时{uintx,y;for(x=z;x0;x--)for(y=110;y0;y--);}/************************************************************************************************************************/voidsavex(){uinti;for(i=0;i4;i++){if(buffer[i]==0x11)bufferx[i]=0;elsebufferx[i]=buffer[i];}}/************************************************************************************************************************/voidsavey(){uinti;for(i=0;i4;i++){if(buffer[i]==0x11)buffery[i]=0;elsebuffery[i]=buffer[i];}}/************************************************************清零函数0x11-十进制17,lab[17]=0x00数码管暗,无显示************************************************************/voidclr(){uinti;for(i=0;i4;i++){buffer[i]=0x11;//}}/************************************************************显示函数************************************************************/voiddisplay()//显示程序{uchari,temp;temp=0xef;for(i=4;i0;i--){P2=lab[buffer[i-1]];P1=temp;temp=(temp1)|0x01;delay(3);}}/************************************************************是否有键按下?************************************************************/ucharkeysearch(){uchark;P0=0xf0;k=P0;k=~k;k=k&0xf0;returnk;//k=0x10,0x20,0x40,0x80列}/************************************************************************************************************************/voiddigitin(ucharval)//移动{inti;for(i=3;i0;i--)buffer[i]=buffer[i-1];buffer[0]=val;}/************************************************************按键函数************************************************************/ucharkeys(){uchara,c,kr,keynumb;a=keysearch();if(a==0)//按键检测return0xff;elsedisplay();//延时消抖a=keysearch();if(a==0)//再次检测return0xff;else{a=0xfe;for(kr=0;kr4;kr++){P0=a;c=P0;//得到键值如下:if((c&0x10)==0)keynumb=kr+0x00;//048cif((c&0x20)==0)keynumb=kr+0x04;//159dif((c&0x40)==0)keynumb=kr+0x08;//26aeif((c&0x80)==0)keynumb=kr+0x0c;//37bfa=_crol_(a,1);}}do{a=keysearch();display();}while(a!=0);//等待按键释放returnkeynumb;//0~f}/************************************************************按键处理函数************************************************************/voidkeybranch(uchark)//k为返回的键值keynumb{uchari,j,flag_add,flag_dec,flag_che,flag_chu;switch(k){case0x00:digitin(1);break;//048ccase0x04:digitin(2);break;//159dcase0x08:digitin(3);break;//26aecase0x01:digitin(4);break;//37bfcase0x05:digitin(5);break;//case0x09:digitin(6);break;//数码管显示case0x02:digitin(7);break;//123+case0x06:digitin(8);break;//456-case0x0a:digitin(9);break;//789×case0x07:digitin(0);break;//0=/case0x0c:savex();//加号键clr();flag_add=1;digitin(0x0a);digitin(0x0d);digitin(0x0d);for(i=0;i100;i++)display();clr();break;case0x0d:savex();//减号键clr();digitin(0x0d);digitin(0x0e);digitin(0x0c);flag_dec=1;for(i=0;i100;i++)display();clr();break;case0x0e:savex();//乘号键clr();digitin(0x0);digitin(0x12);//对应十进制18,对应显示Hdigitin(0x0e);flag_che=1;for(i=0;i100;i++)display();clr();break;case0x0f:savex();//chu号键clr();digitin(0x0c);digitin(0x012);digitin(0x13);flag_chu=1;for(i=0;i100;i++)display();clr();break;case0x03:clr();//清零键savex();savey();break;case0x0b:savey();//等号键if(flag_add==1){x=bufferx[3]*1000+bufferx[2]*100+bufferx[1]*10+bufferx[0];//构造被加数y=buffery[3]*1000+buffery[2]*100+buffery[1]*10+buffery[0];//构造加数z=x+y;}if(flag_dec==1){x=bufferx[3]*1000+bufferx[2]*100+bufferx[1]*10+bufferx[0];//构造被减数y=buffery[3]*1000+buffery[2]*100+buffery[1]*10+buffery[0];//构造减数z=x-y;}if(flag_che==1){x=bufferx[3]*1000+bufferx[2]*100+bufferx[1]*10+bufferx[0];//构造被乘数y=buffery[3]*1000+buffery[2]*100+buffery[1]*10+buffery[0];//构造乘数z=x*y;}if(flag_chu==1){x=bufferx[3]*1000+bufferx[2]*100+bufferx[1]*10+bufferx[0];//构造被除数y=buffery[3]*1000+buffery[2]*100+buffery[1]*10+buffery[0];//构造除数z=x/y;//}buffer[3]=z/1000;buffer[2]=z%1000/100;buffer[1]=z%100/10;buffer[0]=z%10;for(i=0;i4;i++)//j的初值为0{if(buffer[i]!=0)j=i+1;if(j==0)j=1;//处理缓冲区,使数码管显示最高位非零}for(;j4;j++)//最高位零不显示buffer[j]=0x11;//buffer[0x11]对应的显示值是空屏break;default:break;}}/************************************************************主函数************************************************************/voidmain(){uchark;clr();while(1){k=keys();//检测有键按下,松手后显示相应的键值keynumb;if(k!=0xff)//无键按下返回0xff,有键按下返回其他keynumb值keybranch(k);//根据相应的键值改变显示缓冲区的值do{k=keysearch();display();//显示改变后缓冲区的值}whil