整合代码
详细文章(带仿真图)见链接
https://blog.csdn.net/xiantiaoop/article/details/107052493
#include<reg51.h>
#define uc unsigned char
#define ut unsigned int
#define kong1 P1 //控制矩阵按键
// kong0=P0 发送命令发送数据
uc code a[]={'0','1','2','3','4','5','6','7','8','9','+','-','*','/','='};
long sum1,sum2;
float sum3 ; //用于除法
long sum4,sum5; //用于除法;
uc addflag,subflag,mulflag,divflag;
uc keyflag; // 在keyvaluechuli()函数中控制
uc flag ;// 控制乘中的sum1;
uc keyvalue=100;
sbit RS=P2^6;
sbit RW=P2^5;
sbit EN=P2^7;
void delay1ms(ut t);
void LCDcmd(uc cmd);
void LCDdat(uc dat);
void LCDinitial( );
void delay10us(ut t) //误差 0us
{
uc a;
for(;t>0;t--)
for(a=2;a>0;a--);
}
//判断按键值
void delay1ms(ut t) //误差 0us
{
unsigned char a,b;
for( ;t>0;t--)
for(b=199;b>0;b--)
for(a=1;a>0;a--);
}
void LCDcmd(uc cmd)
{
EN=0;
RS=0;
RW=0;
kong1=cmd;
delay1ms(1);
EN=1;
delay1ms(5);
EN=0;
}
void LCDdat(uc dat)
{
EN=0;
RS=1;
RW=0; //RS=0; RW=1
kong1=dat;
delay1ms(1);
EN=1;
delay1ms(5);
EN=0;
}
void LCDinitial()
{
LCDcmd(0x38); //设置功能模式
LCDcmd(0x0c);// 开显示
LCDcmd(0x06);//写一位指针加一
LCDcmd(0x01);//清屏
LCDcmd(0x80); //初始地址
}
uc keypanduan() //返回按键值
{
uc cc; //cc作为返回值 aa控制强制退出
kong1=0xf0;
if(kong1!=0xf0) //先判断行
{
delay10us(100); //1000us
if(kong1!=0xf0)
{
cc=kong1;
keyflag=1;
}
}
kong1=0x0f ;// 判断列
if(kong1!=0x0f)
{
delay10us(100);
if(kong1!=0x0f)
{
cc=cc|kong1; //得到按键值
}
}
while(kong1!=0x0f);
return cc;
}
//通过对应的按键值对应value 在
//keyvaluechuli()函数中对value进行处理
void keyswitch(uc key)
{
switch(key){
case 0xe7: keyvalue=1; break;
// + - * /
case 0xd7: keyvalue=2; break; // 3 6 9 清零
// 2 5 8 =
case 0xb7: keyvalue=3; break; // 1 4 7 0
case 0xeb: keyvalue=4; break;
case 0xdb: keyvalue=5; break;
case 0xbb: keyvalue=6; break;
case 0xed: keyvalue=7; break;
case 0xdd: keyvalue=8; break;
case 0xbd: keyvalue=9; break;
case 0xee: keyvalue=0; break;
case 0x77: keyvalue=10; break; //加法
case 0x7b: keyvalue=11; break;// 减法
case 0x7d: keyvalue=12; break;//乘法
case 0x7e: keyvalue=13; break;//除法
case 0xde: keyvalue=14; break;//等于
case 0xbe: keyvalue=15; break;// 清屏
default :break;
}
}
void shujuchuli() // 0~9
{
if(keyvalue==15)
{
LCDcmd(0x01);
sum1=sum2=0;
addflag=0;
subflag=0;
mulflag=0;
divflag=0;
}
if(keyvalue<10)
{
if(flag==1) //flag在乘中控制使按下一个数据清除sum1
{
sum1=0;
flag=0;
}
sum1=sum1*10+keyvalue;
LCDdat(a[keyvalue]);
}
}
void jiafa()
{
addflag++;
subflag=mulflag=divflag=0;
if(addflag>1)
{
sum1=sum1+sum2;
}
sum2=sum1;
sum1=0;
}
void jianfa()
{
subflag++;
addflag=mulflag=divflag=0;
if(subflag==1)
{
sum2=sum1;
}
if(subflag>1)
{
sum2=sum2-sum1;
}
sum1=0;
}
void chengfa()
{
mulflag++;
subflag=addflag=divflag=0;
flag=1;
if(mulflag>1)
{
sum1=sum1*sum2;
}
sum2=sum1;
}
void chufa()
{
divflag++;
subflag=mulflag=addflag=0;
if(divflag==1)
{
sum3=sum1;
}
if(divflag>1)
{
sum3=sum3/sum1; //除法保留3位小数
}
sum1=0;
}
void dengyu()
{
if(addflag) //加法
{
sum2=sum1+sum2;
LCDcmd(0x4f+0x80);
LCDcmd(0x04);
while(sum2!=0)
{
LCDdat(0x30+sum2%10);
sum2/=10;
}
LCDdat('=');
addflag=0;
}
if(subflag) //减法
{
sum2=sum2-sum1;
LCDcmd(0x4f+0x80); //从第二行从右向左写数据
LCDcmd(0x04);
if(sum2>=0)
{
while(sum2!=0)
{
LCDdat(0x30+sum2%10);
sum2/=10;
}
}
else
{
sum2=-sum2;
while(sum2!=0)
{
LCDdat(0x30+sum2%10);
sum2/=10;
}
LCDdat('-');
}
LCDdat('=');
subflag=0;
}
if(mulflag) //乘法
{
sum2=sum1*sum2;
LCDcmd(0x4f+0x80);
LCDcmd(0x04);
while(sum2!=0)
{
LCDdat(0x30+sum2%10);
sum2/=10;
}
LCDdat('=');
mulflag=0;
}
//除法结果小于0.1和等于0.1和等于以上3种情况
//放大了1000000倍 再通过取余的方法求数据
if(divflag) //除法
{
uc cent=0;
uc k=0,i=0;
sum2=(sum3/sum1)*1000000;//保留6位小数
LCDcmd(0x4f+0x80);
LCDcmd(0x04);
if(sum2==100000)
{
while(sum2!=0)
{
LCDdat(0x30+sum4%10);
sum4/=10;
}
for(i=0;i<cent;i++)
{
if(i==cent-2)
{
LCDdat(0x30); //0
LCDdat('.');
}
else
{
LCDdat(0x30); //0
}
}
cent=0;
}
if(sum2<100000)
{
sum4=sum2;
sum5=sum2;
while(sum5<100000)
{
cent++;
sum5*=10;
}
while(sum4!=0)
{
LCDdat(0x30+sum4%10);
sum4/=10;
}
for(i=0;i<=cent;i++)
{
if(i==cent-1)
{
LCDdat(0x30); //0
LCDdat('.');
}
else
{
LCDdat(0x30); //0
}
}
}
if(sum2>100000)
{
while(sum2!=0)
{
k++; //k到3时写小数点
LCDdat(0x30+sum2%10);
sum2/=10;
if(k==6)
{
LCDdat('.');
if(sum2==0)
{
LCDdat(0x30); //写0
}
}
}
LCDdat('=');
divflag=0;
}
}
}
void keyvaluechuli() //对key的值进行处理
{
if(keyflag) //表明 按键按下
{
keyflag=0;
switch(keyvalue)
{
case 10:jiafa(); LCDdat(a[keyvalue]);break;
case 11:jianfa(); LCDdat(a[keyvalue]);break;
case 12:chengfa(); LCDdat(a[keyvalue]);break;
case 13:chufa(); LCDdat(a[keyvalue]);break;
case 14:dengyu(); break;
default:shujuchuli( ); // 0~9 和清零
}
}
}
void main()
{
uc yy=0;
LCDinitial( );
while(1)
{
yy=keypanduan(); //按键值赋值给yy;
keyswitch(yy); //得到对应的value值
keyvaluechuli(); //对value值对应的功能进行处理
}
}