51单片机设计的计算器
参考了这个博主的代码写的觉得条理很清楚 ,代码的写法基本也是按照这位博主的,只改了一些
https://blog.csdn.net/liang507107/article/details/89453934
矩阵按键代表计算器中的值
可以实现连续的加减乘除 **P0 发送数据 P2实现动态数码管的片选 P1接矩阵按键**+ | - | * | / |
---|---|---|---|
3 | 6 | 9 | 清零 |
2 | 5 | 8 | = |
1 | 4 | 7 | 0 |
下面是代码
在这里插入代码片
#include<reg51.h>
#include<intrins.h>
#define uc unsigned char
#define ut unsigned int
#define key_board P1 //矩阵按键
#define shu_ju P0 //给数码管数据
#define pian_xuan P2 //控制动态数码管
ut sum1=0,sum2=0 ;//算结果的
uc addflag=0;//加法标志
uc subflag=0; //减法标志
uc mulflag=0; //乘法标志
uc divflag=0; //除法标志
uc qpflag=0; //在进行连加减乘除是 清空数码管
uc code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值 共阴数码管
static uc duanxuan[8];
uc keyflag=0;//表示是否有按键的记录
uc keyflag1=0; //在计算函数里控制
uc keyvalue;
void delay(ut t)
{
uc i,j;
for(i=0;i<=t;i++)
{
for(j=0;j<=120;j++);
}
}
void kaishi()
{
uc t,i;
uc yiwei=0x7f;
for(i=0;i<8;i++)
{ t=duanxuan[i];
t=smgduan[t];
shu_ju=0;
pian_xuan=yiwei;
shu_ju=t;
delay(5);
yiwei=_cror_(yiwei,1);
yiwei|=0x80;
}
}
uc anjian( ) //找出按键代表的值
{
uc cc;
uc aa=0;
key_board=0xf0;
if(key_board!=0xf0)
{
delay(10); //消除前抖动
}
if(key_board!=0xf0) //再次检测
{
keyflag=1; //表示有按键按下
cc=key_board; //记录行地址
}
key_board=0x0f;
cc=cc|key_board; //得出地址
while((aa<=50)&&(key_board!=0x0f)) //强制退出
{ delay(10);
aa++;
}
return cc;
}
void keyfenzhi(uc k)
{
switch(k){
case 0xe7: keyvalue=1; break;
case 0xd7: keyvalue=2;break;
case 0xb7: keyvalue=3;break;
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;
}
keyflag1=1;
}
void K_K(ut yyy)
{
duanxuan[0]=yyy%10;
duanxuan[1]=yyy/10%10;
duanxuan[2]=yyy/100%10;
duanxuan[3]=yyy/1000%10;
duanxuan[4]=yyy/10000%10;
duanxuan[5]=yyy/100000%10;
duanxuan[6]=yyy/1000000%10;
duanxuan[7]=yyy/10000000%10;
}
void jiafa() //加法函数
{
addflag++; //进行加法 加法标志加1
subflag=mulflag=divflag=0;
qpflag=1;
if(addflag>1)
{
sum1=sum2+sum1;
}
sum2=sum1;
}
void jianfa() //减法函数
{
subflag++; //进行加法加法标志加1
addflag=mulflag=divflag=0;
qpflag=1;
if(subflag>1)
{
sum1=sum2-sum1;
}
sum2=sum1;
}
void chengfa() //乘法函数
{
mulflag++; //进行加法加法标志加1
addflag=subflag=divflag=0;
qpflag=1;
if(mulflag>1)
{
sum1=sum2*sum1;
}
sum2=sum1;
}
void chufa() //除法函数
{
divflag++; //进行加法加法标志加1
subflag=mulflag=addflag=0;
qpflag=1;
if(divflag>1)
{
sum1=sum2/sum1;
}
sum2=sum1;
}
void dengyu()
{
if(addflag)
{
sum1=sum1+sum2;
}
if(subflag)
{
sum1=sum2-sum1;
}
if(mulflag)
{
sum1=sum2*sum1;
}
if(divflag)
{
sum1=sum2/sum1;
}
addflag=subflag=mulflag=divflag=0;// 运算完成一次所有标志清零
K_K(sum1); qpflag=1;
}
void shujuyiwei(uc la)
{
uc i;
for(i=7;i>0;i--)
{
duanxuan[i]=duanxuan[i-1];
}
duanxuan[0]=la ;
}
void shujuchuli()
{
if(keyvalue==15)
{
sum1=sum2=0;
K_K(sum1);
}
if(qpflag==1)
{
sum1=0;
qpflag=0;
K_K(sum1);
}
if(keyvalue<10)
{
shujuyiwei(keyvalue);
sum1=sum1*10+keyvalue;
}
}
void jisuan()
{
if(keyflag1)
{
keyflag1=0;
switch(keyvalue)
{
case 10:jiafa();K_K(sum1);break; // 这里K_K()是在连续加的时候显示出计算结果
case 11:jianfa();K_K(sum1);break;
case 12:chengfa();K_K(sum1);break;
case 13:chufa();K_K(sum1) ;break;
case 14:dengyu();break;
default:shujuchuli( ); //其他则是数据
}
}
}
void main( )
{
uc y;
while(1)
{
y=anjian( ); //返回 按键值
if(y!=0xff) //判断是否按键按下
{
keyfenzhi(y); //按键对应的值
}
jisuan();
kaishi(); //在8位数码管显示数字
}
}