我给你来个程序参考
- #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; //电平触发(边沿触发IT0=1;)
- while(1)
- {
- keyscan();
- anjianshibie();
- }
- }
- /*按键检测*/
- uchar keyscan1(void) //键盘扫描函数,使用行列反转扫描法
- {
- 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;
- }
- }
- /*按键识别函数*/
- 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'; //一定要加这个,否则会出现满屏的按键对应的数
- }
- if(num==3||num==7||num==11||num==15)
- {
- flag=1;
- flag2=0;
- y=0;
- temp++;//判断运算符号按下的个数
- 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); //把小数点显示出来
- } */
- 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); // 按键释放
- }*/
- }
- /*计算函数*/
- void count()
- {
- if(fuhao==1) //如果符号键是+,执行加法运算
- {
- c=a+b;
- a=c;
- b=0;
- }
- if(fuhao==2) // 如果符号键是-,执行减法运算
- {
- c=a-b;
- a=c;
- b=0;
- }
- if(fuhao==3) //如果符号键是*执行乘法运算
- {
- c=a*b;
- a=c;
- b=0;
- }
- if(fuhao==4) //如果符号键是/ 执行除法运算
- {
- if(b==0)
- {
- write_com(0x01);
- write_string("math error"); //被除数不能为零,否则输出math error
- }
- else
- {
- c=a/b;
- a=c;
- b=0;
- } //这么设置就可连续运算
- }
- 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;
- }
- /*******写数据***********/
- 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; //循环变量
- 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; //进入中断程序执行程序
- }
- while(!zhongduan); //等待释放,如果没有释放,则一直等待
- }
- }
- /******显示7位小数*********/
- 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位小数
- // 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位小数
- // 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位小数
- // 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位小数
- // 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位小数
- // if((nxtemp%1000000%100000%10000%1000%100/10!=0))
- write_data(nxtemp%1000000%100000%10000%1000%100/10+0x30);//显示第2位小数
- write_data(nxtemp%10+0x30);//显示第1位小数 */
- }
- else
- return;
- }
- /*显示多位数*/
- 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的每一位放进数组
- nx=nx/10;
- j++;
- }
- for(;j>0;j--)
- { //显示整数n的每一位
- write_data(shu[j-1]+0x30);
- delayms(5);
- }
- }
- }
复制代码 |