protues仿真:
- /*******************************************************************************
- * 标题: 矩阵键盘实现简易计算器 *
- * 时间 2018年7月22日15:53:57 *
- * *
- * 实验说明:用矩阵键盘实现简易计算器,可以进行四位数的加减乘除,数字显示在动态*
- 数码管,+、-、*、/显示在静态数码管上,每次必须输入四个数字数码管才会亮,例如, *
- 要计算 6+7,那么第一步是输入0006,才会在数码管上显示0006,第二步是+,静态数码管 *
- 上就会出现一个类似+的符号,接着输入0007,步骤同上,最后按=,得出结果 *
- ********************************************************************************
- * 实验心得:做这个简易计算器一共做了快四天,碰到了许多问题,时间浪费最多的是在 *
- 数组定义那里,如果定义成unsigned int code[].那么该数组就不能进行值的改变,所以 *
- 需要 *
- 定义成unsigned int[]。还有一个问题就是很奇怪的一个,就是把xianshi()这个函数放在*
- while(1) *
- { *
- Two(); *
- if(KeyScan()==8) *
- { *
- KeyValue=12; *
- RES(); *
- First[0]=16; *
- First[1]=16; *
- First[2]=16; *
- First[3]=16; *
- KeyValue=8; *
- break; *
- }这个里面,就输出不了结果,很奇怪???现在还不知道为什么会这样,如果有*
- 知道 *
- 的,评论啊。 *
- 最后一个就是protues仿真那里,keypad的线怎么接???,一直不行 *
- ********************************************************************************/
- #include <reg52.h>
- #include <math.h>
- unsigned int result,m,n;//result为计算结果,m为被X数,n为X数
- unsigned int KeyValue=-1;//相当于一个flag的作用
- unsigned char code DIG_CODE[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
- 0x7F, 0x6F, 0x70, 0x40, 0x76, 0x49,0x09};//数码管上显示编码(0~9,+、-、*、/、=)
- unsigned int code change[17]={0x3F,0x06,0x66,0x07,0x3F,0x5B,0x6D,0x7F,0x09,0x4F,0x7D,0x6F,0x70,0x40,0x76,0x49,0x00};
- unsigned int code changenumber[16]={0,1,4,7,0,2,5,8,14,3,6,9,10,11,12,13};
- unsigned int First[4];//定义一个有4个单元的数组,如果定义成 unsigned int code First[4],这个数组就不能修改值
- unsigned int Second[4];
- unsigned int value[8];//给计算出来的result存放值
- #define GPIO_SHOW P0
- #define GPIO_KEY P1
- #define GPIO_DIG P2
- sbit LSA = P3^0;
- sbit LSB = P3^1;
- sbit LSC = P3^2;
- void RES();//返回计算结果函数
- void xianshi(); //显示最终的计算结果
- void caculate();//计算第一个数和最后一数
- void Rejudge();//判断第二个数的函数
- void judge();//判断第一个数的函数
- int KeyScan(void);//按键扫描函数
- void Delay10ms(unsigned int c);//延迟函数
- void One();//被X数
- void Two();//X数
- void main()
- {
- while(1)
- {
- judge();
- while(1)
- {
- One();
-
- if(KeyValue==8)
- {
- GPIO_DIG=change[8];
- xianshi();
- if(KeyScan()==0)
- break;
-
- }
- if(KeyScan()==0)
- {
- GPIO_SHOW=0x00;
- KeyValue=-1;
- break;
- }
-
- else if(KeyScan()==12)
- {
-
- GPIO_DIG=change[12];
- KeyValue=-1;
- Rejudge();
- while(1)
- {
- Two();
- if(KeyScan()==8)
- {
- KeyValue=12;
- RES();
- First[0]=16;
- First[1]=16;
- First[2]=16;
- First[3]=16;
- KeyValue=8;
- break;
- }
-
- }
-
- }
-
- else if(KeyScan()==13)
- {
- GPIO_DIG=change[13];
- KeyValue=-1;
- Rejudge();
- while(1)
- {
- Two();
- if(KeyScan()==8)
- {
- KeyValue=13;
- RES();
- First[0]=16;
- First[1]=16;
- First[2]=16;
- First[3]=16;
- KeyValue=8;
- break;
- }
- }
- }
- else if(KeyScan()==14)
- {
- GPIO_DIG=change[14];
- KeyValue=-1;
- Rejudge();
- while(1)
- {
- Two();
- if(KeyScan()==8)
- {
- KeyValue=14;
- RES();
- First[0]=16;
- First[1]=16;
- First[2]=16;
- First[3]=16;
- KeyValue=8;
- break;
- }
- }
-
- }
- else if(KeyScan()==15)
- {
- GPIO_DIG=change[15];
- KeyValue=-1;
- Rejudge();
- while(1)
- {
- Two();
- if(KeyScan()==8)
- {
- KeyValue=15;
- RES();
- First[0]=16;
- First[1]=16;
- First[2]=16;
- First[3]=16;
- KeyValue=8;
- break;
- }
- }
-
- }
- }
- }
- }
- void One ()
- {
- unsigned char j;
- unsigned char i;
- for(i=0;i<4;i++)
- {
- switch(i)
- {
- case(0):
- LSA=0;LSB=0;LSC=1;
- break;//显示第4位
- case(1):
- LSA=1;LSB=0;LSC=1;
- break;//显示第5位
- case(2):
- LSA=0;LSB=1;LSC=1;
- break;//显示第6位
- case(3):
- LSA=1;LSB=1;LSC=1;
- break;//显示第7位
- }
- GPIO_SHOW=change[First[i]];
- j=10; //扫描间隔时间设定
- while(j--);
- GPIO_SHOW=0x00;//消隐
- }
- }
- void judge()
- {
- unsigned int i;
- for(i=0;i<4;i++)
- {
- do
- {
- KeyScan();
- First[i]=KeyScan();
- }while(KeyValue==-1);
- KeyValue=-1;
-
-
- }
- m = 1000*changenumber[First[0]]+100*changenumber[First[1]]+10*changenumber[First[2]]+changenumber[First[3]]; //;m为被X数
- }
- void Two()
- {
- unsigned char j;
- unsigned char i;
- for(i=0;i<4;i++)
- {
- switch(i)
- {
- case(0):
- LSA=0;LSB=0;LSC=1;
- break;//显示第4位
- case(1):
- LSA=1;LSB=0;LSC=1;
- break;//显示第5位
- case(2):
- LSA=0;LSB=1;LSC=1;
- break;//显示第6位
- case(3):
- LSA=1;LSB=1;LSC=1;
- break;//显示第7位
- }
- GPIO_SHOW=change[Second[i]];
- j=10; //扫描间隔时间设定
- while(j--);
- GPIO_SHOW=0x00;//消隐
- }
- }
- void Rejudge()
- {
- unsigned int i;
- for(i=0;i<4;i++)
- {
- do
- {
- KeyScan();
- Second[i]=KeyScan();
- }while(KeyValue==-1);
- KeyValue=-1;
-
-
- }
- n = 1000*changenumber[Second[0]]+100*changenumber[Second[1]]+10*changenumber[Second[2]]+changenumber[Second[3]]; //;n为X数
- }
- void RES()
- {
- if(KeyValue==12)
- {
- result=m+n;
- caculate();
- }
- else if(KeyValue==13)
- {
- result=m-n;
- caculate();
- }
- else if(KeyValue==14)
- {
- result=m*n;
- caculate();
- }
- else if(KeyValue==15)
- {
- result=m/n;
- caculate();
- }
-
- }
- void caculate()
- {
- // unsigned int i;
- // for(i=0;i<8;i++)
- // {
- // value[i]=(result%(int)(pow(10,(8-i))))/((int)pow(10,(7-i)));
- // }
- value[0]=result/10000000;
- value[1]=(result%10000000)/1000000;
- value[2]=(result%1000000)/100000;
- value[3]=(result%100000)/10000;
- value[4]=(result%10000)/1000;
- value[5]=(result%1000)/100;
- value[6]=(result%100)/10;
- value[7]=(result%10);
-
- }
- void xianshi()
- {
- unsigned char j;
- unsigned char i;
- for(i=0;i<8;i++)
- {
- switch(i)
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//显示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//显示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//显示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//显示第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//显示第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//显示第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//显示第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//显示第7位
- }
- GPIO_SHOW=DIG_CODE[value[i]];
- j=10; //扫描间隔时间设定
- while(j--);
- GPIO_SHOW=0x00;//消隐
- }
-
- }
- int KeyScan(void) //测试行(row)的时候就是线是竖着的的那一列为1,测试列(col)的时候就是线是横着的那几行为1
- {
- char a = 0;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f)//读取按键是否按下
- {
- Delay10ms(1);//延时10ms进行消抖
- if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
- {
- //测试列
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=4;break;
- case(0X0d): KeyValue=8;break;
- case(0X0e): KeyValue=12;break;
- }
- //测试行
- GPIO_KEY=0XF0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue+3;break;
- case(0Xb0): KeyValue=KeyValue+2;break;
- case(0Xd0): KeyValue=KeyValue+1;break;
- case(0Xe0): KeyValue=KeyValue;break;
- }
- while((a<50) && (GPIO_KEY!=0xf0)) //检测按键松手检测
- {
- Delay10ms(1);
- a++;
- }
-
- }
- }
- return KeyValue;//这一步的return值很重要,需要等KeyValue值准确的出来后,才能返回,不用return的话就是一个中途的KeyValue值(刚行扫描完就赋值给数组)。
-
- }
- void Delay10ms(unsigned int c) //误差 0us
- {
- unsigned char a, b;
- //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
- for (;c>0;c--)
- {
- for (b=38;b>0;b--)
- {
- for (a=130;a>0;a--);
- }
- }
- }
复制代码
全部资料51hei下载地址:
protues版.rar
(73.05 KB, 下载次数: 38)
|