外观
软件开发
整体思路
简易计算器代码主要是对思维逻辑的考验,通过将矩阵按键按下的值转换为对应的字符数字,当按下“=”之后,对字符串进行解析,提取出每一个数字以及运算符,遵循先乘除后加减的运算优先级进行计算,最终得到结果。
LCD显示代码
LCD1602的显示代码是比较简单的,在网上也有非常多的参考,这里与之不同的是引脚分配,在LCD1602的DB0~DB7引脚中,并不是直接分配一组IO给它使用,这样导致Lcd_Write写数据或写指令函数会麻烦一点,实际代码如下。
Lcd写数据或写指令函数
C
/*
函数内容:Lcd写数据或写指令函数
函数参数:unsigned char cd---指令或数据
unsigned char Data-待发送的指令或数据
返回值: 无
*/
void Lcd_Write(unsigned char cd,unsigned char Data)
{
if(cd == WriteCommand){
LCD_RS = 0;
LCD_RW = 0;
}
else{
LCD_RS = 1;
LCD_RW = 0;
}
if(Data & 0x80){
LCD_DB7 = 1;
}
else{
LCD_DB7 = 0;
}
if(Data & 0x40){
LCD_DB6 = 1;
}
else{
LCD_DB6 = 0;
}
if(Data & 0x20){
LCD_DB5 = 1;
}
else{
LCD_DB5 = 0;
}
if(Data & 0x10){
LCD_DB4 = 1;
}
else{
LCD_DB4 = 0;
}
if(Data & 0x08){
LCD_DB3 = 1;
}
else{
LCD_DB3 = 0;
}
if(Data & 0x04){
LCD_DB2 = 1;
}
else{
LCD_DB2 = 0;
}
if(Data & 0x02){
LCD_DB1 = 1;
}
else{
LCD_DB1 = 0;
}
if(Data & 0x01){
LCD_DB0 = 1;
}
else{
LCD_DB0 = 0;
}
LCD_EN = 1;
delay_ms(1);
LCD_EN = 0;
delay_ms(1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
按键扫描代码
矩阵按键的扫描在电路原理中已经分析过了,此时仅需要遍历扫描然后返回对应的字符数字即可,推荐返回值使用char类型,这样输入的数据可以直接使用字符数组进行接收,不需要重新转换。
按键扫描函数
C
char MatrixKey(void)
{
char KeyNumber = No_Press;
P1 = 0xFF;
P3_7=1;
P1_4 = 0;
if(P1_0==0){delay_ms(20);if(P1_0==0){while(P1_0==0);KeyNumber = Number7;}}
if(P1_1==0){delay_ms(20);if(P1_1==0){while(P1_1==0);KeyNumber = Number4;}}
if(P1_2==0){delay_ms(20);if(P1_2==0){while(P1_2==0);KeyNumber = Number1;}}
if(P1_3==0){delay_ms(20);if(P1_3==0){while(P1_3==0);KeyNumber = Rem;}}
P1 = 0xFF;
P3_7=1;
P1_5 = 0;
if(P1_0==0){delay_ms(20);if(P1_0==0){while(P1_0==0);KeyNumber = Number8;}}
if(P1_1==0){delay_ms(20);if(P1_1==0){while(P1_1==0);KeyNumber = Number5;}}
if(P1_2==0){delay_ms(20);if(P1_2==0){while(P1_2==0);KeyNumber = Number2;}}
if(P1_3==0){delay_ms(20);if(P1_3==0){while(P1_3==0);KeyNumber = Number0;}}
P1 = 0xFF;
P3_7=1;
P1_6 = 0;
if(P1_0==0){delay_ms(20);if(P1_0==0){while(P1_0==0);KeyNumber = Number9;}}
if(P1_1==0){delay_ms(20);if(P1_1==0){while(P1_1==0);KeyNumber = Number6;}}
if(P1_2==0){delay_ms(20);if(P1_2==0){while(P1_2==0);KeyNumber = Number3;}}
if(P1_3==0){delay_ms(20);if(P1_3==0){while(P1_3==0);KeyNumber = Point;}}
P1 = 0xFF;
P3_7=1;
P1_7 = 0;
if(P1_0==0){delay_ms(20);if(P1_0==0){while(P1_0==0);KeyNumber = Add;}}
if(P1_1==0){delay_ms(20);if(P1_1==0){while(P1_1==0);KeyNumber = Sub;}}
if(P1_2==0){delay_ms(20);if(P1_2==0){while(P1_2==0);KeyNumber = Mul;}}
if(P1_3==0){delay_ms(20);if(P1_3==0){while(P1_3==0);KeyNumber = Div;}}
P1 = 0xFF;
P3_7=0;
if(P1_0==0){delay_ms(20);if(P1_0==0){while(P1_0==0);KeyNumber = BackSpace;}}
if(P1_1==0){delay_ms(20);if(P1_1==0){while(P1_1==0);KeyNumber = SigClear;}}
if(P1_2==0){delay_ms(20);if(P1_2==0){while(P1_2==0);KeyNumber = Clear;}}
if(P1_3==0){delay_ms(20);if(P1_3==0){while(P1_3==0);KeyNumber = Sum;}}
return KeyNumber;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
c
#define No_Press 'F'
#define First_key 0xFE
#define Number0 '0'
#define Number1 '1'
#define Number2 '2'
#define Number3 '3'
#define Number4 '4'
#define Number5 '5'
#define Number6 '6'
#define Number7 '7'
#define Number8 '8'
#define Number9 '9'
#define Rem '%'
#define Point '.'
#define Add '+'
#define Sub '-'
#define Mul '*'
#define Div '/'
#define BackSpace 'b'
#define Clear 'C'
#define SigClear 'c'
#define Sum '='
char MatrixKey(void);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
主逻辑代码
主逻辑代码相对较为复杂,主要分为拆分数据、计算乘除法、计算加减法三部分,我采用的方法是将字符数组中的每一个数和每一个运算符都拆分单独保存起来,其中如果有小数,也是一样的操作,把它当成一个数进行保存。
拆分数据完成后,需要先计算乘除以及取余,此时需要依次遍历运算符,假设是1×2×3这样的字符,那我们需要计算出来,然后将结果保存到第一个数据上。取余计算的话需要注意不能是小数,需要定义整形变量进行强制类型转换。
最后是加减,也是依次遍历运算符,此时是将结果保存在sum中,最后打印sum即可,这里的逻辑需要大家自行理解,同时51单片机调试较为困难,我强烈建议使用一个标准的c语言编译器进行代码验证,比如vs、devc++等等,我们指定一个字符串然后进行处理即可,这里并不设计任何GPIO等操作,标准c语言编译器可以很好的使用调试和printf等操作输出,而且不用反复烧录代码。