基于51单片机的简易减法器设计制作

基于C51单片机的简易减法器设计制作

51单片机可实现很多功能,今天笔者介绍一种使用C51编写程序,通过4*4矩阵键盘和8位共阴数码管实现的简易减法器。矩阵键盘以及数码管的原理图如下:

(1)4*4矩阵键盘原理图:

在这里插入图片描述
(2)数码管的原理图:
本文通过动态数码管来实现运算数字的显示
通过3-8译码器实现数码管的动态显示

编程代码如下:

#include <reg52.h> 
#include "math.h"

#define GPIO_KEY P1

typedef unsigned int u16;      
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u8 b[8]={0,0,0,0,0,0,0,0};

u16 l,m,KeyValue,flag;

u8 DisplayData[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};   
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};   //0-9(十六进制)数组 
void delay(u16 i)   //延时函数 
{
	while(i--); 
}

void KeyDown()    //按键函数 
{
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)
	{
		delay(1000);
		if(GPIO_KEY!=0x0f)
	  	{ 
	   		//测试列
	   		GPIO_KEY=0X0f;
			switch(GPIO_KEY)
	   		{
	    		case(0X07): KeyValue=0;break;
	    		case(0X0b): KeyValue=1;break;
	    		case(0X0d): KeyValue=2;break;
	    		case(0X0e): KeyValue=3;break;
	   		}
	   		//测试行
	   		GPIO_KEY=0Xf0;
	   		switch(GPIO_KEY)
	   		{
	    		case(0X70): KeyValue=KeyValue;break;
	    		case(0Xb0): KeyValue=KeyValue+4;break;
	    		case(0Xd0): KeyValue=KeyValue+8;break;
	    		case(0Xe0): KeyValue=KeyValue+12;break;
	   		}
	   }
	   if(KeyValue==0||KeyValue==1||KeyValue==2||KeyValue==3||KeyValue==4||KeyValue==5||KeyValue==6||KeyValue==7||KeyValue==8||KeyValue==9)
	   {
	   		flag=1;
	   }
	   else if(KeyValue==10)    //S11位减号 
	   {
	   		flag=2;
	   }
	   else if(KeyValue==11)   //S12为等于号 
	   {
	   		flag=3;
	   }
	   while(GPIO_KEY!=0Xf0)   //判断按键是否松开 
	   {
	   		delay(5);
	   }
	}		
}

void DigDisplay()   //在数码管上显示 DisplayData里的元素 
{
 	u8 j;
 	for(j=0;j<8;j++)
 	{	
  		switch(j)  
  		{
        	case(7):
				LSA=1;LSB=1;LSC=1;break;//显示第0位
			case(6):
				LSA=0;LSB=1;LSC=1;break;//显示第1位
			case(5):
				LSA=1;LSB=0;LSC=1;break;//显示第2位
			case(4):
				LSA=0;LSB=0;LSC=1;break;//显示第3位
			case(3):
				LSA=1;LSB=1;LSC=0;break;//显示第4位
			case(2):
				LSA=0;LSB=1;LSC=0;break;//显示第5位
			case(1):
				LSA=1;LSB=0;LSC=0;break;//显示第6位
			case(0):
				LSA=0;LSB=0;LSC=0;break;//显示第7位	
  		}
  		P0=DisplayData[j];
  		delay(100);
  		P0=0x00;   //数码管消隐 
 	}
}



void main()
{
	u16 i,d,e,f=0,s,g=0,t,z,y,h,am;
	u16 lm[8]={0};
	while(1)
	{
		DigDisplay();
		KeyDown();
		if(flag==1)
		{
	 		for(i=7;i>0;i--)
			{
				b[i]=b[i-1];
			}
			b[0]=KeyValue;
			
			//减数与被减数判断 
			if(g==0) 
			{
				l=(b[7]*10000000 + b[6]*1000000 + b[5]*100000 + b[4]*10000 + b[3]*1000 + b[2]*100 + b[1]*10 + b[0]);
			}
			else
			{
				m=(b[7]*10000000 + b[6]*1000000 + b[5]*100000 + b[4]*10000 + b[3]*1000 + b[2]*100 + b[1]*10 + b[0]);
			}
			
			//判断输入的数的位数 
			for(e=0;e<8;e++)
			{
				if(b[e]!=0)
				{
					f=e+1;
				}
			}
			
			//由上面得到输入的数的位数,接下来确定哪几个数码管显示 
			for(d=0;d<f;d++)
			{
				DisplayData[d]=smgduan[b[d]]; 
			}
			flag=100;
		}
		
		if(flag==2)   //减号
		{
			for(s=0;s<8;s++)   //b数组和DisplayData数组清零 
			{
				b[s]=0;
				DisplayData[s]=0x00;
			}
			DisplayData[0]=0x40;   //减号显示,按下减号之后数码管上显示“—”号 
			flag=100;
			g++;	
		}
		if(flag==3)   //等于号 
		{
			if(l>m)
			{	
				t=l-m;
				lm[7]=t/10000000;
				lm[6]=(t%10000000)/1000000;
				lm[5]=((t%10000000)%1000000)/100000;
				lm[4]=(((t%10000000)%1000000)%100000)/10000;
				lm[3]=(((t%10000000)%1000000)%100000)%10000/1000;
				lm[2]=(((t%10000000)%1000000)%100000)%10000%1000/100;
				lm[1]=(((t%10000000)%1000000)%100000)%10000%1000%100/10;
				lm[0]=(((t%10000000)%1000000)%100000)%10000%1000%100%10;
				for(z=0;z<8;z++)
				{
					if(lm[z]!=0)
					{
						y=z+1;
					}
				}
				for(h=0;h<y;h++)
				{
					DisplayData[h]=smgduan[lm[h]];
				}
				for(am=y;am<8;am++)
				{
					DisplayData[am]=0x00;
				}
			}
			if(l<m)
			{
				t=m-l;
				lm[7]=t/10000000;
				lm[6]=(t%10000000)/1000000;
				lm[5]=((t%10000000)%1000000)/100000;
				lm[4]=(((t%10000000)%1000000)%100000)/10000;
				lm[3]=(((t%10000000)%1000000)%100000)%10000/1000;
				lm[2]=(((t%10000000)%1000000)%100000)%10000%1000/100;
				lm[1]=(((t%10000000)%1000000)%100000)%10000%1000%100/10;
				lm[0]=(((t%10000000)%1000000)%100000)%10000%1000%100%10;
				for(z=0;z<8;z++)
				{
					if(lm[z]!=0)
					{
						y=z+1;
					}
				}
				DisplayData[y]=0x40;
				for(h=0;h<y;h++)
				{
					DisplayData[h]=smgduan[lm[h]];
				}
				for(am=y+1;am<8;am++)
				{
					DisplayData[am]=0x00;
				}
					
			}
			flag=100;
		}
		DigDisplay(); 
	}
}
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值