通过矩阵键盘输入数值、运算符进行运算,支持多运算符运算。
仿真图用的12864,可自行替换成其他液晶屏。
说明:
lcd12864.c 包含液晶显示的程序文件
calc.c 包含实现计算的程序文件
keyscanf.c 包含按键扫描的程序文件
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #include <math.h>
- #include "keyscanf.h"
- #include "calc.h"
- #include "lcd12864.h"
- #include <stdio.h>
- bit error = 0;
- bit czfFlag = 0; //当前输入是否为运算符
- bit float_flag = 0; //输入是否浮点数
- bit fs_flag = 0; //输入是否浮点数
- unsigned char keyValue; //按键码
- unsigned char float_num = 0; //浮点位数
- float number1 = 0.0;
- float number2 = 0.0;
- float tempNum = 0.0; //等待运算的数
- unsigned char caozuofu = add;
- unsigned char tempczf = 'A'; //运算符和临时运算符
- unsigned char charNum = 0;
- unsigned char czsNum = 0; //操作数数量
- unsigned char weishu = 0;
- float rest = 0;
- unsigned int sbuf1[255] = {0};
- unsigned char jieguo[255] = {0};
- void loop111()
- {
- clac_loop1();
- if (error == 1)
- {
- lcd_showStr(0,0,"卢某提醒:错误",14);
- }
- else
- {
- if (charNum > 0)
- lcd_showInt(0,0,sbuf1,charNum);
- if (caozuofu == 40)
- lcd_showChars(1,0,jieguo,9);
- }
-
- }
- void clac_loop1()
- {
- keyValue = getkey();
- if (keyValue < 10)
- {
- float temp = 0.0;
- float czstemp = czsNum == 0 ? number1 : number2;
- sbuf1[charNum] = keyValue;
- charNum++;
-
- czstemp = czfFlag == 1 ? 0.0 : czstemp;
-
- if (float_flag == 0)
- {
- czstemp *= 10;
- czstemp += keyValue;
- }
- else
- {
- float_num++;
- temp = (float)keyValue / (pow(10,float_num));
- }
-
- czstemp += temp;
- if (tempczf == 'A')
- {
- if (czsNum == 0)
- number1 = czstemp;
- else
- number2 = czstemp;
- }
- else
- {
- tempNum = czstemp;
- }
- czfFlag = 0;
- weishu++;
- return ;
- }
-
-
- // 防止重复符号
- if (keyValue > 9 && keyValue != 999)
- {
- if (czfFlag == 1)
- return ;
- }
-
- // 防止第一个操作数是符号
- if (keyValue != 999 && keyValue > 6 && charNum == 0)
- {
- return ;
- }
- // + -
- if (keyValue == 11 || keyValue == 22)
- {
- sbuf1[charNum] = keyValue == 11 ? 10 : 11;
- charNum++;czsNum++;
-
- czfFlag = 1;
-
- //核心
- if (isCzf(tempczf))
- {
- number2 = js(number2, tempNum, tempczf);
- tempczf = 'A';
- czsNum--;
- }
-
- if (czsNum == 2)
- {
- number1 = js(number1, number2, caozuofu);
- czsNum--;
- number2 = 0.0;
- }
- caozuofu = keyValue;
- }
-
- // * /
- if (keyValue == 33 || keyValue == 43)
- {
- sbuf1[charNum] = keyValue == 33 ? 12 : 13;
- charNum++;
-
- czsNum++;
- czfFlag = 1;
-
- if ((tempczf == dvi && tempNum <= 0)|| (caozuofu == dvi && number2 <= 0))
- {
- error = 1;
- }
- //核心
- if (isCzf(tempczf))
- {
- number2 = js(number2, tempNum, tempczf);
- tempczf = 'A';
- czsNum--;
- }
-
- if (czsNum == 2)
- {
- tempczf = keyValue;
- }
- else
- caozuofu = keyValue;
- }
-
-
- //小数点
- if (keyValue == 42)
- {
-
- //防止输入两个小数点
- if (float_flag == 1)
- {
- return ;
- }
- float_flag = 1;
- sbuf1[charNum] = 14;
- charNum++;
- }
-
-
- //等于号
- if (keyValue == 40)
- {
- if ((tempczf == dvi && tempNum <= 0)|| (caozuofu == dvi && number2 <= 0))
- {
- error = 1;
- }
-
- //核心
- if (isCzf(tempczf))
- {
- number2 = js(number2, tempNum, tempczf);
- tempczf = 'A';
- czsNum--;
- }
- rest = js(number1, number2, caozuofu);
-
- sbuf1[charNum] = 15;
- charNum++;
-
- //结果转换成字符数组
- sprintf(jieguo,"%f",rest);
- caozuofu = 40;
- float_flag = 0;
- float_num = 0;
- }
- if (rest > 99999999 || float_num > 8 || weishu > 8)
- {
- error = 1;
- return;
- }
-
- //复位
- if (isCzf(keyValue))
- {
- float_flag = 0;
- float_num = 0;
- weishu = 0;
- }
-
- }
- bit isCzf(unsigned char n)
- {
- return (bit)(n == add || n == sub || n == mul || n == dvi || n == equal);
- }
- float js(float a, float b, unsigned char c)
- {
- switch (c)
- {
- case add:
- return a+b;
- case sub:
- return a-b;
- case mul:
- return a*b;
- case dvi:
- return a/b;
- }
- return 0;
- }
复制代码
所有资料51hei提供下载:
CalcEx.zip
(100.17 KB, 下载次数: 42)
|