我給你來個程序參考
- #include<reg52.h>
- #include<math.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define lcddata P1
- sbit LCDRS = P3^3;
- sbit LCDRW = P3^4;
- sbit LCDEN = P3^5;
- sbit beep = P3^7;
- sbit zhongduan = P3^2;
- sbit kaifang = P0^6;
- sbit cifang = P0^7;
- sbit qingling=P0^5;
- sbit kaiguan=P0^4;
- uchar keyscan1(void);
- void keyscan(void);
- void count(void);
- void anjianshibie();
- void write_com(uchar i);
- void write_data(uchar i);
- void write_string(uchar *s);
- void write_num(long n);
- void lcdwrite_float(float n);
- void lcd_init(void);
- void xinxing();
- void delayms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- uchar code table[]=
- {
- 1,2,3,0x2b-0x30, // 1, 2, 3, +
- 4,5,6,0x2d-0x30, // 4, 5, 6, -
- 7,8,9,0x2a-0x30, // 7, 8, 9, x
- 0,0x3d-0x30,0x2e-0x30,0x2f-0x30 // 0, =, 清零, /
- };
- uchar code table1[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
- 0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
- 0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
- 0x01,0x18,0x1c,0x1e,0x1e,0x1e,0x1e,0x1e,
- 0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
- 0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
- 0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
- 0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00
- };
- uchar num='N',flag=0,flag1=0,flag2=0,fuhao=0,temp=0,shu[18]={0},beepflag=1,y=0,j;
- float a=0,b=0,c=0,d,point=0;
- void main()
- {
- xinxing();
- delayms(1000);
- write_com(0x01);
- write_com(0x80);
- EA=1; //全局中斷開
- EX0=1; //外部中斷0開
- IT0=0; //電平觸發(fā)(邊沿觸發(fā)IT0=1;)
- while(1)
- {
- keyscan();
- anjianshibie();
- }
- }
- /*按鍵檢測*/
- uchar keyscan1(void) //鍵盤掃描函數(shù),使用行列反轉(zhuǎn)掃描法
- {
- unsigned char cord_h,cord_l;//行列值中間變量
- P2=0x0f; //行線輸出全為0
- cord_h=P2&0x0f; //讀入列線值
- if(cord_h!=0x0f) //先檢測有無按鍵按下
- {
- delayms(10); //去抖
- if((P2&0x0f)!=0x0f)
- {
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(50);
- beep=1;
- }
- cord_h=P2&0x0f; //讀入列線值
- P2=cord_h|0xf0; //輸出當前列線值
- cord_l=P2&0xf0; //讀入行線值
- while((P2&0xf0)!=0xf0); //等待松開并輸出
- return(cord_h+cord_l); //鍵盤最后組合碼值
- }
- }
- return(0xff); //返回該值
- }
- void keyscan()
- {
- switch(keyscan1())
- {
- case 0xEE:num=0;break;
- case 0xDE:num=1;break;
- case 0xBE:num=2;break;
- case 0x7E:num=3;break;
- case 0xED:num=4;break;
- case 0xDD:num=5;break;
- case 0xBD:num=6;break;
- case 0x7D:num=7;break;
- case 0xEB:num=8;break;
- case 0xDB:num=9;break;
- case 0xBB:num=10;break;
- case 0x7B:num=11;break;
- case 0xE7:num=12;break;
- case 0xD7:num=13;break;
- case 0xB7:num=14;break;
- case 0x77:num=15;break;
- }
- }
- /*按鍵識別函數(shù)*/
- void anjianshibie()
- {
- if(num==0||num==1||num==2||num==4||num==5||num==6||num==8||num==9||num==10||num==12||num==14)
- {
- if(temp>=2)
- {
- write_com(0x01);
- write_string("math error");
- }
- else
- {
- if(flag==0)
- {
- if(num==14)
- {flag2=1;}
- if(num!=14&&flag2==0)
- {a=a*10+table[num];}
- if(num!=14&&flag2==1)
- {
- y++;
- point=table[num]*pow(0.1,y);
- a=a+point;
- }
- write_data(0x30+table[num]);
- delayms(5);
- }
- if(flag==1)
- {
- if(num==14)
- {flag2=1;}
- if(num!=14&&flag2==0)
- {b=b*10+table[num];}
- if(num!=14&&flag2==1)
- {
- y++;
- point=table[num]*pow(0.1,y);
- b=b+point;
- }
- write_data(0x30+table[num]);
- delayms(5);
- }
- }
- num='N'; //一定要加這個,否則會出現(xiàn)滿屏的按鍵對應的數(shù)
- }
- if(num==3||num==7||num==11||num==15)
- {
- flag=1;
- flag2=0;
- y=0;
- temp++;//判斷運算符號按下的個數(shù)
- switch(num)
- {
- case 3:fuhao=1;break; //加
- case 7:fuhao=2;break; // 減
- case 11:fuhao=3;break; // 乘
- case 15:fuhao=4;break; // 除
- }
- write_data(0x30+table[num]);
- num='N';
- }
- if(num==13) //13等號,14清零
- {
- temp=0; //temp清零
- flag=0;
- flag2=0;
- if(flag1==0)
- {write_com(0x80+0x40);}
- write_data(0x30+table[num]);
- delayms(5);
- count(); //計算c的值
- /* if(c==0)
- {
- write_com(0x80+0x41);//如果c為零,直接在等號后邊顯示出來
- write_data(0x30);
- }
- if(c>0)
- {
- d=c;
- }
- if(c<0)
- {
- d=0-c;
- write_data(0x2d); //把小數(shù)點顯示出來
- } */
- lcdwrite_float(c);
- flag1++;
- num='N';
- }
- if(kaifang==0)
- {
- delayms(10);
- if(kaifang==0) //去抖
- {
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(50);
- beep=1;
- }
- temp++;
- flag=1;
- flag2=0;
- y=0;
- write_data(0xe8);
- fuhao=5;
- }
- while(!kaifang); //按鍵釋放
- }
- if(cifang==0)
- {
- delayms(10); // 去抖
- if(cifang==0)
- {
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(50);
- beep=1;
- }
- temp++;
- flag=1;
- flag2=0;
- y=0;
- write_data(0x5e);
- fuhao=6;
- }
- while(!cifang); // 按鍵釋放
- }
- if(qingling==0)
- {
- delayms(10); // 去抖
- if(qingling==0)
- {
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(50);
- beep=1;
- }
- write_com(0x01);
- a=0;
- b=0;
- c=0;
- point=0;
- flag=0;
- flag1=0;
- flag2=0;
- temp=0;
- fuhao=0;
- j=0;
- num='N';
- }
- while(!qingling); // 按鍵釋放
- }
- /*if(kaiguan==0)
- {
- delayms(10); // 去抖
- if(kaiguan==0)
- {
- beepflag=~beepflag;
- }
- while(!cifang); // 按鍵釋放
- }*/
- }
- /*計算函數(shù)*/
- void count()
- {
- if(fuhao==1) //如果符號鍵是+,執(zhí)行加法運算
- {
- c=a+b;
- a=c;
- b=0;
- }
- if(fuhao==2) // 如果符號鍵是-,執(zhí)行減法運算
- {
- c=a-b;
- a=c;
- b=0;
- }
- if(fuhao==3) //如果符號鍵是*執(zhí)行乘法運算
- {
- c=a*b;
- a=c;
- b=0;
- }
- if(fuhao==4) //如果符號鍵是/ 執(zhí)行除法運算
- {
- if(b==0)
- {
- write_com(0x01);
- write_string("math error"); //被除數(shù)不能為零,否則輸出math error
- }
- else
- {
- c=a/b;
- a=c;
- b=0;
- } //這么設置就可連續(xù)運算
- }
- if(fuhao==5)
- {
- if(b<0)
- {
- write_com(0x01);
- write_string("math error");
- }
- else
- {
- c=sqrt(b);
- }
- }
- if(fuhao==6)
- {
- float x=a;
- c=a;
- for(;b>1;b--)
- {
- c=x*a;
- x=c;
- }
- }
- }
- /*寫命令*/
- void write_com(uchar i)
- {
- LCDEN=0;
- LCDRS=0;
- lcddata=i;
- delayms(5);
- LCDEN=1;
- delayms(5);
- LCDEN=0;
- }
- /*******寫數(shù)據(jù)***********/
- void write_data(uchar i)
- {
- LCDEN=0;
- LCDRS=1;
- lcddata=i;
- delayms(5);
- LCDEN=1;
- delayms(5);
- LCDEN=0;
- }
- /*寫字符串*/
- void write_string(uchar *s)
- {
- while(*s)
- {
- write_data(*s);
- s++;
- delayms(5);
- }
- }
- /*******初始化液晶*******/
- void lcd_init(void)
- {
- LCDEN=0;
- LCDRW=0;
- //write_com(0x01); //顯示清屏
- // write_com(0x01); //顯示清屏
- write_com(0x38);//設置成1602顯示
- delayms(5);
- write_com(0x38);//設置成1602顯示
- delayms(5);
- write_com(0x38);//設置成1602顯示
- delayms(5);
- // write_com(0x0f); //開顯示 0x0e-->顯示開,光標開
- write_com(0x0c);//顯示開
- write_com(0x06); //設置光標移動方向增量方式,并指定顯示不移動
- write_com(0x01);
- }
- /*開機界面*/
- void xinxing()
- {
- uchar mingzi[]="by 51Hei" ;
- uchar num1; //循環(huán)變量
- lcd_init(); //初始化
- write_com(0x40);
- for(num1=0;num1<64;num1++)
- {
- write_data(table1[num1]);
- }
- write_com(0x85);
- for(num1=0;num1<4;num1++)
- {
- write_data(num1);
- }
- write_com(0xc5);
- for(num1=4;num1<8;num1++)
- {
- write_data(num1);
- }
- write_com(0x80+0x4a);
- for(num1=0;num1<6;num1++)
- {
- write_data(mingzi[num1]);
- }
-
- }
- void waibu(void) interrupt 0 //using 1
- {
- if(zhongduan==0) //如果檢測到低電平
- {
- delayms(10); //延時,去抖動,一般為10ms
- if(zhongduan==0) //如果去抖動之后還是低電平,說明按下了
- {
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(50);
- beep=1;
- }
- beepflag=~beepflag; //進入中斷程序執(zhí)行程序
- }
- while(!zhongduan); //等待釋放,如果沒有釋放,則一直等待
- }
- }
- /******顯示7位小數(shù)*********/
- void lcdwrite_float(float n)
- {
- uchar i=0;
- long nxtemp;
- if(n==0)
- {
- write_data('0');
- return;
- }
- if(n<0)
- {
- write_data('-');
- n=0-n;
- }
- nxtemp=n;
- n=n;//+0.000002;
- write_num(nxtemp);
- if((n-nxtemp)>0)
- {
- write_data('.');
- nxtemp=(n-nxtemp)*10000000;
- // n=n-1;
- // nxtemp=n;
- // if(nxtemp%10!=0)
- write_data(nxtemp/1000000+0x30);//顯示第7位小數(shù)
- // if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0)||(nxtemp%1000000%100000/10000!=0)||(nxtemp%1000000/100000!=0))
- write_data(nxtemp%1000000/100000+0x30);//顯示第6位小數(shù)
- // if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0)||(nxtemp%1000000%100000/10000!=0))
- write_data(nxtemp%1000000%100000/10000+0x30);//顯示第5位小數(shù)
- // if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0))
- write_data(nxtemp%1000000%100000%10000/1000+0x30);//顯示第4位小數(shù)
- // if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0))
- write_data(nxtemp%1000000%100000%10000%1000/100+0x30);//顯示第3位小數(shù)
- // if((nxtemp%1000000%100000%10000%1000%100/10!=0))
- write_data(nxtemp%1000000%100000%10000%1000%100/10+0x30);//顯示第2位小數(shù)
- write_data(nxtemp%10+0x30);//顯示第1位小數(shù) */
- }
- else
- return;
- }
- /*顯示多位數(shù)*/
- void write_num(long n)
- {
- // uchar length=0,j=0,a[8]={0,0,0,0,0,0,0,0};
- long nx;
- /* if(n==0)
- {
- write_data('0');
- return;
- }
- if(n<0)
- {
- write_data('-');
- n=0-n;
- } */
- // nx=n;
- // for(j=0;j<8;j++)
- // {
- // if(nx>=1)
- // length++;
- // nx/=10;
- // }
- nx=n;
- if(nx==0)
- {
- write_data('0');
- }
- else
- {
- while(nx>0)
- {
- shu[j]=nx%10; //把n的每一位放進數(shù)組
- nx=nx/10;
- j++;
- }
- for(;j>0;j--)
- { //顯示整數(shù)n的每一位
- write_data(shu[j-1]+0x30);
- delayms(5);
- }
- }
- }
復制代碼 |