📄 123.c
字号:
/**************************
0 1 2 3
4 5 6 7
8 9 . CLR
+ - = CLR
***************************/
/***************************
用键盘扫描,数码管显示实现计算功能,能实现xxx.x任意正数的加减
运算,超过范围显0000,功能键如上,并将所得结果储入EEPROM
****************************/
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
/*sfr ISP_DATA=0Xe2;
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;*/
//sfr LedPort=0x80; //P0口段选
//sfr LedBit=0x90; //P1口位选
uchar code table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef
};//0,1,2,3,4,5,6,7,8,9,0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,
uchar temp,dat;
uchar buf1[5];
uchar buf2[5];
uchar end[5];
/**************延时程序*************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/***********键盘扫描***************/
uchar keyscan()
{
uchar num=0;
P2=0x7f;
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
delay(5);
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
temp=P2;
switch(temp)
{
case 0x77:num=1;break;
case 0x7b:num=2;break;
case 0x7d:num=3;break;
case 0x7e:num=4;break;
}
}
}
P2=0xbf;
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
delay(5);
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
temp=P2;
switch(temp)
{
case 0xb7:num=5;break;
case 0xbb:num=6;break;
case 0xbd:num=7;break;
case 0xbe:num=8;break;
}
}
}
P2=0xdf;
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
delay(5);
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
temp=P2;
switch(temp)
{
case 0xd7:num=9;break;
case 0xdb:num=10;break;
case 0xdd:num=11;break;
case 0xde:num=12;break;
}
}
}
P2=0xef;
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
delay(5);
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
temp=P2;
switch(temp)
{
case 0xe7:num=13;break;
case 0xeb:num=14;break;
case 0xed:num=15;break;
case 0xee:num=16;break;
}
}
}
return num;
}
/*********在数码管上显示四位数字**********/
void show(uchar *dis)
{
P1=0xf7;
P0=table[dis[3]];
delay(5);
P1=0xfb;
P0=table[dis[2]];
delay(5);
P1=0xfd;
P0=table[dis[1]];
delay(5);
P1=0xfe;
P0=table[dis[0]];
delay(5);
}
/*********eeprom里读数据******************/
/*uchar EEPROM_Read(uint address)
{
ISP_ADDRH=address/256; // 待写入扇区首地址
ISP_ADDRL=address%256;
ISP_CONTR=0X83; //控制字节
ISP_CMD=0X01; //读命令
ISP_TRIG=0X46; //命令触发寄存器
ISP_TRIG=0XB9;
_nop_();
ISP_CONTR=0X00; //初始化
ISP_CMD=0X00;
ISP_TRIG=0X00;
ISP_ADDRH=0x00;
ISP_ADDRL=0x00;
return(ISP_DATA); //返回读出的值
}
/*********向eeprom里写数据**********************/
/*void EEPROM_Write(uint address,uchar DataTemp)
{
ISP_DATA=DataTemp;
ISP_ADDRH=address/256;
ISP_ADDRL=address%256;
ISP_CMD=0X02; //写指令
ISP_TRIG=0X46; //触发,数据写入
ISP_TRIG=0XB9;
_nop_();
ISP_CONTR=0X00; //初始化
ISP_CMD=0X00;
ISP_TRIG=0X00;
ISP_ADDRH=0x00;
ISP_ADDRL=0x00;
}*/
/*************扇区擦除**********************/
/*void EEPROM_Eares(uint address) //扇区擦除
{
ISP_ADDRL=address;
ISP_ADDRH=address>>6;
ISP_CONTR=0X83;
ISP_CMD=0X03; //扇区命令
ISP_TRIG=0X46; //命令触发寄存器
ISP_TRIG=0XB9;
_nop_();
ISP_ADDRL=0x00;
ISP_ADDRH=0x00;
ISP_CONTR=0X00;
ISP_CMD=0X00;
ISP_TRIG=0X00;
}*/
/********主程序里进行运算********************/
void main(void)
{
uchar i,key,flag,addflag;
addflag=1;
while(1)
{
key=keyscan();
if(addflag==1)
show(buf1);
if(addflag==2)
show(buf2);
if(addflag==3)
show(end);
if(key>0&&key<12&&addflag==1) //第一次输入的数
{
do
{
show(buf1);
P2=0x0f;
temp=P2;
}
while(temp!=0x0f);
if(key!=11)
{
buf1[4]=buf1[3];
buf1[3]=buf1[2];
buf1[2]=buf1[1];
buf1[1]=buf1[0];
buf1[0]=key-1;
}
else
buf1[0]=buf1[0]+10;
if(buf1[4]!=0)
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
if(key>0&&key<12&&addflag==2) //第二次输入的数
{
do
{
show(buf2);
P2=0x0f;
temp=P2;
}
while(temp!=0x0f);
if(key!=11)
{
buf1[4]=buf1[3];
buf2[3]=buf2[2];
buf2[2]=buf2[1];
buf2[1]=buf2[0];
buf2[0]=key-1;
}
else
buf2[0]=buf2[0]+10;
}
if(key==13) //+
{
addflag=2;
flag=1;
}
if(key==14) //-
{
addflag=2;
flag=2;
}
if((key==15)&&(flag==1)) //做加法的结果
{
do
{
show(end);
addflag=3;
P2=0x0f;
temp=P2;
}
while(temp!=0x0f);
addflag=3;
if(buf1[1]<=9&&buf2[1]<=9)
{
end[0]=buf1[0]+buf2[0];
end[1]=buf1[1]+buf2[1];
end[2]=buf1[2]+buf2[2];
end[3]=buf1[3]+buf2[3];
if(end[0]>9) //有进位的整数加法
{
end[0]=end[0]-10;
end[1]++;
}
if(end[1]>9)
{
end[1]=end[1]-10;
end[2]++;
}
if(end[2]>9)
{
end[2]=end[2]-10;
end[3]++;
}
if(end[3]>9)
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
else if(buf1[1]>9&&buf2[1]>9) //两个带小数点的计算
{
end[0]=buf1[0]+buf2[0];
end[1]=buf1[1]+buf2[1]-10;
end[2]=buf1[2]+buf2[2];
end[3]=buf1[3]+buf2[3];
if(end[0]>9) //考虑进位
{
end[0]=end[0]-10;
end[1]++;
}
if(end[1]>19)
{
end[1]=end[1]-10;
end[2]++;
}
if(end[2]>9)
{
end[2]=end[2]-10;
end[3]++;
}
if(end[3]>9)
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
else if(buf1[1]>9&&buf2[0]<=9&&buf2[1]<=9) //带小数点的和整数相加
{ end[0]=buf1[0];
end[1]=buf1[1]+buf2[0];
end[2]=buf1[2]+buf2[1];
end[3]=buf1[3]+buf2[2];
if(end[1]>19)
{
end[1]=end[1]-10;
end[2]++;
}
if(end[2]>9)
{
end[2]=end[2]-10;
end[3]++;
}
if(end[3]>9)
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
else if(buf1[0]<=9&&buf1[1]<=9&&buf2[1]>9) //整数和带小数点的相加
{ end[0]=buf2[0];
end[1]=buf1[0]+buf2[1];
end[2]=buf1[1]+buf2[2];
end[3]=buf1[2]+buf2[3];
if(end[1]>19)
{
end[1]=end[1]-10;
end[2]++;
}
if(end[2]>9)
{
end[2]=end[2]-10;
end[3]++;
}
if(end[3]>9)
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
//EEPROM_Eares(0x2000);
//EEPROM_Write(0x2000+end[5],end[5]); //起始地址为2000
}
if((key==15)&&(flag==2)) //做减法的结果
{
do
{
show(end);
addflag=3;
P2=0x0f;
temp=P2;
}
while (temp!=0x0f);
addflag=3;
if(buf1[1]<=9&&buf2[1]<=9)
{
end[0]=buf1[0]-buf2[0];
end[1]=buf1[1]-buf2[1];
end[2]=buf1[2]-buf2[2];
end[3]=buf1[3]-buf2[3];
if(buf1[0]<buf2[0]) //考虑有借位的两整数相减
{
end[0]=buf1[0]+(10-buf2[0]);
end[1]--;
buf1[1]--;
}
if(buf1[1]<buf2[1])
{
end[1]=buf1[1]+(10-buf2[1]);
end[2]--;
buf1[2]--;
}
if(buf1[2]<buf2[2])
{
end[2]=buf1[2]+(10-buf2[2]);
end[3]--;
}
if(buf1[3]<buf2[3])
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
else if (buf1[1]>9&&buf2[1]>9) //考虑两带小数点的两数相减
{
end[0]=buf1[0]-buf2[0];
end[1]=buf1[1]-buf2[1]+10;
end[2]=buf1[2]-buf2[2];
end[3]=buf1[3]-buf2[3];
if(buf1[0]<buf2[0])
{
end[0]=buf1[0]+(10-buf2[0]);
end[1]--;
buf1[1]--;
}
if(buf1[1]<buf2[1])
{
end[1]=buf1[1]+20-buf2[1];
end[2]--;
buf1[2]--;
}
if(buf1[2]<buf2[2])
{
end[2]=buf1[2]+(10-buf2[2]);
end[3]--;
}
if(buf1[3]<buf2[3])
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
else if(buf1[1]>9&&buf2[0]<=9&&buf2[1]<=9) //带小数点的减整数
{
end[0]=buf1[0];
end[1]=buf1[1]-buf2[0];
end[2]=buf1[2]-buf2[1];
end[3]=buf1[3]-buf2[2];
if(buf1[1]<buf2[0]+10)
{
end[1]=buf1[1]+10-buf2[0];
end[2]--;
buf1[2]--;
}
if(buf1[2]<buf2[1])
{
end[2]=buf1[2]+10-buf2[1];
end[3]--;
}
if(buf1[3]<buf1[3])
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
else if(buf1[0]<=9&&buf1[1]<=9&&buf2[1]>9) //整数减带小数点的
{
end[0]=10-buf2[0];
end[1]=buf1[0]-buf2[1]+19;
end[2]=buf1[1]-buf2[2];
end[3]=buf1[2]-buf2[3];
if(buf1[0]<buf2[1]-10)
{
end[1]=buf1[0]+29-buf2[1];
end[2]--;
buf1[1]--;
}
if(buf1[1]<buf2[2])
{
end[2]=buf1[1]+10-buf2[1];
end[3]--;
}
if(buf1[3]<buf1[3])
{
for(i=0;i<4;i++)
buf1[i]=0;
}
}
// EEPROM_Eares(0x2000);
// EEPROM_Write(0x2000+end[5],end[5]);
}
if(key==12||key==16) //清0键
{
for(i=0;i<4;i++)
buf1[i]=0;
for(i=0;i<4;i++)
buf2[i]=0;
for(i=0;i<4;i++)
end[i]=0;
addflag=1;
}
/* while(1)
{
EEPROM_Write(0x2000,end[5]);//起始地址为2000
ISP_DATA=0;
dat=0;
dat=EEPROM_Read(0x200+end[5]-1); //一个扇区与下一个扇区相差200
show(end);
} */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -