|
20黑币
设计一个矩阵键盘5*5的计算器,要求有括号的优先级。还有小数点。。写到小数点就不知道该怎么写。。请各帮帮忙。
- #include<reg52.h>
- #include<math.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit rs = P2^0;
- sbit rw = P2^1;
- sbit lcden = P2^2;
- uchar code anjian[]={ //键盘值
- 'A','(',')','B','C',
- '7','8','9','/','D',
- '4','5','6','*','E',
- '1','2','3','-','F',
- 'G','0','.','+','='
- };
- uchar code shuzhi[]={
- '0','1','2','3','4',
- '5','6','7','8','9'
- };
- double num[20]; //储存数值
- double value; //储存结果
- char flag; //运算符判断
- uchar KeyValue = 30; //按键值
- void delay(uint z) //毫秒级延时
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=114;y>0;y--);
- }
- /*********************** 定时器0初始化 ***********************/
- //void Init_timer0()
- //{
- // EA = 1;
- // ET0 = 1;
- // TR0 = 1;
- // TMOD = 0x01;
- // TH0 = 0xED; //定时5ms
- // TL0 = 0xFF;
- //}
- /*********************** 5*5矩阵键盘 ***********************/
- void KeyScan()
- {
- P3 = 0xFF; //列扫描
- P1 = 0;
- while(KeyValue == 30)
- {
- if(P3 != 0xFF)
- {
- delay(10);
- if(P3 != 0xFF)
- {
- switch(P3)
- {
- case 0xFE: KeyValue=0; break;
- case 0xFD: KeyValue=1; break;
- case 0xFB: KeyValue=2; break;
- case 0xF7: KeyValue=3; break;
- case 0xEF: KeyValue=4; break;
- }
- P1 = 0xFF; //行扫描
- P3 = 0;
- switch(P1)
- {
- case 0xF7: KeyValue=KeyValue; break;
- case 0xEF: KeyValue=KeyValue+5; break;
- case 0xDF: KeyValue=KeyValue+10; break;
- case 0xBF: KeyValue=KeyValue+15; break;
- case 0x7F: KeyValue=KeyValue+20; break;
- }
- while(P1 != 0xFF); //松手检测
- }
- }
- }
- }
- /*********************** LCD1602 ***********************/
- void Read_Busy() //判忙函数
- {
- uchar busy;
- P0 = 0xFF;
- rs = 0;
- rw = 1;
- do
- {
- lcden = 1;
- busy = P0;
- lcden = 0;
- }while(busy & 0x80);
- }
- void Write_Cmd(uchar cmd) //写指令
- {
- Read_Busy();
- rs = 0;
- rw = 0;
- P0 = cmd;
- lcden = 1;
- lcden = 0;
- }
- void Write_Dat(uchar dat) //写数据
- {
- Read_Busy();
- rs = 1;
- rw = 0;
- P0 = dat;
- lcden = 1;
- lcden = 0;
-
- KeyValue = 30; //清按键值
- }
- void Init_lcd() //lcd初始化
- {
- Write_Cmd(0x38); //16*2显示
- Write_Cmd(0x0C); //开显示
- Write_Cmd(0x01); //清屏
- Write_Cmd(0x06); //读写一字节后,地址指针加1
- }
- /*********************** 获取数值 ***********************/
- void GetNum(int x)
- {
- num[x] = anjian[KeyValue] - 48;
- Write_Dat(anjian[KeyValue]);
- KeyScan();
- while(48 <= anjian[KeyValue] && anjian[KeyValue] <= 57)
- {
- num[x] = num[x] * 10 + (anjian[KeyValue] - 48);
- Write_Dat(anjian[KeyValue]);
- KeyScan();
- }
- }
- /*********************** 运算符号 ***********************/
- void GetFlag()
- {
- switch(anjian[KeyValue])
- {
- case '+':
- flag = '+';
- Write_Dat('+'); break;
- case '-':
- flag = '-';
- Write_Dat('-'); break;
- case '*':
- flag = '*';
- Write_Dat('*'); break;
- case '/':
- flag = '/';
- Write_Dat('/'); break;
- }
- KeyScan();
- GetNum(1);
- }
- /*********************** 计算结果 ***********************/
- void calculate()
- {
- int ge, shi, bai;
-
- Write_Cmd(0xC0);
- Write_Dat('=');
-
- switch(flag)
- {
- case '+':
- value = num[0] + num[1]; break;
- case '-':
- value = num[0] - num[1]; break;
- case '*':
- value = num[0] * num[1]; break;
- case '/':
- value = num[0] / num[1]; break;
- }
-
- if(0 <= fabs(value) && fabs(value) <= 9) //1位数
- {
- ge = fabs(value);
- if(value >= 0)
- Write_Dat(shuzhi[ge]);
- else
- {
- Write_Dat('-');
- Write_Dat(shuzhi[ge]);
- }
- }
-
- if(10 <= fabs(value) && fabs(value) <= 99) //2位数
- {
- shi = fabs(value) / 10;
- ge = (int)fabs(value) % 10;
- if(value >= 0)
- {
- Write_Dat(shuzhi[shi]);
- Write_Dat(shuzhi[ge]);
- }
- else
- {
- Write_Dat('-');
- Write_Dat(shuzhi[shi]);
- Write_Dat(shuzhi[ge]);
- }
- }
-
- if(100 <= fabs(value) && fabs(value) <= 999) //3位数
- {
- bai = fabs(value) / 100;
- shi = (int)fabs(value) /10 % 10;
- ge = (int)fabs(value) % 10;
- if(value >= 0)
- {
- Write_Dat(shuzhi[bai]);
- Write_Dat(shuzhi[shi]);
- Write_Dat(shuzhi[ge]);
- }
- else
- {
- Write_Dat('-');
- Write_Dat(shuzhi[bai]);
- Write_Dat(shuzhi[shi]);
- Write_Dat(shuzhi[ge]);
- }
- }
- }
- void main()
- {
- //Init_timer0();
- Init_lcd();
- Write_Cmd(0x80); //第一行显示字符
-
- while(1)
- {
- KeyScan();
- if(48 <= anjian[KeyValue] && anjian[KeyValue] <= 57) //获取0~9数值
- GetNum(0);
-
- if(anjian[KeyValue] == '=')
- calculate();
- else
- GetFlag();
- }
- }
- /*********************** T0中断函数 ***********************/
- //void timer0() interrupt 1
- //{
- // TH0 = 0xED; //定时5ms
- // TL0 = 0xFF;
- //
- // if(anjian[KeyValue] == 'A')
- // {
- // Write_Cmd(0x01); //清屏
- // Write_Cmd(0x80); //第一行显示字符
- // //KeyValue = 0;
- // }
- //}
复制代码
|
-
捕获.PNG
(92.65 KB, 下载次数: 85)
仿真图
|