×
单片机 > 单片机程序设计 > 详情

基于51单片机六位整数计算器源程序

发布时间:2020-09-01 发布时间:
|
#include

#define uint unsigned int
#define uchar unsigned char
sbit beep=P2^3;        //beep用于控制蜂鸣器(每按一次键就为0并且叫一下)
sbit dula=P2^6;        //dula通过控制锁存器1来控制数码管段选
sbit wela=P2^7;        //wela通过控制锁存器2来控制数码管位选
uchar code table[]={     //数码管的显示编码
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x79};
uchar fuhao=0,scan=0;     //全局变量fuhao用来存放运算符的值   scan作为是否按键的标志位(按下就为1没按为0)
void delay(uint z);       //延时Z毫秒
void display(long n);    //用六位数码管显示long值
uchar keyscan();         //键盘扫描并把扫描得到的值返回    
void displayerror();     //显示错误操作提示信息

void main()
{
 uchar val=0,j=0,i=0,jie,e=0;  //i,j用于判断每次输入的数是否超过六位,e为错误操作标志位(为1表示已错误操作),jie为显示计算结果标志位(为1表示要显示结果)
 long a=0,b=0,c=0;      //a存放第一次输入的数,b存放第二次输入的数,c存放计算的结果
 display(0);           //初始化显示
 delay(1000);         //延时1000毫秒
 while(1)
 {
  beep=1;             //关闭蜂鸣器
  val=keyscan();     //把扫描得到的值赋给val
  if(scan==1)        //一旦按下键我就对其操作
  {
   scan=0;         //把按键标志位scan复位
   if(val==10)     //如果按下的为复位键
   {
    a=0;b=0;c=0;fuhao=0;jie=0;e=0;i=0;j=0;display(0);

   //复位操作(初始化)  (显示是不能停)
    continue;           //直接进入下一次循环
   }
   else if(val>=11&&val<=15&&i==0&&fuhao==0)//如果第一次按下的不是数字键
   {
    display(0);        //数码管显示不能停
    continue;        //直接进入下一次循环
   }
  
   else if(val>=12&&val<=15&&fuhao==0&&i!=0)//输入数字之后按下的第一个运算符
   {
    fuhao=val;        //把扫描得到运算符值赋给fuhao标志位
    i=0;             //一旦输入运算符就把数字输入计数i清零
    display(0);       //数码管显示不能停
   }
   else if(fuhao!=0&&val>=11&&val<=15)   //只要按下等于或者运算符之前按了数字键和运算符就显示计算结果
   {
    jie=1;            //计算结果标志位jie为1(表示要显示计算结果c)
    if(fuhao==12)      //如果输入的是运算符‘+’
    {
     c=a+b;          //把运算的结果赋给c
     if(c>999999)     //如果计算结果超出数码管的显示范围
     {
      displayerror();     //显示出错信息
      e=1;             //出错信息标志位置1
     }
     else        
     {
      display(c);     //不超出显示范围就显示结果
     }
    }
    else if(fuhao==13)     //如果输入的运算符是‘-’
    {
     if(a       
      displayerror();
     }
     else
     {
      c=a-b;
      display(c);
     }
    }
    else if(fuhao==14)       //如果输入的运算符是‘*’
    {
     c=a*b;
     if(c>999999)
     {
      displayerror();
      e=1;
     }
     else
     {
      display(c);
     }
    }
    else          //如果输入的运算符是‘/’
    {
     c=a/b;
     display(c);
    }
   }
   else if(val>=0&&val<=9)     //如果按下的为数字键
   {
    if(fuhao==0)      //如果是第一次按下数字键
    {
     a=a*10+val;      //把前面显示的值左移一位再加当前输入的数字存放到a(0到9)
     i++;       //每输入一个数字,数字计数i加1
     if(i>6)          //如果连续输入数字超过六位
     {
      displayerror();e=1;   //显示出错信息且错误标志位置1
     }
     else
     {
      display(a);     //显示得到的a
      continue;     //进入下次次循环
     }
    }
    else            //第二次按下数字键
    {
      b=b*10+val;      //把前面显示的值左移一位再加当前输入的数字存放到b(0到9)
      j++;       //第二次输入数字的计算变量j加1
      if(j>6)         //如果输入超出数码管显示范围
      {
       displayerror(); e=1;
      }
      else
      {
       display(b);
       continue;
      }
    
   }
  
  }
  else           //如果没按下键(也要显示)
  {
   if(e==1)      displayerror();//如果出错标志位为1就显示出错信息
   else if(fuhao==0)         display(a);  //如果还没输入运算符(到目前为止还只是输入数字)就显示a  
   else if(fuhao!=0&&jie==0) display(b);  //如果输入数字后又输了运算符且没输入运算符和等于就显示b
   else if(jie==1)           display(c);  //如果输入了结果标志位就显示计算结果c
   else                      display(0);  //其余就初始化显示
  }
  
 }
}

void delay(uint z)        
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}


uchar keyscan()                     
{
 uchar num,temp1,temp2,temp;  //num用于存放扫描到得按键值
 P3=0x0f;                     //给P3口低四位赋0高四位赋1
 temp1=P3;      //读取P3口的值
 if(temp1!=0x0f)     //如果P3口发生变化
 {
  delay(10);    //延时消斗
  temp1=P3;    //再次读取P3口的值
  if(temp1!=0x0f)   //如果确实有按键按下
  {
   P3=0xf0;   //再给P3口高四位赋1低四位赋0
   temp2=P3;   //读取P3口的值
   temp=temp1|temp2; //把两次读取的值或运算赋给temp
   switch(temp)  //判断temp按下的是哪个键再对num赋值
   {
    case 0xee:num=0;
     break;
    case 0xde:num=1;
     break;
    case 0xbe:num=2;
     break;
    case 0x7e:num=3;
     break;
    case 0xed:num=4;
     break;
    case 0xdd:num=5;
     break;
    case 0xbd:num=6;
     break;
    case 0x7d:num=7;
     break;
    case 0xeb:num=8;
     break; 
    case 0xdb:num=9;
     break;
    case 0xbb:num=10;
     break;
    case 0x7b:num=11;
     break;
    case 0xe7:num=12;
     break;
    case 0xd7:num=13;
     break;
    case 0xb7:num=14;
     break;
    case 0x77:num=15;break;
    default : num=16;break;
   
   while(temp2!=0xf0)     //松手检测
   {
     temp2=P3;
   }
   beep=0;       //每扫描到一个num蜂鸣器就叫一下
   scan=1;       //已按下键
  }
 }
 return num;           //返回扫描得到的值
}

void displayerror()    //最高位显示E表示出错信息
{
 dula=1;
 P0=table[10];
 dula=0;
 P0=0xff;
 wela=1;
 P0=0xdf;
 wela=0;
 delay(1);
 wela=1;
 P0=0xff;
 wela=0;
}

void display(long n)  

 uchar j=0;
 long quan=1;
 if(n==0)    //如果n为0则初始化显示(最高位显示0)
 {
  wela=1;
  P0=0xdf;
  wela=0;
  dula=1;
  P0=table[0];
  dula=0;
  P0=0xff;
  delay(1);
  wela=1;
  P0=0xff;     //把数码管全关掉(用于消掉余辉)
  wela=0;
 }
 else
 {
  while(n/quan!=0)     //用于判断long为几位
  {
   quan=quan*10;
   j++;       // j用于存放long的位数
  }
  if(j==1)       //如果long为一位
  
   wela=1;
   P0=0xdf;
   wela=0;
   dula=1;
   P0=table[n];
   dula=0; 
   P0=0xff;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  }
  else if(j==2)
  {
   dula=1;
   P0=table[n/10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xef;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  
   dula=1;
   P0=table[n%10];
   dula=0;
   P0=0xff;
   wela=1;
   P0=0xdf;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  }
  else if(j==3)
  {
   dula=1;
   P0=table[n/100];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xf7;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/10)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xef;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  
   dula=1;
   P0=table[n%10];
   dula=0;
   P0=0xff;
   wela=1;
   P0=0xdf;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  }
  else if(j==4)
  {
   dula=1;
   P0=table[n/1000];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xfb;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/100)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xf7;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/10)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xef;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  
   dula=1;
   P0=table[n%10];
   dula=0;
   P0=0xff;
   wela=1;
   P0=0xdf;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  }
  else if(j==5)
  {
   dula=1;
   P0=table[n/10000];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xfd;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/1000)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xfb;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/100)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xf7;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/10)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xef;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  
   dula=1;
   P0=table[n%10];
   dula=0;
   P0=0xff;
   wela=1;
   P0=0xdf;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  }
  else
  {
   dula=1;
   P0=table[(n/100000)];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xfe;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/10000)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xfd;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/1000)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xfb;
   wela=0;
   delay(1);
 
   dula=1;
   P0=table[(n/100)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xf7;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
 
   dula=1;
   P0=table[(n/10)%10];
   dula=0; 
   P0=0xff;
   wela=1;
   P0=0xef;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  
   dula=1;
   P0=table[n%10];
   dula=0;
   P0=0xff;
   wela=1;
   P0=0xdf;
   wela=0;
   delay(1);
   wela=1;
   P0=0xff;
   wela=0;
  }
 }
}

关键字:51单片机  六位整数  计算器 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR熔丝位操作时的要点和需要注意的相关事项