1 #include
2 typedef unsigned charuint8;3 typedef unsigned intuint16;4
5 sbit rw=P2^5;6 sbit rs=P2^6;7 sbit e=P2^7;8 sbit led=P3^7;9
10 uint8 key,num,ei,eii,p;11 uint8 fuhao;//定义具体的那个符号,是加减还是乘除。
12 uint8 flag; //定义有没有按下符号键,这个是统称
13 long a,b,c,d; //定义运算数据的第一个和第二个及等于的数变量
14 uint8 k; //定义小数点后面显示的位数
15
16 uint8 dat1[]={1,2,3,0x2b-0x30, 4,5,6,0x2d-0x30, 7,8,9,0x2a-0x30,17 0,0x01-0x30,0x3d-0x30,0x2b-0x30 };//保存显示的数据
18 uint8 dat2[]="9999 revo rewsna";19 uint8 dat3[]="Hi welcome into";20 uint8 dat4[]="counter by yumo";21 voiddelay(uint16 i)22 {23 while(i--);24 }25 void lcdwrc(uint8 c)//写入命令
26 {27 delay(1000);28 rs=0;//选择发送命令
29 rw=0;//选择写入
30 e=0;//使能
31
32 P0=c;//放入命令
33 e=1;//写时序
34 delay(1000);//保持时间
35 e=0;36 }37 void lcdwrd(uint8 dat)//写入数据
38 {39 delay(1000);40 rs=1;//选择输入数据
41 rw=0;//选择写入
42 e=0;43
44 P0=dat;//写入数据
45 e=1;//写入时序
46 delay(1000);47 e=0;48 rs=0;49 }50
51 void lcdinit()//LCD初始化
52 {53 delay(1500);54 lcdwrc(0x38);55 delay(500);56 lcdwrc(0x38);57 delay(500);58 lcdwrc(0x38);59 delay(500);60 lcdwrc(0x38);61 lcdwrc(0x08);62 lcdwrc(0x01);63 lcdwrc(0x06);64 lcdwrc(0x0c);65 key=0;66 num=0;67 flag=0;68 fuhao=0;69 a=0;70 b=0;71 c=0;72 d=0;73 led=0;74 }75
76 show()77 {78 for(eii=0;eii<15;eii++)79 {80
81 lcdwrd(dat3[eii]);82 }83 lcdwrc(0xc0);//写命令函数使其到第二行第一个字符
84 for(p=0;p<15;p++)85 {86
87 lcdwrd(dat4[p]);88 }89 return 1;90 }91 voidkeyscan()92 {93 P1=0xfe; //令第一行为0,然后判断是哪一列按下
94 if(P1!=0xfe)95 {96 delay(1000);97 if(P1!=0xfe)98 {99 key=P1&0xf0;100 switch(key)101 {102 case 0xe0: num=0;break; //1
103 case 0xd0: num=1;break; //2
104 case 0xb0: num=2;break; //3
105 case 0x70: num=3;break; //加
106 }107 }108 while(P1!=0xfe);109 if(num==0||num==1||num==2) //确认第一行的数1,2,3
110 {111 if(flag==0) //没有按下符号键
112 {113 led=1;114 a=a*10+dat1[num];115 }116 else
117 {118 led=1;119 delay(1000);120 led=0;121 delay(1000);122 led=1;123 b=b*10+dat1[num];124 }125 }126 if(num==3)127 {128 led=0;129 flag=1;130 fuhao=1;//加号+
131 }132 lcdwrd(0x30+dat1[num]);133 }134
135 P1=0xfd; //令第二行为0,判断是哪一列按下
136 if(P1!=0xfd)137 {138 delay(1000);139 if(P1!=0xfd)140 {141 key=P1&0xf0;142 switch(key)143 {144 case 0xe0: num=4;break; //4
145 case 0xd0: num=5;break; //5
146 case 0xb0: num=6;break; //6
147 case 0x70: num=7;break; //减—
148 }149 }150 while(P1!=0xfd);151 if(num==4||num==5||num==6)152 {153 if(flag==0) //没有按下符号键
154 {155 led=1;156 a=a*10+dat1[num];157 }158 else
159 {160 led=1;161 b=b*10+dat1[num];162 }163 }164 else
165 {166 led=0;167 flag=1;168 fuhao=2;//带表减号
169 }170 lcdwrd(0x30+dat1[num]);171 }172
173 P1=0xfb; //令第三行为0,判断哪一列按下
174 if(P1!=0xfb)175 {176 delay(1000);177 if(P1!=0xfb)178 {179 key=P1&0xf0;180 switch(key)181 {182 case 0xe0: num=8;break; //7
183 case 0xd0: num=9;break; //8
184 case 0xb0: num=10;break; //9
185 case 0x70: num=11;break; //乘*
186 }187 }188 while(P1!=0xfb);189 if(num==8||num==9||num==10)190 {191 if(flag==0) //没有按下符号键
192 {193 led=1;194 a=a*10+dat1[num];195 }196 else
197 {198 led=1;199 b=b*10+dat1[num];200 }201 }202 else
203 {204 led=0;205 flag=1;206 fuhao=3;//带表乘号*
207 }208 lcdwrd(0x30+dat1[num]);209 }210
211 P1=0xf7; //令第四行为0,判断哪一列按下
212 if(P1!=0xf7)213 {214 delay(1000);215 if(P1!=0xf7)216 {217 key=P1&0xf0;218 switch(key)219 {220 case 0xe0: num=12;break; //0
221 case 0xd0: num=13;break; //清除rst
222 case 0xb0: num=14;break; //等号=
223 case 0x70: num=15;break; //除/
224 }225 }226 while(P1!=0xf7);227 switch(num)228 {229 case 12:230 if(flag==0) //没有按下符号键
231 {232 led=1;233 a=a*10+dat1[num];234 lcdwrd(0x30);235 }236 else
237 {238 led=1;239 b=b*10+dat1[num];240 lcdwrd(0x30);241 }242 break;243 case 13:244 lcdwrc(0x01); //清屏指令
245 a=0;246 b=0;247 c=0;248 flag=0;249 fuhao=0;250 break;251 case 15:252
253 led=0;254 flag=1;255 fuhao=4;256 lcdwrd(0x2f);//除号/
257 break;258 case 14: //如果是等于号
259 if(fuhao==1)//加
260 {261 lcdwrc(0x4f+0x80);262 lcdwrc(0x04);//设置光标左移,屏幕不移动
263 c=a+b;264
265 if(c==0)266 {267 lcdwrc(0x4f+0x80);268 lcdwrc(0x04);269 lcdwrd(0x30);270 }271 while((c!=0)&&(c<=9999)) //一位一位显示
272 {273
274 lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
275 c=c/10;//取前面的结果数据
276 }277 if(c>9999)278 {279 for(ei=0;ei<=16;ei++)280 {281 lcdwrd(dat2[ei]);282 }283 }284 lcdwrd(0x3d); //显示等于号=
285 a=0;286 b=0;287 c=0;288 flag=0;289 fuhao=0;//全部清除为0
290 }291 if(fuhao==2) //减
292 {293 lcdwrc(0x4f+0x80);294 lcdwrc(0x04);//设置光标左移,屏幕不移动
295 if(a>b)296 c=a-b;297 else
298 c=b-a;299
300 if((c==0))//此语句位置影响显示
301 {302 lcdwrc(0x4f+0x80);303 lcdwrc(0x04);304 lcdwrd(0x30);305 }306 while((c!=0)&&(c<=9999)) //一位一位显示
307 {308 lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
309 c=c/10;//取前面的结果数据
310 }311 if(c>9999)312 {313 for(ei=0;ei<=16;ei++)314 {315 lcdwrd(dat2[ei]);316 }317 }318 if(a
319 lcdwrd(0x3d); //显示等于号=
320 a=0;321 b=0;322 flag=0;323 fuhao=0;//全部清除为0
324 }325 if(fuhao==3)//乘法
326 {327 lcdwrc(0x4f+0x80);328 lcdwrc(0x04);//设置光标左移,屏幕不移动
329 c=a*b;330 while((c!=0)&(c<=9999)) //一位一位显示
331 {332 lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
333 c=c/10;//取前面的结果数据
334 }335 if (c>9999)336 {337 for(ei=0;ei<=16;ei++)338 {339 lcdwrd(dat2[ei]);340 }341 }342 if(a==0||b==0)343 {344 lcdwrd(0x30);345 }346 lcdwrd(0x3d); //显示等于号=
347 a=0;348 b=0;349 flag=0;350 fuhao=0;//全部清除为0
351 }352 if(fuhao==4)//除法
353 {354 k=0;355 lcdwrc(0x4f+0x80);356 lcdwrc(0x04);//设置光标左移,屏幕不移动
357 c=(long)(((float)a/b)*10000);//强制转换为long。
358 while((c!=0)&&(c<=99990000)) //一位一位显示
359 {360 k++;361 lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
362 c=c/10;//取前面的结果数据
363 if(k==4)//结果保留四位有效数字
364 {365 lcdwrd(0x2e);//显示一个点366 //k=0;//倘若K=0,那么每隔三位就有一个小数点,计算器上的逗号就是这个原理。
367 }368 }369 if(c>99990000)370 {371 for(ei=0;ei<=16;ei++)372 {373 lcdwrd(dat2[ei]);374 }375 }376 if(0
379
380 }381 if((a/b)<1) //如果a比b小的话那么除的结果最高位是0
382 {383 lcdwrd(0x30);384 }385 if(b==0)//检错因为除数不能为0,否则就显示ERROR
386 {387 lcdwrc(0x4f+0x80);388 lcdwrc(0x04);389 lcdwrd(0x52);390 lcdwrd(0x4f);391 lcdwrd(0x52);392 lcdwrd(0x52);393 lcdwrd(0x45);394 }395 lcdwrd(0x3d); //显示等号
396 a=0;397 b=0;398 flag=0;399 fuhao=0;//全部清除为0
400 }401 break;402 }403 }404 }405 voidmain()406 {407 lcdinit();408 show();//个性化界面
409 while(1)410 {411 keyscan();412 }413 }