#include<reg51.h> #define uint unsigned int #define uchar unsigned char sbit lcden=P2^0; sbit rs=P2^2; sbit rw=P2^1; sbit busy=P1^7; char i,j,temp,num; long a,b,c; uchar flag,fuhao; 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, 4,5,6,0x2a-0x30, 1,2,3,0x2d-0x30, 0x01-0x30,0,0x3d-0x30,0x2b-0x30}; void lcd1602_delay(uint x); void lcd1602_write_str(uchar *p); void lcd1602_write_com(uchar com); void lcd1602_delay1(uint x); void lcd1602_pos(uchar x,uchar y); void lcd1602_write_date(uchar date); void lcd1602_init(); void lcd1602_delay(uint x) { uint a,b; for(a=x;a>0;a--) for(b=10;b>0;b--); } void lcd1602_delay1(uint x) { uint a,b; for(a=x;a>0;a--) for(b=100;b>0;b--); } void lcd1602_write_com(uchar com) //向1602寫入命令 { P1=com; rs=0; rw = 0; lcden=0; lcd1602_delay(10); lcden=1; lcd1602_delay(10); lcden=0; } void lcd1602_pos(uchar x,uchar y) //1602定位 { uchar pos; if (x==0) x=0x80; else if (x==1) x=0xc0; pos = x+y ; lcd1602_write_com(pos); //顯示地址 } void lcd1602_write_date(uchar date) //向1602寫入數據 { P1=date; rs=1; rw=0; lcden=0; lcd1602_delay(10); lcden=1; lcd1602_delay(10); lcden=0; } void lcd1602_write_str(uchar *p) //向1602寫入一個字符串 { while(*p!='\0') { lcd1602_write_date(*p); p++; } } void lcd1602_init() //1602初始化 { rw=0; lcd1602_write_com(0x38); lcd1602_delay(20); lcd1602_write_com(0x0c); lcd1602_delay(20); lcd1602_write_com(0x06); lcd1602_delay(20); lcd1602_write_com(0x01); lcd1602_delay(20); num=-1; lcden=1; //使能信號為高電平 i=0; j=0; a=0; //第一個參與運算的數 b=0; //第二個參與運算的數 c=0; flag=0; //flag表示是否有符號鍵按下, fuhao=0; // fuhao表征按下的是哪個符號 } void delay(uchar z) // 延遲函數 { uchar y; for(z;z>0;z--) for(y=0;y<110;y++); } void keyscan() // 鍵盤掃描程序 { P3=0xfe; if(P3!=0xfe) { delay(5); if(P3!=0xfe) { temp=P3&0xf0; switch(temp) { case 0xe0:num=0; break; case 0xd0:num=1; break; case 0xb0:num=2; break; case 0x70:num=3; break; } } while(P3!=0xfe); if(num==0||num==1||num==2)//如果按下的是'7','8'或'9 { if(j!=0) { lcd1602_write_com(0x01); j=0; } if(flag==0)//沒有按過符號鍵 { a=a*10+table[num]; } else//如果按過符號鍵 { b=b*10+table[num]; } } else//如果按下的是'/' { flag=1; fuhao=4;//4表示除號已按 } i=table1[num]; lcd1602_write_date(0x30+i); } P3=0xfd; if(P3!=0xfd) { delay(5); if(P3!=0xfd) { temp=P3&0xf0; switch(temp) { case 0xe0:num=4; break; case 0xd0:num=5; break; case 0xb0:num=6; break; case 0x70:num=7; break; } } while(P3!=0xfd); if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6' { if(j!=0) { lcd1602_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]; lcd1602_write_date(0x30+i); } P3=0xfb; if(P3!=0xfb) { delay(5); if(P3!=0xfb) { temp=P3&0xf0; switch(temp) { case 0xe0:num=8; break; case 0xd0:num=9; break; case 0xb0:num=10; break; case 0x70:num=11; break; } } while(P3!=0xfb); if(num==8||num==9||num==10)//如果按下的是'1','2'或'3' { if(j!=0) { lcd1602_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]; lcd1602_write_date(0x30+i); } P3=0xf7; if(P3!=0xf7) { delay(5); if(P3!=0xf7) { temp=P3&0xf0; switch(temp) { case 0xe0:num=12; break; case 0xd0:num=13; break; case 0xb0:num=14; break; case 0x70:num=15; break; } } while(P3!=0xf7); switch(num) { case 12:{lcd1602_write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零" break; case 13:{ //按下的是"0" if(flag==0&a!=0)//沒有按過符號鍵 { a=a*10; lcd1602_write_date(0x30); } else if(flag==1&b!=0)//如果按過符號鍵 { b=b*10; lcd1602_write_date(0x30); } else { lcd1602_pos(0,0); lcd1602_write_str("0"); } } break; case 14:{j=1; if(fuhao==1){lcd1602_pos(1,16); lcd1602_write_com(0x04); c=a+b; if((c>=-99999999)&&(c<=99999999)) { while(c!=0) { lcd1602_write_date(0x30+c%10); c=c/10; } lcd1602_write_date(0x3d); //再寫"=" a=0;b=0;flag=0;fuhao=0; } else { lcd1602_pos(1,11); lcd1602_write_str("RORRE"); } } else if(fuhao==2){lcd1602_pos(1,16); lcd1602_write_com(0x04); if((a-b)>0) c=a-b; else c=b-a; if((c>=-99999999)&&(c<=99999999)) { while(c!=0) { lcd1602_write_date(0x30+c%10); c=c/10; } if((a-b)<0) lcd1602_write_date(0x2d); lcd1602_write_date(0x3d); //再寫"=" a=0;b=0;flag=0;fuhao=0; } else { lcd1602_pos(1,11); lcd1602_write_str("RORRE"); } } else if(fuhao==3){lcd1602_pos(1,16); lcd1602_write_com(0x04); c=a*b; if((c>=-99999999)&&(c<=99999999)) { while(c!=0) { lcd1602_write_date(0x30+c%10); c=c/10; } lcd1602_write_date(0x3d); a=0;b=0;flag=0;fuhao=0; } else { lcd1602_pos(1,11); lcd1602_write_str("RORRE"); } } else if(fuhao==4){lcd1602_pos(1,16); lcd1602_write_com(0x04); i=0; c=(long)(((float)a/b)*1000); if((c>=-99999999)&&(c<=99999999)) { while(c!=0) { lcd1602_write_date(0x30+c%10); c=c/10; i++; if(i==3) lcd1602_write_date(0x2e); } if(a/b<=0) lcd1602_write_date(0x30); lcd1602_write_date(0x3d); a=0;b=0;flag=0;fuhao=0; } else { lcd1602_pos(1,11); lcd1602_write_str("RORRE"); } } } break; case 15:{lcd1602_write_date(0x30+table1[num]);flag=1;fuhao=1;} break; } } } main() { unsigned int i; lcd1602_init(); lcd1602_pos(0,1); lcd1602_write_str("C51 calculator"); lcd1602_pos(1,1); lcd1602_write_str("By sdju BG0801"); for(i=10000;i>0;i++); for(i=10000;i>0;i++); for(i=10000;i>0;i++); for(i=10000;i>0;i++); for(i=10000;i>0;i++); for(i=10000;i>0;i++); for(i=10000;i>0;i++); for(i=10000;i>0;i++); lcd1602_init(); while(1) { keyscan();
|