51 简易加法计算器

/*
*******************************************************************************
目标
做一个简易的加法计算器
功能分析
按下键盘数字,显示到数码管
按下加号 数码管清零,记录下一个数字
直到按下回车键 显示出结果

构思
按键扫描函数,检测4次报告哪个键被有效按下  			keyscan
按键驱动函数,再主程序里面不断进行循环检测按键		keydrive
按键动作函数,根据按下的不同键,输出给不同的数值 	keyaction
数码管显示函数,根据不同的按键值显示数码管数值		ledshow	
数码管扫描函数,每1ms切换点亮数码管					ledscan

*******************************************************************************
*/
#include <reg52.h>
//数码管相关
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
//按键相关
sbit key1=P2^4;
sbit key2=P2^5;
sbit key3=P2^6;
sbit key4=P2^7;
unsigned char key[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char code keycodemap[4][4]={{1,2,3,10},{4,5,6,11},{7,8,9,12},{0,14,15,16}}; //按键数值设定
unsigned char code ledchar[]={0XC0,0XF9,0XA4,0XB0,
0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E};//数码管数值取值
unsigned char leddd[6]={0xff,0xff,0xff,0xff,0xff,0xff};
void ledshow(unsigned long number)//对按键传递的数值进行显示
{
	unsigned char k;
	unsigned char cnt=0;
	unsigned char shu;
	for(k=0;k<6;k++)
		leddd[k]=0xff;
	if(number==0)leddd[0]=ledchar[0];
	while(number!=0)
	{
		shu=number%10;
		number=number/10;
		leddd[cnt]=ledchar[shu];
		cnt++;	
	}
}
void keyaction(unsigned char k,unsigned char l)
{
	static unsigned long number=0;
	static unsigned long sum=0;
	if(keycodemap[k][l]>=0&&keycodemap[k][l]<=9)//输入的是数字
	{
		number=number*10+keycodemap[k][l];
		if(number>999999)number=0;
		ledshow(number);
	}
	else if(keycodemap[k][l]==10)//输入的是向上键
	{
		ledshow(0);
		sum=sum+number;
		number=0;
	}
	else if(keycodemap[k][l]==15)//输入的是回车
	{
		sum=sum+number;
		if(sum>999999)sum=0;
		ledshow(sum);
		sum=0;
		number=0;
	}
	else 
	{
		sum=0;
		number=0;
		ledshow(0);
	}

}
void keydrive()
{
	unsigned char i,j;
	static unsigned char old[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		{
			if(key[i][j]!=old[i][j])//按键被按下
			{
				if(old[i][j]==1)
					keyaction(i,j); //对不同按键数值进行反应
				old[i][j]=key[i][j];
			}
		}
}
void keyscan() //每1ms对按键值进行扫描
{
	unsigned char z=0;
	static unsigned char keyout=0;
	static unsigned char keyy[4][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},
	{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
	//对这一排的按键进行扫描
	keyy[keyout][0]=(keyy[keyout][0]<<1)|key1;
	keyy[keyout][1]=(keyy[keyout][1]<<1)|key2;
	keyy[keyout][2]=(keyy[keyout][2]<<1)|key3;
	keyy[keyout][3]=(keyy[keyout][3]<<1)|key4;
	//判断四次扫描数值
	for(z=0;z<4;z++)
	{
		if((keyy[keyout][z]&0x0f)==0x0f)
			key[keyout][z]=1;
		else if	((keyy[keyout][z]&0x0f)==0x00)
			key[keyout][z]=0;
	}
	//切换不同排数
	keyout++;
	if (keyout>=4)keyout=0;
	switch (keyout)
	{
		case 0:P2=0XF7;break;
		case 1:P2=0XFB;break;
		case 2:P2=0XFD;break;
		case 3:P2=0XFE;break;
		default:break;
	}
}

void ledscan() //按键扫描
{
	static unsigned char sis=0;
	P0=0xff;//消隐
	switch(sis)
	{
		case 0:ADDR2=0;ADDR1=0;ADDR0=0;sis++;P0=leddd[0];break;
		case 1:ADDR2=0;ADDR1=0;ADDR0=1;sis++;P0=leddd[1];break;
		case 2:ADDR2=0;ADDR1=1;ADDR0=0;sis++;P0=leddd[2];break;
		case 3:ADDR2=0;ADDR1=1;ADDR0=1;sis++;P0=leddd[3];break;
		case 4:ADDR2=1;ADDR1=0;ADDR0=0;sis++;P0=leddd[4];break;
		case 5:ADDR2=1;ADDR1=0;ADDR0=1;sis=0;P0=leddd[5];break;
		default :break;
	}	
}
void main()
{
   //打开138
   ENLED=0;
   ADDR3=1;
   //打开定时
   TMOD=0X01;
   TH0=0XFC;
   TL0=0X67;
   EA=1;
   ET0=1;
   TR0=1;
   leddd[0]=ledchar[0];
   while(1)
   {
   		keydrive(); 	
   }
}
void interruptTimer0() interrupt 1
{
   TH0=0XFC;
   TL0=0X67;
   ledscan();
   keyscan();	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王蒟蒻

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

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

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

打赏作者

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

抵扣说明:

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

余额充值