51单片机数码管计算器(代码详解)

/******************************************************************
							按键说明
				S6--S15  数字0--9的输入		S16	清零
				S17	等于			S18--S21加减乘除
程序功能:	本程序为简易计算器。可以算整数且正数类型的运算。
			但是暂时没有实现其连算功能,故在每次运算之后,请按下清零键。
******************************************************************/
#include<reg52.h>

#define uchar unsigned char

uchar a0=16,b0=16,c0=16,d0=16,e0=16,f0=16,wei,temp,key,i,j,k;
uchar jia,jian,cheng,chu,dengyu,jia0,jian0,cheng0,chu0,qingling;
uchar s0,s1,s2,s3,s4,s5; //参加运算的各个位
unsigned long qian,hou;//定义参于运算的第一个数和第二个数。
sbit dula=P2^6;//数码管段选(段选锁存器)
sbit wela=P2^7;//数码管位选(位选锁存器)
sbit beep=P2^3;//蜂鸣器

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//数码管0~9

void delay(uchar i)//延时函数
{
	for(j=i;j>0;j--)
	for(k=125;k>0;k--);
}

/*------------------------------------
函数功能:数码管显示函数
参数说明:a,b,c,d,e,f都是传入数码管要显示的数据,即段选数据
         通过定义的数组table传入
-------------------------------------*/

void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
{
   
   dula=0;
   P0=table[a];
   dula=1;
   dula=0;

   wela=0;
   P0=0xfe;
   wela=1;
   wela=0;
   delay(5);
   
   P0=table[b];
   dula=1;
   dula=0;
 
   P0=0xfd;
   wela=1;
   wela=0;
   delay(5);

   P0=table[c];
   dula=1;
   dula=0;
 
   P0=0xfb;
   wela=1;
   wela=0;
   delay(5);
   
   P0=table[d];
   dula=1;
   dula=0;

   P0=0xf7;
   wela=1;
   wela=0;
   delay(5);
   
   P0=table[e];
   dula=1;
   dula=0;

   P0=0xef;
   wela=1;
   wela=0;
   delay(5);
   
   P0=table[f];
   dula=1;
   dula=0;
   
   P0=0xdf;
   wela=1;
   wela=0;
   delay(5);
}


/*--------------------------------
函数功能:按键控制函数,通过按键来实现数据的输入,
         及举矩阵键盘的扫描函数
---------------------------------*/

void keyscan()
{
  {	
    P3=0xfe;
    temp=P3;
    temp=temp&0xf0;
    if(temp!=0xf0)
    {
      delay(10);
      if(temp!=0xf0)
      {	
        temp=P3;
        switch(temp)
        {
          case 0xee:
               key=0;
			   wei++;
               break;

          case 0xde:
               key=1;
			   wei++;
               break;

          case 0xbe:
               key=2;
			   wei++;
               break;

          case 0x7e:
               key=3;
			   wei++;
               break;
         }
         while(temp!=0xf0) 
        {
           temp=P3;
           temp=temp&0xf0;
           beep=0;
         }
         beep=1;
      }
    }
    P3=0xfd;
    temp=P3;
    temp=temp&0xf0;
    if(temp!=0xf0)
    {
      delay(10);
      if(temp!=0xf0)
      {
        temp=P3;
        switch(temp)
        {
          case 0xed:
               key=4;
			   wei++;
               break;

          case 0xdd:
               key=5;
			   wei++;
               break;

          case 0xbd:
               key=6;
			   wei++;
               break;

          case 0x7d:
               key=7;
			   wei++;
               break;
         }
         while(temp!=0xf0)
         {
           temp=P3;
           temp=temp&0xf0;
           beep=0;
         }
         beep=1;
      }
      }
    P3=0xfb;
    temp=P3;
    temp=temp&0xf0;
    if(temp!=0xf0)
    {
      delay(10);
      if(temp!=0xf0)
      {
        temp=P3;
        switch(temp)
        {
          case 0xeb:
               key=8;
			   wei++;
               break;

          case 0xdb:
               key=9;
			   wei++;
               break;
			   
          case 0xbb:
               qingling=1;
			   //key=10;
			   //wei++;
               break;

          case 0x7b:
               dengyu=1;
			   //key=11;
			   //wei++;
               break;
         }
        while(temp!=0xf0)
         {
           temp=P3;
           temp=temp&0xf0;
           beep=0;
         }
         beep=1;
      }
      }
	      P3=0xf7;
    temp=P3;
    temp=temp&0xf0;
    if(temp!=0xf0)
    {
      delay(10);
      if(temp!=0xf0)
      {
        temp=P3;
        switch(temp)
        {
          case 0xe7:
		  	   jia=1; 
               //key=12;
			  // wei++;
               break;

          case 0xd7:
               jian=1;
               break;

          case 0xb7:
               cheng=1;     //乘运算
               break;

          case 0x77:
               chu=1;       //除运算
               break;
         }
         while(temp!=0xf0)
         {
           temp=P3;
           temp=temp&0xf0;
           beep=0;
         }
         beep=1;
      }
    }
}
}


/*-----------------------------------
函数功能:显示函数
控制数码管希纳是的位数,以及运算过程中按键的命令
------------------------------------*/
void display0()
{
	if(key!=20)
	{
	switch(wei)
		{
			case 1: a0=key;
					b0=16;
					c0=16;
					d0=16;
					e0=16;
					f0=16;
					break;
			case 2: b0=key;
					c0=16;
					d0=16;
					e0=16;
					f0=16;
					break;
			case 3: c0=key;
					d0=16;
					e0=16;
					f0=16;
					break;
			case 4: d0=key;
					e0=16;
					f0=16;
					break;
			case 5: e0=key;
					f0=16; 
					break;
			case 6: f0=key;
					//wei=0;
					break;
	}
	key=20;
	}
	display(a0,b0,c0,d0,e0,f0);//调用起初定义的数码管显示函数
	if(a0!=16) s5=a0;
	if(b0!=16) s4=b0;
	if(c0!=16) s3=c0;
	if(d0!=16) s2=d0;
	if(e0!=16) s1=e0;
	if(f0!=16) s0=f0;
}


/*-------------------------------------
函数功能:主函数
--------------------------------------*/
void main()
{	uchar gongneng,yunsuan;
  	while(1)
	{
	  	keyscan();
		gongneng=jia|jian|cheng|chu|dengyu|qingling;//判断执行的功能键,加减乘除
		if(gongneng==0)
		{
			display0();	//调用功能显示函数
		}

/*------------------------------
下面的代码是一些运算的处理,读者可
以自行理解
------------------------------*/
		else
		{  	yunsuan=jia|jian|cheng|chu;
			if(yunsuan)
			{	
	
				a0=16;
				b0=16;
				c0=16;
				d0=16;
				e0=16;
				f0=16;
				//wei=0;
				if(jia)
				{jia=0;	jia0=1;jian0=0;cheng0=0;chu0=0;}
				if(jian)
				{jian=0;jia0=0;jian0=1;cheng0=0;chu0=0;}
				if(cheng)
				{cheng=0;jia0=0;jian0=0;cheng0=1;chu0=0;}
				if(chu)
				{chu=0;	jia0=0;jian0=0;cheng0=0;chu0=1;}
				switch(wei)
				{
					case 6:
					qian=s5*100000+s4*10000+s3*1000+s2*100+s1*10+s0;break;
					case 5:
					qian=s5*10000+s4*1000+s3*100+s2*10+s1;break;
					case 4:
					qian=s5*1000+s4*100+s3*10+s2;break;
					case 3:
					qian=s5*100+s4*10+s3;break;
					case 2:
					qian=s5*10+s4;break;
					case 1:
					qian=s5;break;
				}
				wei=0;
				s0=0;s1=0;s2=0;s3=0;s4=0;s5=0;
				display(a0,b0,c0,d0,e0,f0);
				//P1=0x55;
			}
			if(dengyu)//等于键
			{
				 dengyu=0;
				 //display(16,16,16,16,16,16);
				 switch(wei)
				{
					case 6:
					hou=s5*100000+s4*10000+s3*1000+s2*100+s1*10+s0;break;
					case 5:
					hou=s5*10000+s4*1000+s3*100+s2*10+s1;break;
					case 4:
					hou=s5*1000+s4*100+s3*10+s2;break;
					case 3:
					hou=s5*100+s4*10+s3;break;
					case 2:
					hou=s5*10+s4;break;
					case 1:
					hou=s5;break;
				}
				wei=0;
				s0=0;s1=0;s2=0;s3=0;s4=0;s5=0;
				 if(jia0)
				 {jia0=0;	hou=qian+hou;}
				 if(jian0)
				 {jian0=0;	hou=qian-hou;}
				 if(cheng0)
				 {cheng0=0;	hou=qian*hou;}
				 if(chu0)
				 {chu0=0;	hou=qian/hou;}
				 if(hou<10)
				 {
				 	a0=hou;b0=16;c0=16;d0=16;e0=16;f0=16;
				 }
				 else
				 {
				 	if(hou<100)
					{a0=hou/10;b0=hou%10;c0=16;d0=16;e0=16;f0=16;}
					else
					{
						if(hou<1000)
						{a0=hou/100;b0=hou%100/10;c0=hou%10;d0=16;e0=16;f0=16;}
						else
						{
							if(hou<10000)
							                {a0=hou/1000;b0=hou%1000/100;c0=hou%100/10;d0=hou%10;e0=16;f0=16;}
							else
							{
								if(hou<100000)
								 
                      {a0=hou/10000;b0=hou%10000/1000;c0=hou%1000/100;d0=hou%100/10;e0=hou%10;f0=16;}
								else
								{
									if(hou<1000000)
									{a0=hou/100000;b0=hou%100000/10000;c0=hou%10000/1000;d0=hou%1000/100;e0=hou%100/10;f0=hou%10;}
								}
							}
						}
					}
				 }
				 display(a0,b0,c0,d0,e0,f0);
				 P1=hou;
	
			}
			if(qingling)
			{
				a0=16;b0=16;c0=16;d0=16;e0=16;f0=16;
				s0=0;s1=0;s2=0;s3=0;s4=0;s5=0;
				jia=0;jian=0;cheng=0;chu=0;
				jia0=0;jian0=0;cheng0=0;chu0=0;
				qingling=0;dengyu=0;
				qian=0;hou=0;
				display(a0,b0,c0,d0,e0,f0);
			}
			
		}

	}
}

 

注:此代码已经过运行调试,读者不必怀疑其正确性,如果不能运行,请自行检查IO口配置,以及数码管是否用的是段选位选锁存器。

最后,希望我的分享能带给你启发和收获,敬请关注,一起成长!持续更新中~~~

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小_扫地僧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值