/*****************************************************************************************************************************
文件名:简易计算器
功能:基本功能:
1、实现加、减、乘、除
2、小数的加减乘除
扩展功能:
1、能显示负数
2、能做复合运算
作者:
创建时间:
修改时间:
特别说明:
*****************************************************************************************************************************/
#include <REGX52.H>
#define uchar unsigned char
#define uint unsigned int
#define weixuan P1
#define duanxuan P0
uchar code tab[11] = /*数码管编码*/
{0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00};
uchar code scan[8] = /*数码管位选编码*/
{0x7f,0xbf,0xdf,0xef,
0xf7,0xfb,0xfd,0xfe};
uchar cache[8] = {0};
uchar result0, result1;
uchar a[8] = {1,10,100,1000,10000,100000,1000000,10000000};
uint res[3] = {0};
uint dip[8] = {0};
uint num1, num2, RESU;
uchar X, Y, Z, p, op, jw;
uchar set, t, i, j, k, index;
bit flag, flag0, flag1, flag2, f; /*定义标志位,flag=0时没有数据输入,flag=1的时候有数据输入*/
void LED_IN();
void scan_key();
void operation();
void deal_keynumber();
void convert();
/****************************************************************************************************************************
延时函数
****************************************************************************************************************************/
void delay(uchar t)
{
for(i = t;i>0;i--)
for(j = 0;j<200;j++);
}
/****************************************************************************************************************************
初始化子程序
****************************************************************************************************************************/
void init()
{
TMOD = 0x01;
TH0 = -10;
TR0 = 1;
ET0 =1;
EA = 1;
}
/****************************************************************************************************************************
主函数
****************************************************************************************************************************/
void main()
{
init();
while(1)
{
scan_key();
if(flag0 == 1&&flag == 1)
{
LED_IN();
flag0 = 0;
}
}
}
/****************************************************************************************************************************
定时器中断服务子程序,定时(5ms)扫描数码管一次
****************************************************************************************************************************/
void TIMER_0() interrupt 1
{
flag0 = 1;
TH0 = -10;
}
/****************************************************************************************************************************
矩阵键盘的扫描,给变量p赋相应的“符号标志”,为数据的输入以及加减乘除的识别做准备
****************************************************************************************************************************/
void scan_key()
{
uchar m;
P3=0xff;
P3=0x0f;
if(P3!=0x0f) //判断是否有按键按下
{
delay(40); //延时去抖
if(P3!=0x0f)//确认真的有键按下
{
set++; /*记录按键的次数*/
flag = 1; //flag标志变量 ,方便LED_IN1中输入数据u
X=P3;
P3=0xf0;
Y=P3;
Z=X|Y;
while(P3 != 0xf0);//确认松开按键
switch(Z)
{
case 0xee:
{
k = 1; /*'!'作为似识别是0-9的数据输入的标志符号*/
p = '!';
break; //输出‘1’
}
case 0xde:
{
k = 2;
p = '!';
break; //输出‘2’
}
case 0xbe:
{
k = 3;
p = '!';
break; //输出‘3’
}
case 0x7e:
{
k = 10; /*'@'作为识别+、-、*、/的标志符号*/
p = '@';
op = '+';
break; //代表‘+’
}
case 0xed:
{
k = 4;
p = '!';
break; //输出‘4’
}
case 0xdd:
{
k = 5;
p = '!';
break; //输出‘5’
}
case 0xbd:
{
k = 6;
p = '!';
break; //输出‘6’
}
case 0x7d:
{
k = 11;
p = '@';
op = '-';
break; //代表‘-’
}
case 0xeb:
{
k = 7;
p = '!';
break; //输出‘7’
}
case 0xdb:
{
k = 8;
p = '!';
break; //输出‘8’
}
case 0xbb:
{
k = 9;
p = '!';
break; //输出‘9’
}
case 0x7b:
{
k = 12;
p = '@';
op = '*';
break; //代表‘*’
}
case 0xe7:
{
k = 15;
p = '&'; /*&作为清0的标志符号*/
break; //代表清‘0’
}
case 0xd7:
{
k = 0;
p = '!';
break; //输出‘0’
}
case 0xb7:
{
k = 14;
p = '#'; /*作为=的标志符号*/
break; // 作为‘=’
}
case 0x77:
{
k = 13;
p = '@';
op = '/';
break; //代表‘/’
}
}
}
// set++; /*记录按键的次数*/
if(set == 9) /*若按下的键,全是p == ‘!’的情形,能显示的最大数为“8位”*/
{
set = 0;
for(m = 0;m < 8;m++)
{
dip[m] = 0;
}
}
}
deal_keynumber(); /*调用函数,处理数据*/
}
/****************************************************************************************************************************
此函数的作用是:“处理矩阵键盘传来的数据,以及各种特殊标志符号所代表的具体功能”
****************************************************************************************************************************/
void deal_keynumber()
{
uchar n, v1,v2,v3;
if(p == '!')
{
flag2 = 0;
p = 0; /*一定要归‘0’*/
for(v1 = 7;v1 >0;v1--) /*数据移位*/
{
dip[v1] = dip[v1-1];
}
dip[0] = k;
}
else if(p == '@') /*按了‘+’‘-’‘*’‘/’*/
{
flag2 = 1;
set = 0; /*为输入第二个数做准备*/
index = 0;
p = 0;
num1 = dip[0]*a[0]+dip[1]*a[1]+dip[2]*a[2]+dip[3]*a[3]+dip[4]*a[4]+
dip[5]*a[5]+dip[6]*a[6]+dip[7]*a[7]; /*记录输入的第一个数据*/
for(v2 = 0;v2 < 8;v2++) /*第一个数据赋给:num1后,把dip[i]归0*/
{
dip[v2] = 0;
}
}
else if(p == '&')
{
flag2 = 1;
p = 0;
for(n = 0;n < 8;n++)
{
dip[n] = 0; /*按了‘清0’键后,清屏*/
set = 0;
}
}
else if(p == '#')
{
flag2 = 0; /*按了“=”之后,执行相应的运算,并显示*/
p = 0;
num2 = dip[0]*a[0]+dip[1]*a[1]+dip[2]*a[2]+dip[3]*a[3]+dip[4]*a[4]+
dip[5]*a[5]+dip[6]*a[6]+dip[7]*a[7]; /*记录输入的第二个数据*/
for(v3 = 0;v3 < 8;v3++) /*第二个数据赋给:num2后,把dip[i]归0*/
{
dip[v3] = 0;
}
operation(); /*调用运算函数,处理数据,进而,得出结果*/
convert();
} /*调用数据转换函数,供显示用*/
}
/****************************************************************************************************************************
加、减、乘、除四则运算的处理函数
****************************************************************************************************************************/
void operation()
{
switch(op)
{
case '+' :
{
RESU = num1+num2;
flag1 = 1;
break;
}
case '-':
{
if( num1 > num2)
{
RESU = num1 - num2;
}
flag1 = 1;
break;
}
case '*':
{
RESU = num1*num2;
flag1 = 1;
break;
}
case '/':
{
RESU = num1/num2;
flag1 = 1;
break;
}
}
op = 0;
}
/****************************************************************************************************************************
此函数的功能是:“把res[0]、res[1]、res[2]的千万位、百万位、十万位、万位、~~~分离出来,同时存入缓存数组---cache[]之中,为
显示函数输出做准备”!
**************************