最近在学习单片机,在学习了动态数码管和矩阵按键后自己突然想实现一个简易的计算器程序。
按键的设置:按顺序设置下来4x4的矩阵按键,前两排设置成数字0-7,第三排按键前两个是数字8,9,后两个是'+'、'-'符号,最后一排是前两个设置成'*'、'/'符号,第三个是'='符号,最后一个暂未设置,可以进行数值较小的数字的运算,后续再慢慢进行优化
定义的变量的说明:数组用于保存按下的数字按键用于数码管动态显示,标志位tag0代表加运算,1代表减运算,2代表乘运算,3代表除运算,临时变量temp默认为0用于保存按下的数字后面用于计算,nexttag用于当按下符号按键后,下一次按下数字按键的话就会对数组进行清空进行第二次数字的输入。
大概思路就是单片机接通电源后,会一直进行检测有没有按键按下,如果有按键按下的话会进行判断,如果检测是按下数字按键的话会保存在一个数组里,temp变量进行*10+数字按键的计算保存按下的数字,如果检测到按下的是符号的话,这时会将临时变量保存到一个新的变量上后面用于运算,并将nexttag置为1,temp置为0,下一次进行数字按键输入的话就会清空数组,进行重新显示第二个数字,最后按下等于号的话就会将此时temp变量存储的值赋给第二个变量,通过判断tag进行对应的运算。
最后是源代码的分享,仅供参考哦,希望各位大神多多指教
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define GPIO_DIG P0
#define GPIO_KEY P1
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
u8 keyvalue;
u8 keyvalue1;
u8 array[16]={0};
int count=0;
u8 tag;
int temp=0;
int one=0;
int two=0;
int total;
u8 nexttag=0;
void cleararray()
{
u8 i;
for(i=0;i<count;i++)
{
array[i]=0;
}
count=0;
}
void delay(int i)
{
while(i--);
}
void gettotal()
{
u8 temp1;
u8 i;
u8 temp2;
while(total)
{
temp1=total%10;
array[count++]=temp1;
total=total/10;
}
for(i=0;i<count/2;i++)
{
temp2=array[i];
array[i]=array[count-1-i];
array[count-1-i]=temp2;
}
}
void KeyDown()
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)
{
delay(1000);
if(GPIO_KEY!=0x0f)
{
switch(GPIO_KEY)
{
case(0x07):keyvalue=0;break;
case(0x0b):keyvalue=1;break;
case(0x0d):keyvalue=2;break;
case(0x0e):keyvalue=3;break;
}
GPIO_KEY=0xf0;
switch(GPIO_KEY)
{
case(0x70):
{
if(keyvalue==0)
{
keyvalue1=0;
}else if(keyvalue==1)
{
keyvalue1=1;
}else if(keyvalue==2)
{
keyvalue1=2;
}else
{
keyvalue1=3;
}
}break;
case(0xb0):
{
if(keyvalue==0)
{
keyvalue1=4;
}else if(keyvalue==1)
{
keyvalue1=5;
}else if(keyvalue==2)
{
keyvalue1=6;
}else
{
keyvalue1=7;
}
}break;
case(0xd0):
{
if(keyvalue==0)
{
keyvalue1=8;
}else if(keyvalue==1)
{
keyvalue1=9;
}else if(keyvalue==2)
{
keyvalue1=10;
}else
{
keyvalue1=11;
}
}break;
case(0xe0):
{
if(keyvalue==0)
{
keyvalue1=12;
}else if(keyvalue==1)
{
keyvalue1=13;
}else if(keyvalue==2)
{
keyvalue1=14;
}else
{
keyvalue1=15;
}
}break;
}
if(keyvalue1>=0&&keyvalue1<=9)
{
if(nexttag==0)
{
array[count++]= keyvalue1;
temp=temp*10+keyvalue1;
}else
{
cleararray();
array[count++]= keyvalue1;
temp=temp*10+keyvalue1;
nexttag=0;
}
}else if(keyvalue1==10) //加法
{
tag=0;
one=temp;
temp=0;
nexttag=1;
}else if(keyvalue1==11) //减法
{
tag=1;
one=temp;
temp=0;
nexttag=1;
}else if(keyvalue1==12) //乘法
{
tag=2;
one=temp;
temp=0;
nexttag=1;
}else if(keyvalue1==13) //除法
{
tag=3;
one=temp;
temp=0;
nexttag=1;
}else if(keyvalue1==14)
{
two=temp;
cleararray();
switch(tag)
{
case 0:
{
total=one+two;
gettotal();
}
break;
case 1:
{
total=one-two;
gettotal();
}
break;
case 2:
{
total=one*two;
gettotal();
}
break;
case 3:
{
total=one/two;
gettotal();
}
break;
}
}
while((a<50)&&(GPIO_KEY!=0xf0))
{
delay(1000);
a++;
}
}
}
}
void main()
{
int i;
while(1)
{
KeyDown();
for(i=0;i<count;i++)
{
switch(i)
{
case 0:
LSA=1;LSB=1;LSC=1;break;
case 1:
LSA=0;LSB=1;LSC=1;break;
case 2:
LSA=1;LSB=0;LSC=1;break;
case 3:
LSA=0;LSB=0;LSC=1;break;
case 4:
LSA=1;LSB=1;LSC=0;break;
case 5:
LSA=0;LSB=1;LSC=0;break;
case 6:
LSA=1;LSB=0;LSC=0;break;
case 7:
LSA=0;LSB=0;LSC=0;break;
}
GPIO_DIG=smgduan[array[i]];
delay(100);
GPIO_DIG=0x00;
}
}
}