通過矩陣鍵盤輸入數值、運算符進行運算,支持多運算符運算。
仿真圖用的12864,可自行替換成其他液晶屏。
說明:
lcd12864.c 包含液晶顯示的程序文件
calc.c 包含實現計算的程序文件
keyscanf.c 包含按鍵掃描的程序文件
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (9.92 KB, 下載次數: 33)
下載附件
2018-11-24 14:57 上傳
單片機源程序如下:
- #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;
- }
復制代碼
0.png (16.23 KB, 下載次數: 41)
下載附件
2018-11-24 14:57 上傳
所有資料51hei提供下載:
CalcEx.zip
(100.17 KB, 下載次數: 42)
2018-11-24 11:34 上傳
點擊文件名下載附件
下載地址 下載積分: 黑幣 -5
|