#include<reg52.h>
#include<math.h>
#define unchar unsigned char
#define unint unsigned int
#define Pi 3.141596
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;
sbit busy=P0^7;
char i,j,flag,fuhao,y,r,z;
char s[30];
unchar num,temp;
long a,b,c;
unchar code table[]={7,8,9,0,//内部运算用
4,5,6,0,
1,2,3,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0};
unchar code table1[]={7,8,9,0x2f-0x30,//显示用7,8,9,/,//后面加了0x30,所以这里减掉
4,5,6,0x2a-0x30,//4,5,6,*
1,2,3,0x2d-0x30,//1,2,3,-
0x01-0x30,0,0x3d-0x30,0x2b-0x30,//ON/C,0,=,+
0x22-0x30,0x5e-0x30,0x25-0x30,0x21-0x30,//"代表根号,^次方,%,!
0x02-0x30,0x03-0x30,0x04-0x30,//2转10,10转2,10转16,16转10
0x05-0x30,0x06-0x30,0x07-0x30,0x08-0x30};//sin,coa,tan,ln
void delay(unchar z)
{
unchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void checkbusy()
{
while(busy==1)//P0^7最高位为1为忙,0为闲
{
P0=0xff;
rs=0;
rw=1;
en=0;//禁止读写
delay(20);
en=1;
}
}
void write_com(unchar com)
{
rs=0;
rw=0;
en=0;
checkbusy();
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write_date(unchar date)
{
rs=1;
rw=0;
en=0;
checkbusy();
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init()
{
write_com(0x38);//16*2显示,5*7点阵,8位数据接口
delay(50);
write_com(0x0c);//开显示关光标和闪烁
delay(50);
write_com(0x06);//地址向后移
delay(50);
write_com(0x80);//光标初始地址
write_com(0x01);//清屏
delay(50);
i=0;flag=0;//赋初值flag表示按符号键后的输入值,默认为没按之前的输入
fuhao=0;a=0;b=0;c=0;
}
void lcd_clean()//清屏
{
write_com(0x01);
delay(20);
}
void keyscan()
{
//**************P3口的键盘检测
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:num=0; break;
case 0xde:num=1; break;
case 0xbe:num=2; break;
case 0x7e:num=3; break;
}
}
while(P3!=0xfe);
if(num==0||num==1||num==2)
{
if(flag==0)
a=a*10+table[num];//a是在没按符号键之前输入的值
if(flag==1)
b=b*10+table[num];//b是按符号键后输入的值
}
if(num==3)//"/"除键
{
flag=1;
fuhao=4;//"/"
}
i=table1[num];//显示的值
write_date(0x30+i);//十六进制表示的ASC码
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=4; break;
case 0xdd:num=5; break;
case 0xbd:num=6; break;
case 0x7d:num=7; break;
}
}
while(P3!=0xfd);
if(num==4||num==5||num==6)
{
if(flag==0)
a=a*10+table[num];
else
b=b*10+table[num];
}
if(num==7)//"*"乘
{
flag=1;
fuhao=3;
}
i=table1[num];
write_date(0x30+i);
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=8; break;
case 0xdb:num=9; break;
case 0xbb:num=10; break;
case 0x7b:num=11; break;
}
}
while(P3!=0xfb);
if(num==8||num==9||num==10)
{
if(flag==0)
{a=a*10+table[num];}
else
{b=b*10+table[num];}
}
if(num==11)//"-"减
{
flag=1;
fuhao=2;
}
i=table1[num];
write_date(0x30+i);
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num=12; break;
case 0xd7:num=13; break;
case 0xb7:num=14; break;
case 0x77:num=15; break;
}
}
while(P3!=0xf7);//松手检测,没有松手则保持显示的状态
switch(num)
{
case 12:{
lcd_clean();
a=0;b=0;flag=0;
fuhao=0;
} break;
case 13:{
if(flag==0)
{
a=a*10;write_date(0x30);
}
else
{
b=b*10;
write_date(0x30);
}
} break;
case 14:{//需要按"="的
if(fuhao==1)
{
write_com(0x80+0x0f);
lcd_clean();//重新定位后再清屏
write_com(0x04); i=0;
c=a+b;
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
}
write_date(0x3d);//写"="
a=0;b=0;flag=0;fuhao=0;//清0
}
else if(fuhao==2)
{
write_com(0x80+0x0f);
lcd_clean();
write_com(0x04);
if(a-b>0)
c=a-b;
else
c=b-a;
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
}
if(a-b<0)
write_date(0x2d);//"-"减
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==3)
{
write_com(0x80+0x0f);
lcd_clean();
write_com(0x04);
c=a*b;
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
}
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==4)
{
write_com(0x80+0x0f);
lcd_clean();
write_com(0x04);
i=0;
c=(long)(((float)a/b)*1000);//化整后再加小数点
while(c!=0)
{
write_date(0x30+c%10);
c=c/10; i++;
if(i==3)
write_date(0x2e);//加小数点"."
}
if(a/b<=0)
write_date(0x30);
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==5)
{
write_com(0x80+0x0f);
lcd_clean();
write_com(0x04);
c=(long)(pow((float)a,(float)1/b)*1000);
i=0;
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
i++;
if(i==3)
write_date(0x2e);
}
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==6)
{
write_com(0x80+0x0f);
lcd_clean();
write_com(0x04);
c=pow((float)a,(float)b);//c52内部的函数
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
}
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==7)
{
write_com(0x80+0x0f);
lcd_clean();
write_com(0x04);
c=a%b;
if(c==0)
write_date(0x30);
while(c>0)
{
write_date(0x30+c%10);
c=c/10;
}
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
} break;
case 15:{
i=table1[num];
write_date(0x30+i);//"+"加
flag=1;fuhao=1;
} break;
}
}
//*********************P1口的键盘检测
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:num=16; break;
case 0xde:num=17; break;
case 0xbe:num=18; break;
case 0x7e:num=19; break;
}
}
while(P1!=0xfe);
switch(num)
{
case 16:{
i=table1[num];
write_da