高手老手们,谁能帮我完善一下这个单片机计算器程序呀c51!我这只能算了10以内的,要能算10以外的加算法该怎么办呀!帮下忙呀!
#include <reg52.h> #include <intrins.h> sbit RS=0xB0^6; sbit RW=0xa0^5; sbit E=0xa0^6; #define LCM_RW RW //定义引脚 #define LCM_RS RS #define LCM_E E #define LCM_Data P0 #define Busy 0x80 //用于检测LCM状态字中的Busy标识 unsigned char n=0; unsigned char one[17]; unsigned char two[17]; unsigned char code jianma[16]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; void WriteDataLCM(unsigned char WDLCM); void WriteCommandLCM(unsigned char WCLCM,BuysC); unsigned char ReadDataLCM(void); unsigned char ReadStatusLCM(void); void LCMInit(void); void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData); void Delay5Ms(void); void Delay400Ms(void); void disp(void) { DisplayListChar(0,0,one); } //写数据 void WriteDataLCM(unsigned char WDLCM) { ReadStatusLCM(); //检测忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; //若晶振速度太高可以在这后加小的延时 LCM_E = 0; //延时 LCM_E = 1; } //写指令 void WriteCommandLCM(unsigned char WCLCM,BuysC) / ysC为0时忽略忙检测 { if (BuysC) ReadStatusLCM(); //根据需要检测忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1; } //读数据 unsigned char ReadDataLCM(void) { LCM_RS = 1; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; return(LCM_Data); } //读状态 unsigned char ReadStatusLCM(void) { LCM_Data = 0xFF; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while (LCM_Data & Busy); //检测忙信号 return(LCM_Data); } void LCMInit(void) //LCM初始化 { LCM_Data = 0; WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号 Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号 WriteCommandLCM(0x08,1); //关闭显示 WriteCommandLCM(0x01,1); //显示清屏 WriteCommandLCM(0x06,1); // 显示光标移动设置 WriteCommandLCM(0x0C,1); // 显示开及光标设置 } //按指定位置显示一个字符 void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) { Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40; X |= 0x80; //算出指令码 WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码 WriteDataLCM(DData); } //按指定位置显示一串字符 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData) { unsigned char ListLength; ListLength = 0; Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 while (DData[ListLength]!='\0') //若到达字串尾则退出 { if (X <= 0xF) //X坐标应小于0xF { DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符 ListLength++; X++; } } } //5ms延时 void Delay5Ms(void) { unsigned int TempCyc = 5552; while(TempCyc--); } //400ms延时 void Delay400Ms(void) { unsigned char TempCycA = 5; unsigned int TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); }; } void dlms(void) { unsigned int j; for(j=500;j>0;j--) {} } unsigned char kbscan(void) {unsigned char sccode,recode; P1=0xf0; if((P1&0xf0)!=0xf0) { dlms(); if((P1&0xf0)!=0xf0) {sccode=0xfe; while((sccode&0x10)!=0) { P1=sccode; if((P1&0xf0)!=0xf0) {recode=P1&0xf0; sccode=sccode&0x0f; wait: P1=0xf0; if((P1&0xf0)!=0xf0) goto wait; else return(sccode+recode); } else sccode=(sccode<<1)|0x01; } } } return(0) ; } void delay (unsigned char m) //控制频率延时,基本延时为1ms { unsigned i=m; while(--i); } void delayms(unsigned char a) //毫秒延时子程序 { while(--a); //采用while(--a) 不要采用while(a--); } unsigned char panduanshuzi(unsigned char k) { unsigned char i; switch(k) {case 0xee: i=1;break; case 0xde: i=2;break; case 0xbe: i=3;break; case 0x7e: i=4;break; case 0xed: i=5;break; case 0xdd: i=6;break; case 0xbd: i=7;break; case 0x7d: i=8;break; case 0xeb: i=9;break; case 0xd7: i=0;break; default:i=10; } return(i); } unsigned char panduanfuhao(unsigned char m) { unsigned char i; switch(m) {case 0xdb: i='+';break; case 0xbb: i='-';break; case 0x7b: i='*';break; case 0xe7: i='/';break; default:i=0; } return(i); } main() {unsigned char a,b,c,d,k,clr; unsigned int a1,b1,c1,d1,e,e1,e2; start: Delay400Ms(); //启动等待,等LCM进入工作状态 LCMInit(); //LCM初始化 Delay5Ms(); a=0; b=0; c=0; d=0; e=0; a1=0; b1=0; c1=0; d1=0; e1=0; e2=0; k=0; while(1) {k=kbscan(); if(k!=0) {a=k; a1=panduanshuzi(a); if(a1!=10) { one[0]=a1+0x30; one[1]='\0'; DisplayListChar(0,0,one); }; fuhao: b=kbscan(); if(b==0) goto fuhao; b1=panduanfuhao(b); if(b1!=0) {one[1]=b1; one[2]='\0'; DisplayListChar(0,0,one); } secdata: c=kbscan(); if(c==0) goto secdata; c1=panduanshuzi(c); if(c1!=10) {one[2]=c1+0x30; one[3]='\0'; DisplayListChar(0,0,one); }; equ: d=kbscan(); if (d!=0xb7) goto equ; one[3]='='; switch(b1) {case '+': {e=a1+c1; one[4]=' ';} break; case '-': {if(a1>=c1) {e=a1-c1; one[4]=' ';} else {e=c1-a1; one[4]='-';}};break; case '*': { e=a1*c1; one[4]=' ';}break; case '/': { e=a1/c1; one[4]=' ';}break; default:e=0;} e1=e/10; e2=e%10; e1=e1+0x30; e2=e2+0x30; one[5]=e1; one[6]=e2; one[7]='\0'; DisplayListChar(0,0,one); clr1:clr=kbscan(); if(clr!=0x77) goto clr1; else { //启动等待,等LCM进入工作状态 LCMInit(); //LCM初始化 Delay5Ms(); break;} } } }
http://www.51hei.com 里面也有一个计算机程序好像也不大好用。
相同位数的数相加取余为该位数字,除10为下一位数字
很好 ,很强大 拷了。
从网上找的没有实践过; /*-------------------------------------- 计算器源程序 Calculator progarm V1.0 MCU STC89C52RC XAL 12MHz Build by Gavin Hu, 2007.11.23 --------------------------------------*/ #include <reg51.h> // #define uchar unsigned char #define uint unsigned int #define ulong unsigned long #define MAX_NUM 99999992.0 #define MIN_NUM -9999992.0 sbit BUZZ=P3^7; uchar dec_flag; void delay(uint); void display(uchar*); uchar key_scan(uint); uchar add_number(uchar*,uchar); float str2float(uchar*); uchar float2str(uchar*,float); float calcu(float,float,uchar); void err_sound(void); /*-------------------------------------- main function --------------------------------------*/ void main(void) { uchar kk,mm,err,lk,d1ok,ec; uchar dispram[9]; float d1,d2; err=0; d1ok=0; ec=0; mm=0; dec_flag=0; d1=0.0; d2=0.0; float2str(dispram,d1); BUZZ=0; for (kk=10;kk;kk--) display(dispram); BUZZ=1; while (!err) { display(dispram); kk=key_scan(((uint)(P3)<<8)|P1); if (kk!=0xff) { BUZZ=0; display(dispram); BUZZ=1; switch (kk) { case 0: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,7); lk=0; ec=0; break; case 1: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,8); lk=0; ec=0; break; case 2: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,9); lk=0; ec=0; break; case 3: if (!d1ok) {d1=str2float(dispram); d1ok=1;} else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);} kk=float2str(dispram,d1); if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;} lk=1; mm=4; ec=0; break; case 4: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,4); lk=0; ec=0; break; case 5: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,5); lk=0; ec=0; break; case 6: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,6); lk=0; ec=0; break; case 7: if (!d1ok) {d1=str2float(dispram); d1ok=1;} else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);} kk=float2str(dispram,d1); if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;} lk=1; mm=3; ec=0; break; case 8: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,1); lk=0; ec=0; break; case 9: if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,2); lk=0; ec=0; break; case 10:if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,3); lk=0; ec=0; break; case 11:if (!d1ok) {d1=str2float(dispram); d1ok=1;} else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);} kk=float2str(dispram,d1); if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;} lk=1; mm=2; ec=0; break; case 12:if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,0); lk=0; ec=0; break; case 13:if (lk) {float2str(dispram,0.0); dec_flag=0;} add_number(dispram,10); lk=0; ec=0; break; case 14:if (!d1ok) {d1=str2float(dispram); d1ok=1;} else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);} kk=float2str(dispram,d1); if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;} lk=1; mm=1; ec=0; break; case 15:if (ec==0) { if (!d1ok) d1=str2float(dispram); else {d2=str2float(dispram); d1=calcu(d1,d2,mm); ec=1;} } else {d1=calcu(d1,d2,mm);} kk=float2str(dispram,d1); if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;} lk=2; d1ok=0; break; } while ((P1&P3)!=0xff) display(dispram); } } dispram[0]=14; for (kk=1;kk<8;kk++) dispram[kk]=17; dispram[8]=255; err_sound(); while (1) { display(dispram); kk=key_scan(((uint)(P3)<<8)|P1); if (kk!=0xff) { err_sound(); while ((P1&P3)!=0xff) display(dispram); } } } /*-------------------------------------- Delay function Parameter: unsigned int dt Delay time=dt(ms) --------------------------------------*/ void delay(unsigned int dt) { register unsigned char bt,ct; for (; dt; dt--) for (ct=2;ct;ct--) for (bt=250; --bt; ); } /*-------------------------------------- 8 LED digital tubes display function Parameter: sting pointer to display --------------------------------------*/ void display(uchar*disp_ram) { unsigned char i; unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff}; for (i=0;i<8;i++) { if (disp_ram[8]==i) P0 =table[disp_ram]&0x7f; else P0 =table[disp_ram]; P2 =0x01<<i; delay(2); P0 =0xff; P2 =0; } } /*-------------------------------------- Key scan function Parameter key port state word Return key number,255 no key press --------------------------------------*/ uchar key_scan(uint key_port) { unsigned char i; for (i=0;i<16;i++) { if (!(key_port&0x0001)) return i; key_port >>=1; key_port |=0x8000; } return 0xff; } /*-------------------------------------- Add number (input figures) function Parameter:pointer for result,new number Retrun:0 fail,other ok --------------------------------------*/ uchar add_number(uchar*ch,uchar num) { uchar i; if (ch[0]!=17) return 0; if (num==10) if (!dec_flag) {dec_flag=1;return 2;} else return 0; if ((!dec_flag)&&(ch[7]==0)&&(ch[6]==17)) {ch[7]=num;return 1;} for (i=0;i<7;i++) ch=ch[i+1]; ch[7]=num; ch[8]-=dec_flag; return 1; } /*-------------------------------------- String to float function Parameter:pointer of string Return result, 0xffffffff fail --------------------------------------*/ float str2float(uchar*ch) { uchar i,ng; float dt,ft; ng=0; dt=0.0; ft=1.0; i=ch[8]; do { if (ch>9) { if (ch==16) ng=1; break; } dt+=ch*ft; ft*=10.0; } while (i--); ft=0.1; for (i=ch[8]+1;i<8;i++) { dt+=ch*ft; ft/=10.0; } if (ng) dt*=-1.0; if ((dt>MAX_NUM)||(dt<MIN_NUM)) return 0xffffffff; else return dt; } 接下一个
由于太大只能分两次法了 /*-------------------------------------- Float to string function Parameter:pointer for result,data to convert Retrun:0 ok,255 fail --------------------------------------*/ uchar float2str(uchar*ch,float dt) { uchar i,ng; float f; if ((dt>MAX_NUM)||(dt<MIN_NUM)) return 0xff; ng=0; if (dt<0.0) {dt*=-1.0; ng=1;} f=10000000.0; for (i=0;i<7;i++) { if ((dt/f)>=1.0) break; else f/=10.0; } for (i=0;i<8;i++) { ch=(uchar)(dt/f); dt -=f*ch; if (f==1.0) {ch[8]=i;} f/=10.0; } if (ch[0]>9) return 0xff; if (ng) { for (i=7;i;i--) ch=ch[i-1]; ch[0]=16; ch[8]++; } while ((ch[7]==0)&&(ch[8]<7)) { for (i=7;i;i--) { ch=ch[i-1]; } ch[0]=17; ch[8]++; } if ((ch[6]==16)&&(ch[7]==0)) ch[6]=17; return 0; } /*-------------------------------------- Calculate function Parameter:data1,data2,mathod Return result --------------------------------------*/ float calcu(float a,float b,uchar m) { float dt; switch (m) { case 1: dt=a+b; break; case 2: dt=a-b; break; case 3: dt=a*b; break; case 4: if (b==0.0) return 0xffffffff; else dt=a/b; break; } if ((dt>MAX_NUM)||(dt<MIN_NUM)) return 0xffffffff; else return dt; } /*-------------------------------------- Err sound function --------------------------------------*/ void err_sound(void) { uchar i; BUZZ=0; delay(500); for (i=0;i<5;i++) { BUZZ=!BUZZ; delay(100); } }
没电路图啊。。。。
欢迎光临 (http://www.51hei.com/bbs/) | Powered by Discuz! X3.1 |