计算器 计算器 计算器 计算器 计算器 计算器

源代码在线查看: jiajian.c

软件大小: 3 K
上传用户: peterzhang1982
关键词: 计算器
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*本人倾力编写的简易计算器程序,可实现八位数的加减乘除功能
				显示和键扫描部分程序是参考他人的著作:磁动力工作室明浩大侠
				写的简易计数器程序,马忠梅等老师写的单片机C程序设计一书
				  *********编写:姜海峰   E-mail:jihafesz@163.com******
				  日期:2004.03.08
				奉献给广大初学者,以做参考,如有疑问欢迎与本人联系共同探讨*/
				//P3口接4×4行列式键盘
				#include 
				#define uchar unsigned char
				#define uint unsigned int
				#define LED P0    //LED输出
				#define LED0 P2_0 //LED控制
				#define LED1 P2_1 //LED控制
				#define LED2 P2_2 //LED控制
				#define LED3 P2_3 //LED控制
				#define LED4 P2_4 //LED控制
				#define LED5 P2_5 //LED控制
				#define LED6 P2_6 //LED控制
				#define LED7 P2_7 //LED控制
				uchar code LEDDis[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};//共阳0-9的LED笔划
				uchar code keynb[]={0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};
				static uchar LEDN[6];
				uchar key,newkey,oldkey; //扫描的键值,新键值,旧键值
				bit valueflag;//键值标值志位,有值则为1,无值为0
				static unsigned long data value,valuefirst,valuesecond;//键值,按符号键之前按键值,按符号键之后按键值
				uchar keycounter,keytemp,symbol;//数字键按下计数器,键值暂存器,符号键值暂存器
				void dlms(void);
				uchar kbscan(void);
				
				    
				void dlms(void)           //延时0.000804s程序
				{
				 uint i;
				 for(i=0;i				}
				
				uchar kbscan(void)            
				    {uchar sccode,recode;
				    P3=0xf0;//发全0行扫描码*,列线输入
				    if((P3&0xf0)!=0xf0)//若有键按下
				        {dlms();//延时去抖动
				        if((P3&0xf0)!=0xf0)
				            {sccode=0xfe;//逐行扫描初值
				            while((sccode&0x10)!=0) //判断是否扫描结束
				                {P3=sccode;//输出行扫描码
				                if((P3&0xf0)!=0xf0)
				                    {recode=((P3&0xf0)|0x0f);
				                    return((~sccode)+(~recode));
				                    }    
				                else sccode=(sccode				                }            
				            }            
				        }
				      return(0x00);  
				    }         
				
				
				
				
				void main(void)
				{
				dlms();
				//初始化变量
				valueflag=0;
				value=valuefirst=valuesecond=0;
				symbol=0;
				EA = 1; //允许CPU中断
				ET0 = 1; //定时器0中断打开
				TMOD = 0x1; //设定时器0为模式1,16位模式
				TH0=0xB1;
				TL0=0xDF; //设定时值为20000us(20ms)
				TR0 = 1; //开始定时
				while(1)
				{
					newkey=key;
					if((oldkey!=newkey)&&(key!=0x00)&&(key!=0x88)&&(key!=0x84)&&(key!=0x81)&&(key!=0x82)&&(key!=0x48)&&(key!=0x44))//按下的是数字键处理
				    {
				     if(symbol!=0&&keycounter==0)
				     value=0;//如果是按了符号之后第一次按下数字键则清零value后重新计算其值
				     valueflag=1;
				     keycounter++;
				     if(keycounter>8)keycounter=0;
				     if(key==keynb[0])keytemp=0;
				     else if(key==keynb[1])keytemp=1;
				     else if(key==keynb[2])keytemp=2;
				     else if(key==keynb[3])keytemp=3;
				     else if(key==keynb[4])keytemp=4;
				     else if(key==keynb[5])keytemp=5;
				     else if(key==keynb[6])keytemp=6;
				     else if(key==keynb[7])keytemp=7;
				     else if(key==keynb[8])keytemp=8;
				     else if(key==keynb[9])keytemp=9;
				     
				     switch(keycounter)
				      {
				     	case 1:value=keytemp;break;
				     	case 2:value=value*10+keytemp;break;
				     	case 3:value=value*10+keytemp;break;
				     	case 4:value=value*10+keytemp;break;
				     	case 5:value=value*10+keytemp;break;
				     	case 6:value=value*10+keytemp;break;
				     	case 7:value=value*10+keytemp;break;
				     	case 8:value=value*10+keytemp;break;
				     	default:break;
				      }
				    
				     }
				     
				 
				   else if(key==0x88&&symbol!=0&&valueflag==0)          //'='号程序
				     {
				     	valuesecond=value;
				     	keycounter=0;
				     	if(symbol=='+')
				     	  {value=valuefirst+valuesecond;
				     	  symbol=0;}
				     	else if(symbol=='-')
				     	  {value=valuefirst-valuesecond;
				     	  symbol=0;}
				     	else if(symbol=='*')
				     	  {value=valuefirst*valuesecond;
				     	  symbol=0;}
				     	else if(symbol=='/')
				     	  {value=valuefirst/valuesecond;
				     	  symbol=0;}
				     }
				   else if(key==0x84)                //'C'号程序
				     {value=0;
				      valueflag=0;
				      keycounter=0;
				      valuefirst=0;
				      valuesecond=0;
				     }
				   else if(key==0x82&&valueflag!=0&&symbol==0)//'/'号程序
				     {
				     	symbol='/';
				     	keycounter=0;
				     	valuefirst=value;
				     	
				     }
				   else if(key==0x81&&valueflag!=0&&symbol==0)//'*'号程序
				     {
				     	symbol='*';
				     	keycounter=0;
				     	valuefirst=value;
				     	
				     }
				   else if(key==0x48&&valueflag!=0&&symbol==0)//'-'号程序
				     {
				     	symbol='-';
				     	keycounter=0;
				     	valuefirst=value;
				     	
				     }
				   else if(key==0x44&&valueflag!=0&&symbol==0)//'+'号程序
				     {
				     	symbol='+';
				     	keycounter=0;
				     	valuefirst=value;
				     	
				     }
				   oldkey=newkey;      
				   /*如果键一直按下,则只算按下一次因为(oldkey一直等于newkey),松开后再按下
				   oldkey就不等于newkey,因此键值会增加一位,因为中断时间只有20ms ,一次按键过
				   程中会产生多次中断,故设置此两变量来判别*********************************/
				   
				/*以下为数码管显示程序*/   
				LEDN[7]=value/10000000;
				LEDN[6] = (value-10000000*(long)LEDN[7])/1000000;
				LEDN[5] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6])/100000;
				LEDN[4] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5])/10000;
				LEDN[3] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4])/1000;
				LEDN[2] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3])/100;
				LEDN[1] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2])/10;
				LEDN[0] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2]-10*(long)LEDN[1]);
				
				if(LEDN[7]==0)              //第7位显示,如有前缀0,则不显示
				{LED=LEDDis[10];
				LED7 = 0;
				dlms();
				LED7 = 1;}
				else
				{LED=LEDDis[LEDN[7]];
				LED7 = 0;
				dlms();
				LED7 = 1;}
				
				if(LEDN[7]==0&&LEDN[6]==0)//第6位显示,如有前缀0,则不显示
				{LED=LEDDis[10];
				LED6 = 0;
				dlms();
				LED6 = 1;}
				else
				{LED=LEDDis[LEDN[6]];
				LED6 = 0;
				dlms();
				LED6 = 1;}
				
				if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0)//第5位显示,如有前缀0,则不显示
				{LED=LEDDis[10];
				LED5 = 0;
				dlms();
				LED5 = 1;}
				else
				{LED=LEDDis[LEDN[5]];
				LED5 = 0;
				dlms();
				LED5 = 1;}
				
				if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0)//第4位显示,如有前缀0,则不显示
				{LED=LEDDis[10];
				LED4 = 0;
				dlms();
				LED4 = 1;}
				else
				{LED=LEDDis[LEDN[4]];
				LED4 = 0;
				dlms();
				LED4 = 1;}
				
				if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0&&LEDN[3]==0)//第3位显示,如有前缀0,则不显示
				{LED=LEDDis[10];
				LED3 = 0;
				dlms();
				LED3 = 1;}
				else
				{LED=LEDDis[LEDN[3]];
				LED3 = 0;
				dlms();
				LED3 = 1;}
				
				if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0&&LEDN[3]==0&&LEDN[2]==0)//第2位显示,如有前缀0,则不显示
				{LED=LEDDis[10];
				LED2 = 0;
				dlms();
				LED2 = 1;}
				else
				{LED=LEDDis[LEDN[2]];
				LED2 = 0;
				dlms();
				LED2 = 1;}
				
				if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0&&LEDN[3]==0&&LEDN[2]==0&&LEDN[1]==0)//第1位显示,如有前缀0,则不显示
				{LED=LEDDis[10];
				LED1 = 0;
				dlms();
				LED1 = 1;}
				else
				{LED=LEDDis[LEDN[1]];
				LED1 = 0;
				dlms();
				LED1 = 1;}
				
				
				LED=LEDDis[LEDN[0]];//第0位显示,如有前缀0,则不显示
				LED0 = 0;
				dlms();
				LED0 = 1;
				  
				}              
				     	     	
				}
				
				//定时器0中断外理中键扫描
				void KeyAndDis_Time0(void) interrupt 1 using 2
				{
				TH0=0xB1;  //重赋初值
				TL0=0xDF; 
				key=kbscan();//调键扫描子程序
				
				}
				
				
				
				
					
					
					
					
				  			

相关资源