Bootstrap

矩阵键盘实现简易计算器,PROTEUS仿真(免费完整代码)

proteus电路图如下:

 主函数:

#include"Util.h"
#include"Int_DigitalDisplay.h"
#include"Int_MatrixButton.h"

//总结:
//1.变量的声明和定义要在函数的前面,否则报错
//2.计算数要足够大,否则会溢出
//3.某行代码无法打断点,将代码优化等级调为零即可

void main()
{

	unsigned long num1 = 0;  //避免数字溢出
	unsigned long num2 = 0;
	unsigned long res;
	u8 sys,keyValue;
	u8 i = 0;
	u8 computation = 1;
	Int_InitDigitalTube();
	Int_InitMatrixButton();
	
	while(1)
	{
		keyValue = Int_IsButtonPressed();
		//按的数字
		if(keyValue >= 0 && keyValue <= 9)
		{
			if(computation == 1)
			{
				num1 *= 10;
				num1 += keyValue;
				Int_DigitalTube_DisplayNum(num1);		//展示数字并且刷新数字缓存区
			}
			else
			{
				num2 *= 10;
				num2 += keyValue;
				Int_DigitalTube_DisplayNum(num2);
			}
		}
		else if(keyValue >= 10 && keyValue <= 13)//按的运算符
		{
			sys = keyValue;
			computation++;
		}
		else if(keyValue == 14) //按的清零
		{
			num1 = 0;
			num2 = 0;
			computation = 1;
			Int_ResetDigital();
		}
		else if(keyValue == 15) //按的等号
		{
			switch(sys)
			{
				case 10:
					res = num1 + num2;
					Int_DigitalTube_DisplayNum(res);
					break;
				case 11:
					res = num1 - num2;
					Int_DigitalTube_DisplayNum(res);
					break;
				case 12:
					res = num1 * num2;
					Int_DigitalTube_DisplayNum(res);
					break;
				case 13:
					res = num1 / num2;
					Int_DigitalTube_DisplayNum(res);
					break;				
			}
		}
		Int_DigitalRefresh();
	}
}

子函数c文件:

//数码管驱动

//以下是头文件(Int_DigitalDisplay.h)
#include<stc89c5xrc.h>
#include<intrins.h>

#define chip P0 //片选
#define seg  P2  //段选

//数码管初始化,关闭所有数码管
void Int_InitDigitalTube();

//展示一个数码管的数字
void Int_DisplaySingle_DigitalTube(u8 dig,u8 num);

刷新数码管
void Int_DigitalRefresh();

//显示数字,写多少显示多少
void Int_DigitalTube_DisplayNum(unsigned long num);

//复位数码管,使之全灭
void Int_ResetDigital();


//以下是c文件
#include"Util.h"
#include"Int_DigitalDisplay.h"
#include<math.h>

static seg_table[] = 
	{
	0xc0,//0
	0xf9,//1
	0xa4,//2
	0xb0,//3
	0x99,//4
	0x92,//5
	0x82,//6
	0xf8,//7
	0x80,//8
	0x90,//9
	0xff //全灭
	};
	
//数字缓存,存储一个16位数字的个十百··位
static u8 NumberBuff[8] = {10,10,10,10,10,10,10,10};
	
void Int_InitDigitalTube()
{
	chip = 0;
}

void Int_DisplaySingle_DigitalTube(u8 dig,u8 num)
{
	u8 temp = 0x01;
	temp = _crol_(temp,dig - 1);
	chip = temp;
	seg = seg_table[num];
}

//刷新缓存区里的数字
void Int_DigitalRefresh()
{
	u8 j;
	for(j = 1;j <= 8;j++)
	{
		Int_DisplaySingle_DigitalTube(j,NumberBuff[8 - j]);
	}
}

void Int_DigitalTube_DisplayNum(unsigned long num)
{
	u8 i = 7;
	u8 j = 0;
	u8 temp = (u8)log10(num) + 1;
	
	if(num ==0)
	{
		NumberBuff[7] = 0;
	}
	
	while(num > 0)
	{
		NumberBuff[i] = num % 10;
		i--;
		num /= 10;
	}
	//把缓存数组前面的零变成全灭对应的数值
//	while(NumberBuff[j] == 0)
//	{
//		NumberBuff[j] = 10;
//		j++;
//	}
  for(j = 0;j < 8 - temp;j++)
	{
		NumberBuff[j] = 10;
	}
}

void Int_ResetDigital()
{
	u8 i;
	for(i = 0;i < 8;i++)
	{
		NumberBuff[i] = 10;
	}
	
}


//矩阵按键

//头文件(Int_MatrixButton.h)
#include<stc89c5xrc.h>
#include<intrins.h>

#define KEY P1   //P10-P13表示行,P14-17表示列

//初始化矩阵按键,行拉低,列拉高
void Int_InitMatrixButton();

u8 Int_IsButtonPressed();

//c文件
#include"Util.h"
#include"Int_MatrixButton.h"
#include"Int_DigitalDisplay.h"

//P00-P03表示行,P04-07表示列

//按键按下去KEY口对应的16个数值
static u8 MatrixTable[16] = {0xee,0xed,0xeb,0xe7,
														 0xde,0xdd,0xdb,0xd7,
														 0xbe,0xbd,0xbb,0xb7,
														 0x7e,0x7d,0x7b,0x77};

void Int_InitMatrixButton()
{
	KEY = 0X0F;
}

u8 Int_IsButtonPressed()
{
	//第一行
	KEY = 0XEF;
	if(KEY == MatrixTable[0])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[0])
		{
			while(~P10); //等待松开
			return 7;
		}
	}

	if(KEY == MatrixTable[1])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[1])
		{
			while(~P10); //等待松开
			return 8;
		}
	}
	
	if(KEY == MatrixTable[2])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[2])
		{
			while(~P10); //等待松开
			return 9;
		}
	}
	
	if(KEY == MatrixTable[3])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[3])
		{
			while(~P10); //等待松开
			return 10;
		}
	}	
	
	//第二行
	KEY = 0XDF;
	if(KEY == MatrixTable[4])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[4])
		{
			while(~P10); //等待松开
			return 4;
		}
	}

	if(KEY == MatrixTable[5])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[5])
		{
			while(~P10); //等待松开
			return 5;
		}
	}
	
	if(KEY == MatrixTable[6])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[6])
		{
			while(~P10); //等待松开
			return 6;
		}
	}
	
	if(KEY == MatrixTable[7])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[7])
		{
			while(~P10); //等待松开
			return 11;
		}
	}	
	
	//第三行
	KEY = 0XBF;
	if(KEY == MatrixTable[8])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[8])
		{
			while(~P10); //等待松开
			return 1;
		}
	}

	if(KEY == MatrixTable[9])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[9])
		{
			while(~P10); //等待松开
			return 2;
		}
	}
	
	if(KEY == MatrixTable[10])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[10])
		{
			while(~P10); //等待松开
			return 3;
		}
	}
	
	if(KEY == MatrixTable[11])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[11])
		{
			while(~P10); //等待松开
			return 12;
		}
	}	
	
	//第四行
	KEY =  0X7F;
	if(KEY == MatrixTable[12])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[12])
		{
			while(~P10); //等待松开
			return 14;
		}
	}

	if(KEY == MatrixTable[13])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[13])
		{
			while(~P10); //等待松开
			return 0;
		}
	}
	
	if(KEY == MatrixTable[14])
	{
		DelayMs(80); //按下消抖
		if(KEY == MatrixTable[14])
		{
			while(~P10); //等待松开
			return 15;
		}
	}
	
	if(KEY == MatrixTable[15])
	{
		DelayMs(100); //按下消抖
		if(KEY == MatrixTable[15])
		{
			while(~P10); //等待松开
			return 13;
		}
	}	
	
	return 16;
	
}


//通用函数

//头文件(Util.h)
#include<STC89C5XRC.H>
//放置通用定义以及通用函数

typedef unsigned int u16;
typedef unsigned char u8;

void DelayMs(u16 z);

//c文件
#include"Util.h"

void DelayMs(u16 z)
{
  u16 x,y;
  for(x = z;x > 0;x--)
     for(y = 114;y > 0;y--);
}

总结:
1.变量的声明和定义要在函数的前面,否则报错
2.用于计算的数要足够大,否则会溢出
3.某行代码无法打断点,将代码优化等级调为零即可

不足:

1.只能实现两个数字的加减乘除

2.无法显示负数

3.除法运算的时候无法显示小数

以后有空再来升级(狗头 狗头)。

;