【Proteus仿真】51单片机制作简易计算器+ LCD1602显示

【Proteus仿真】51单片机制作简易计算器+ LCD1602显示


  • Proteus仿真效果演示
    在这里插入图片描述

程序代码

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#include<reg51.h> //头文件
#define uint unsigned int
#define uchar unsigned char

sbit lcden=P1^1; //LCD1602控制引脚
sbit rs=P1^0;
sbit rw=P1^2;
sbit busy=P0^7;//LCD忙

char i,j,temp,num,num_1;
long a,b,c; //a,第一个数 b,第二个数 c,得数
float a_c,b_c;
uchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符
//flag=1表示运算符键按下,flag=0表示运算符键没有按下;
//fuhao=1为加法,fuhao=2为减法,fuhao=3为乘法,fuhao=4为除法。

uchar code table[]={//运算数字输入数组
7,8,9,0,
4,5,6,0,
1,2,3,0,
0,0,0,0};
uchar code table1[]={ //经处理后进行键输入显示准备的数组
7,8,9,0x2f-0x30, //7,8,9,÷
4,5,6,0x2a-0x30, //4, 5, 6,×
1,2,3,0x2d-0x30, //1, 2, 3,-
0x01-0x30,0,0x3d-0x30,0x2b-0x30//C,0,=,+
};
void delay(uchar z) // 延迟函数
{
uchar y;
for(z;z>0;z--)
for(y=0;y<110;y++);
}
void write\_com(uchar com) // 写指令函数
{
rs=0;
P0=com; //com指令付给P0口
delay(5);lcden=1;delay(5); lcden=0;
}

void write\_date(uchar date) // 写数据函数
{
rs=1; P0=date; delay(5);
lcden=1; delay(5); lcden=0;
}

void init() //初始化
{
num=-1;
lcden=1; //使能信号为高电平
rw=0;
write\_com(0x38); //8位,2行
delay(5); write\_com(0x38); //8位,2行
delay(5); write\_com(0x0c); //显示开,光标关,不闪烁\*/
delay(1); write\_com(0x06); //增量方式不移位
delay(1); write\_com(0x80); //检测忙信号
delay(1); write\_com(0x01); //显示开,光标关,不闪烁
num_1=0;
i=0; j=0;
a=0; //第一个参与运算的数
b=0; //第二个参与运算的数
c=0;
flag=0; //flag表示是否有符号键按下,
fuhao=0; // fuhao表征按下的是哪个符号
}
void keyscan() // 键盘扫描程序
{
P2=0xfe;
if(P2!=0xfe)
{
delay(20);// 延迟20ms
if(P2!=0xfe) { temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=0; break; //7
case 0xd0:num=1; break; //8
case 0xb0:num=2; break; //9
case 0x70:num=3; break; //÷
}
} while(P2!=0xfe);
if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
{
if(j!=0){write\_com(0x01); j=0; }
if(flag==0)//没有按过运算符键
{ a=a\*10+table[num]; } //按下数字存储到a
else//如果按过运算符键
{ b=b\*10+table[num]; }//按下数字存储到b
}
else//如果按下的是'/' 除法
{
flag=1; //按下运算符
fuhao=4;//4表示除号已按
}
i=table1[num]; //数据显示做准备
write\_date(0x30+i);//显示数据或操作符号
}

P2=0xfd;
if(P2!=0xfd)
{
delay(20);
if(P2!=0xfd){ temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=4; break; //4
case 0xd0:num=5; break; //5
case 0xb0:num=6; break; //6
case 0x70:num=7; break; //×
}
} while(P2!=0xfd);//等待按键释放
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
{
if(j!=0){ write\_com(0x01); j=0; }
if(flag==0)//没有按过运算符键
{ a=a\*10+table[num]; }
else//如果按过运算符键
{ b=b\*10+table[num]; }
}
else//如果按下的是'×'
{ flag=1;
fuhao=3;//3表示乘号已按
}
i=table1[num]; //数据显示做准备
write\_date(0x30+i);//显示数据或操作符号
}

P2=0xfb;
if(P2!=0xfb){ delay(20);
if(P2!=0xfb) { temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=8; break; //1
case 0xd0:num=9; break; //2
case 0xb0:num=10; break; //3
case 0x70:num=11; break; //-
}
} while(P2!=0xfb);
if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
{
if(j!=0){ write\_com(0x01); j=0; }
if(flag==0)//没有按过运算符键
{ a=a\*10+table[num]; }
else//如果按过运算符键
{ b=b\*10+table[num]; }
}
else if(num==11)//如果按下的是'-'
{
flag=1;
fuhao=2;//2表示减号已按
}
i=table1[num]; //数据显示做准备
write\_date(0x30+i);//显示数据或操作符号
}

P2=0xf7;
if(P2!=0xf7){ delay(20);
if(P2!=0xf7){ temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=12; break; //清0键
case 0xd0:num=13; break; //数字0
case 0xb0:num=14; break; //等于键
case 0x70:num=15; break; //加
}
} while(P2!=0xf7);

switch(num)
{
case 12:{write\_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
break;
case 13:{ //按下的是"0"
if(flag==0)//没有按过运算符键
{ a=a\*10; write\_date(0x30); P2=0; }
else if(flag>=1)//如果按过运算符键
{ b=b\*10; write\_date(0x30); }
} break;
case 14:{j=1; //按下等于键,根据运算符号进行不同的算术处理
if(fuhao==1) //加法运算
{
write\_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处
write\_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格
c=a+b;
while(c!=0){write\_date(0x30+c%10); c=c/10; }
write\_date(0x3d); //再写"="
a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==2) //减法运算
{
write\_com(0x80+0x4f);//光标前进至第二行最后一个显示处
write\_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样)
if(a-b>0) c=a-b;
else c=b-a;
while(c!=0) { write\_date(0x30+c%10);c=c/10; }
if(a-b<0) write\_date(0x2d);
if(a==b) write\_date(0x30+0); //当两个数相等时,输出结果0
write\_date(0x3d); //再写"="
a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==3) //乘法运算
{write\_com(0x80+0x4f); write\_com(0x04);
c=a\*b;
while(c!=0) {write\_date(0x30+c%10); c=c/10; }
write\_date(0x3d); a=0;b=0;flag=0;fuhao=0;
}
else if(fuhao==4)//除法运算
{write\_com(0x80+0x4f);
write\_com(0x04);
i=0;
if(b!=0)
{
c=(long)(((float)a/b)\*1000);
while(c!=0)
{
write\_date(0x30+c%10);
c=c/10;
i++; if(i==3) write\_date(0x2e);
}
if(a/b<=0)
{
if(i<=2)
{

if(i==1) write\_date(0x30);
write\_date(0x2e); // .
write\_date(0x30);
}

write\_date(0x30); //
}
write\_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
else
{
write\_date('!');write\_date('R');write\_date('O');
write\_date('R');write\_date('R');write\_date('E');
}
}
} break;
case 15:{write\_date(0x30+table1[num]);flag=1;fuhao=1;} break; //加键 设置加标志fuhao=1;
}
}//P2!=0xf7
}

main()
{
init(); //系统初始化
while(1)
{
keyscan();//键扫描
}
}



程序源码

1
2
3
链接:https://pan.baidu.com/s/18vMU5QZdKOc2CwkEP11a3g 
提取码:vxr5